aboutsummaryrefslogtreecommitdiff
path: root/source/30-game/Ires.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2023-10-19 22:50:07 -0700
committerrtk0c <[email protected]>2025-08-16 11:31:16 -0700
commit297232d21594b138bb368a42b5b0d085ff9ed6aa (patch)
tree075d5407e1e12a9d35cbee6e4c20ad34e0765c42 /source/30-game/Ires.cpp
parentd5cd34ff69f7fd134d5450696f298af1a864afbc (diff)
The great renaming: switch to "module style"
Diffstat (limited to 'source/30-game/Ires.cpp')
-rw-r--r--source/30-game/Ires.cpp436
1 files changed, 0 insertions, 436 deletions
diff --git a/source/30-game/Ires.cpp b/source/30-game/Ires.cpp
deleted file mode 100644
index 0529395..0000000
--- a/source/30-game/Ires.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-#include "Ires.hpp"
-
-#include "AppConfig.hpp"
-#include "EditorCore.hpp"
-#include "EditorUtils.hpp"
-#include "Material.hpp"
-#include "Shader.hpp"
-#include "Sprite.hpp"
-#include "Texture.hpp"
-
-#include <Macros.hpp>
-#include <Metadata.hpp>
-#include <RapidJsonHelper.hpp>
-#include <ScopeGuard.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::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", PRINTF_STRING_VIEW(Metadata::EnumToString(mKind)));
-
- 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(Metadata::EnumToString(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) {
- std::unique_ptr<IresObject> ires;
- Uid uid;
- for (auto it = value.MemberBegin(); it != value.MemberEnd(); ++it) {
- if (it->name == "Type"_rj_sv) {
- if (it->value.GetType() != rapidjson::kStringType)
- return nullptr;
- auto kind = Metadata::EnumFromString<Kind>(rapidjson::AsStringView(it->value));
- if (!kind.has_value())
- return nullptr;
- if ((ires = Create(*kind)) == nullptr)
- return nullptr;
- } else if (it->name == "Uid"_rj_sv) {
- // FIXME this needs to do type checks
- uid.Read(it->value);
- }
- }
- if (ires == nullptr || uid.IsNull())
- return nullptr;
-
- ires->mUid = uid;
- 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((int)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.\n", 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 < (int)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.\n", 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(Metadata::EnumToString(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);
- // We no longer need this after disabling BRUSSEL_Uid_WRITE_USE_ARRAY
-// writer.SetFormatOptions(rapidjson::PrettyFormatOptions::kFormatSingleLineArray);
-#if BRUSSEL_Uid_WRITE_USE_ARRAY
-# warning "Writing Uid in array format but single line formatting isn't enabled, this might cause excessively long ires files."
-#endif
- root.Accept(writer);
-}
-
-void IresManager::OverwriteAllToDisk() {
- for (const auto& [DISCARD, ires] : mObjByUid) {
- Save(ires.Get());
- }
-}
-
-IresObject* IresManager::FindIres(const Uid& uid) const {
- auto iter = mObjByUid.find(uid);
- if (iter != mObjByUid.end()) {
- return iter->second.Get();
- } else {
- return nullptr;
- }
-}
-
-#include <generated/Ires.gs.inl>