diff options
author | rtk0c <[email protected]> | 2022-05-30 17:03:20 -0700 |
---|---|---|
committer | rtk0c <[email protected]> | 2022-05-30 17:03:20 -0700 |
commit | e66286ebe30afc9acc4531fc2bea29b7fb924f93 (patch) | |
tree | fa6b76554c3eb88bc8f088fbab68e20c40118ca7 /source/Ires.cpp | |
parent | 366ef5a5450c6e0e680c924c3454943a9ae9814d (diff) |
Changeset: 56 Buildsystem cleanup: change to layered structure for different targets
Diffstat (limited to 'source/Ires.cpp')
-rw-r--r-- | source/Ires.cpp | 425 |
1 files changed, 0 insertions, 425 deletions
diff --git a/source/Ires.cpp b/source/Ires.cpp deleted file mode 100644 index 10a6867..0000000 --- a/source/Ires.cpp +++ /dev/null @@ -1,425 +0,0 @@ -#include "Ires.hpp" - -#include "AppConfig.hpp" -#include "EditorCore.hpp" -#include "EditorUtils.hpp" -#include "Macros.hpp" -#include "Material.hpp" -#include "RapidJsonHelper.hpp" -#include "ScopeGuard.hpp" -#include "Shader.hpp" -#include "Sprite.hpp" -#include "Texture.hpp" -#include "Utils.hpp" - -#include <imgui.h> -#include <misc/cpp/imgui_stdlib.h> -#include <rapidjson/document.h> -#include <rapidjson/filereadstream.h> -#include <rapidjson/filewritestream.h> -#include <rapidjson/prettywriter.h> -#include <rapidjson/writer.h> -#include <algorithm> -#include <cassert> - -namespace fs = std::filesystem; -using namespace std::literals; - -IresObject::IresObject(Kind kind) - : mKind{ kind } { -} - -std::string_view IresObject::ToString(Kind kind) { - switch (kind) { - case KD_Texture: return BRUSSEL_TAG_PREFIX_Ires "Texture"sv; - case KD_Shader: return BRUSSEL_TAG_PREFIX_Ires "Shader"sv; - case KD_Material: return BRUSSEL_TAG_PREFIX_Ires "Material"sv; - case KD_SpriteFiles: return BRUSSEL_TAG_PREFIX_Ires "SpriteFiles"sv; - case KD_Spritesheet: return BRUSSEL_TAG_PREFIX_Ires "Spritesheet"sv; - case KD_COUNT: break; - } - return std::string_view(); -} - -IresObject::Kind IresObject::FromString(std::string_view name) { - if (name == BRUSSEL_TAG_PREFIX_Ires "Texture"sv) return KD_Texture; - if (name == BRUSSEL_TAG_PREFIX_Ires "Shader"sv) return KD_Shader; - if (name == BRUSSEL_TAG_PREFIX_Ires "Material"sv) return KD_Material; - if (name == BRUSSEL_TAG_PREFIX_Ires "SpriteFiles"sv) return KD_SpriteFiles; - if (name == BRUSSEL_TAG_PREFIX_Ires "Spritesheet"sv) return KD_Spritesheet; - return KD_COUNT; -} - -std::unique_ptr<IresObject> IresObject::Create(Kind kind) { - switch (kind) { - case KD_Texture: return std::make_unique<IresTexture>(); - case KD_Shader: return std::make_unique<IresShader>(); - case KD_Material: return std::make_unique<IresMaterial>(); - case KD_SpriteFiles: return std::make_unique<IresSpriteFiles>(); - case KD_Spritesheet: return std::make_unique<IresSpritesheet>(); - case KD_COUNT: break; - } - return nullptr; -} - -bool IresObject::IsAnnoymous() const { - return mName.empty(); -} - -void IresObject::SetName(std::string name) { - if (mMan) { - mMan->Rename(this, std::move(name)); - } else { - mName = std::move(name); - } -} - -void IresObject::ShowNameSafe(IresObject* ires) { - if (ires) { - ires->ShowName(); - } else { - ShowNameNull(); - } -} - -void IresObject::ShowNameNull() { - ImGui::Text("<null>"); -} - -void IresObject::ShowName() const { - if (IsAnnoymous()) { - ImGui::Text("<annoymous %p>", (void*)this); - } else { - ImGui::Text("%s", mName.c_str()); - } -} - -void IresObject::ShowReferenceSafe(IEditor& editor, IresObject* ires) { - if (ires) { - ires->ShowReference(editor); - } else { - ShowReferenceNull(editor); - } -} - -void IresObject::ShowReferenceNull(IEditor& editor) { - ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_ButtonHovered]); - ImGui::Text("<null>"); - ImGui::PopStyleColor(); - ImGui::AddUnderLine(ImGui::GetStyle().Colors[ImGuiCol_Button]); -} - -void IresObject::ShowReference(IEditor& editor) { - ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_ButtonHovered]); - if (IsAnnoymous()) { - ImGui::Text("<annoymous %p>", (void*)this); - } else { - ImGui::Text("%s", mName.c_str()); - } - ImGui::PopStyleColor(); - if (ImGui::IsItemHovered()) { - if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) { - editor.GetInspector().SelectTarget(IEditorInspector::ITT_Ires, this); - } - ImGui::AddUnderLine(ImGui::GetStyle().Colors[ImGuiCol_ButtonHovered]); - } else { - ImGui::AddUnderLine(ImGui::GetStyle().Colors[ImGuiCol_Button]); - } -} - -void IresObject::ShowEditor(IEditor& editor) { - ImGui::Text("%s", ToString(mKind).data()); - - bool isAnnoymous = mName.empty(); - if (isAnnoymous) { - ImGui::Text("Name: <annoymous: %p>", (void*)this); - } else { - ImGui::Text("Name: %s", mName.c_str()); - } - - if (mUid.IsNull()) { - ImGui::TextUnformatted("Uid: <none>"); - } else { - ImGui::Text("Uid: %lx-%lx", mUid.upper, mUid.lower); - } -} - -void IresObject::WriteFull(IresWritingContext& ctx, IresObject* ires, rapidjson::Value& value, rapidjson::Document& root) { - rapidjson::Value rvIres(rapidjson::kObjectType); - ires->Write(ctx, rvIres, root); - - value.AddMember("Type", rapidjson::StringRef(ToString(ires->GetKind())), root.GetAllocator()); - value.AddMember("Uid", ires->mUid.Write(root), root.GetAllocator()); - value.AddMember("Value", rvIres, root.GetAllocator()); -} - -std::unique_ptr<IresObject> IresObject::ReadFull(IresLoadingContext& ctx, const rapidjson::Value& value) { - auto ires = ReadBasic(value); - if (!ires) { - return nullptr; - } - - if (!ReadPartial(ctx, ires.get(), value)) { - return nullptr; - } - - return ires; -} - -std::unique_ptr<IresObject> IresObject::ReadBasic(const rapidjson::Value& value) { - auto rvType = rapidjson::GetProperty(value, rapidjson::kStringType, "Type"sv); - if (!rvType) return nullptr; - auto kind = FromString(rapidjson::AsStringView(*rvType)); - auto ires = Create(kind); - if (!ires) return nullptr; - - auto rvUid = rapidjson::GetProperty(value, rapidjson::kArrayType, "Uid"sv); - if (!rvUid) return nullptr; - ires->mUid.Read(*rvUid); - - return ires; -} - -bool IresObject::ReadPartial(IresLoadingContext& ctx, IresObject* ires, const rapidjson::Value& value) { - auto rvValue = rapidjson::GetProperty(value, "Value"sv); - if (!rvValue) return false; - ires->Read(ctx, *rvValue); - return true; -} - -void IresObject::Write(IresWritingContext& ctx, rapidjson::Value& value, rapidjson::Document& root) const { -} - -void IresObject::Read(IresLoadingContext& ctx, const rapidjson::Value& value) { -} - -void IresManager::DiscoverFilesDesignatedLocation() { - auto path = AppConfig::assetDirPath / "Ires"; - DiscoverFiles(path); -} - -void IresManager::DiscoverFiles(const fs::path& dir) { - struct LoadCandidate { - fs::path path; - rapidjson::Document data; - RcPtr<IresObject> ires; - }; - - class IresLoadTimeContext final : public IresLoadingContext { - public: - // NOTE: pointer stability required - robin_hood::unordered_node_map<Uid, LoadCandidate> candidates; - std::vector<std::vector<LoadCandidate*>> candidatesByKind; - - IresLoadTimeContext() { - candidatesByKind.resize(IresObject::KD_COUNT); - } - - std::vector<LoadCandidate*>& GetByKind(IresObject::Kind kind) { - int i = static_cast<int>(kind); - return candidatesByKind[i]; - } - - virtual IresObject* FindIres(const Uid& uid) const override { - auto iter = candidates.find(uid); - if (iter != candidates.end()) { - auto& cand = iter->second; - return cand.ires.Get(); - } else { - return nullptr; - } - } - } ctx; - - for (auto& item : fs::directory_iterator(dir)) { - if (!item.is_regular_file()) { - continue; - } - if (item.path().extension() != ".json") { - continue; - } - - auto file = Utils::OpenCstdioFile(item.path(), Utils::Read); - if (!file) { - fprintf(stderr, "Ires file [" PLATFORM_PATH_STR "] Failed to open file.", item.path().c_str()); - continue; - } - DEFER { fclose(file); }; - - char readerBuffer[65536]; - rapidjson::FileReadStream stream(file, readerBuffer, sizeof(readerBuffer)); - - rapidjson::Document root; - root.ParseStream(stream); - - auto ires = IresObject::ReadBasic(root); - if (!ires) { - fprintf(stderr, "Ires file: [" PLATFORM_PATH_STR "] Failed to parse header.", item.path().c_str()); - continue; - } - - // Load name from filename - ires->mName = item.path().filename().replace_extension().string(); - auto& iresName = ires->mName; - - // Load uid should be handled by IresObject::ReadBasic - assert(!ires->mUid.IsNull()); - auto iresUid = ires->GetUid(); - - auto iresKind = ires->GetKind(); - - auto&& [iter, DISCARD] = ctx.candidates.try_emplace( - iresUid, - LoadCandidate{ - .path = item.path(), - .data = std::move(root), - .ires = RcPtr(ires.release()), - }); - auto& cand = iter->second; - - ctx.GetByKind(iresKind).push_back(&cand); - } - - // Load Ires in order by type, there are dependencies between them - // TODO full arbitary dependency between Ires - for (int i = 0; i < IresObject::KD_COUNT; ++i) { - auto kind = static_cast<IresObject::Kind>(i); - auto& list = ctx.GetByKind(kind); - for (auto cand : list) { - auto& ires = cand->ires; - - if (!IresObject::ReadPartial(ctx, ires.Get(), cand->data)) { - fprintf(stderr, "Ires file: [" PLATFORM_PATH_STR "] Failed to parse object data.", cand->path.c_str()); - continue; - } - - ires->mMan = this; - mObjByUid.try_emplace(ires->GetUid(), ires); - } - } -} - -std::pair<IresObject*, bool> IresManager::Add(IresObject* ires) { - auto& name = ires->mName; - if (name.empty()) { - name = Utils::MakeRandomNumberedName(IresObject::ToString(ires->GetKind()).data()); - } - - auto& uid = ires->mUid; - if (uid.IsNull()) { - uid = Uid::Create(); - } - - auto [iter, inserted] = mObjByUid.try_emplace(uid, ires); - if (inserted) { - ires->mMan = this; - // TODO handle full path - return { ires, true }; - } else { - return { iter->second.Get(), false }; - } -} - -IresObject* IresManager::Load(const fs::path& filePath) { - auto file = Utils::OpenCstdioFile(filePath, Utils::Read); - if (!file) return nullptr; - DEFER { fclose(file); }; - - char readerBuffer[65536]; - rapidjson::FileReadStream stream(file, readerBuffer, sizeof(readerBuffer)); - - rapidjson::Document root; - root.ParseStream(stream); - - auto ires = IresObject::ReadFull(*this, root); - if (!ires) { - return nullptr; - } - - // Load uid should be handled by IresObject::ReadFull - assert(!ires->mUid.IsNull()); - // Load name from filename - ires->mName = filePath.filename().replace_extension().string(); - Add(ires.get()); - - return ires.release(); -} - -static fs::path GetDesignatedPath(IresObject* ires) { - return AppConfig::assetDirPath / "Ires" / fs::path(ires->GetName()).replace_extension(".json"); -} - -void IresManager::Delete(IresObject* ires) { - // TODO -} - -bool IresManager::Rename(IresObject* ires, std::string newName) { - auto oldPath = GetDesignatedPath(ires); - ires->mName = std::move(newName); - auto newPath = GetDesignatedPath(ires); - if (fs::exists(oldPath)) { - fs::rename(oldPath, newPath); - } - - // TODO validate no name duplication -#if 0 - if (mObjByPath.contains(newName)) { - return false; - } - - // Keep the material from being deleted, in case the old entry in map is the only one existing - RcPtr rc(ires); - - // Remove old entry (must do before replacing Material::mName, because the std::string_view in the map is a reference to it) - mObjByPath.erase(ires->GetName()); - - // Add new entry - ires->mName = std::move(newName); - // TODO handle full path - mObjByPath.try_emplace(ires->GetName(), ires); -#endif - return true; -} - -void IresManager::Reload(IresObject* ires) { - auto file = Utils::OpenCstdioFile(GetDesignatedPath(ires), Utils::Read); - if (!file) return; - DEFER { fclose(file); }; - - char readerBuffer[65536]; - rapidjson::FileReadStream stream(file, readerBuffer, sizeof(readerBuffer)); - - rapidjson::Document root; - root.ParseStream(stream); - - IresObject::ReadPartial(*this, ires, root); -} - -void IresManager::Save(IresObject* ires) { - Save(ires, GetDesignatedPath(ires)); -} - -void IresManager::Save(IresObject* ires, const fs::path& filePath) { - rapidjson::Document root(rapidjson::kObjectType); - - IresObject::WriteFull(*this, ires, root, root); - - auto file = Utils::OpenCstdioFile(filePath, Utils::WriteTruncate); - if (!file) return; - DEFER { fclose(file); }; - - char writerBuffer[65536]; - rapidjson::FileWriteStream stream(file, writerBuffer, sizeof(writerBuffer)); - rapidjson::PrettyWriter<rapidjson::FileWriteStream> writer(stream); - writer.SetFormatOptions(rapidjson::PrettyFormatOptions::kFormatSingleLineArray); - root.Accept(writer); -} - -IresObject* IresManager::FindIres(const Uid& uid) const { - auto iter = mObjByUid.find(uid); - if (iter != mObjByUid.end()) { - return iter->second.Get(); - } else { - return nullptr; - } -} |