From 419d69f24ebbe6eda71616b0a72d9b50f435d33f Mon Sep 17 00:00:00 2001 From: Panos Karabelas Date: Sat, 30 Nov 2024 07:21:49 +0000 Subject: [PATCH] [resourcecache] simplified how resources work so they only need one file path --- editor/Editor.cpp | 24 +++++----- editor/Widgets/Properties.cpp | 2 +- editor/Widgets/ResourceViewer.cpp | 9 +--- editor/Widgets/TitleBar.cpp | 28 +++++++----- runtime/Core/FileSystem.cpp | 14 ------ runtime/Core/FileSystem.h | 1 - runtime/Rendering/Material.cpp | 8 ++-- runtime/Rendering/Mesh.cpp | 2 +- runtime/Resource/IResource.h | 34 +++------------ runtime/Resource/ResourceCache.cpp | 70 +++--------------------------- runtime/Resource/ResourceCache.h | 27 +++--------- 11 files changed, 55 insertions(+), 164 deletions(-) diff --git a/editor/Editor.cpp b/editor/Editor.cpp index f3eb395ad..afcec7c5d 100644 --- a/editor/Editor.cpp +++ b/editor/Editor.cpp @@ -59,7 +59,7 @@ namespace } } -Editor::Editor(const std::vector& args) +Editor::Editor(const vector& args) { Spartan::Engine::Initialize(args); ImGui::CreateContext(); @@ -197,30 +197,30 @@ void Editor::BeginWindow() ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; - + ImGuiStyle& style = ImGui::GetStyle(); - + // set window position and size const ImGuiViewport* viewport = ImGui::GetMainViewport(); const float padding_offset = 2.0f * (style.FramePadding.y - TitleBar::GetPadding().y) - 1.0f; const float offset_y = widget_menu_bar ? widget_menu_bar->GetHeight() + padding_offset : 0; - + ImGui::SetNextWindowPos(ImVec2(viewport->Pos.x, viewport->Pos.y - offset_y)); ImGui::SetNextWindowSize(ImVec2(viewport->Size.x, viewport->Size.y - offset_y)); ImGui::SetNextWindowViewport(viewport->ID); - + // set window style ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::SetNextWindowBgAlpha(0.0f); - + // begin window std::string name = "##main_window"; bool open = true; ImGui::Begin(name.c_str(), &open, window_flags); ImGui::PopStyleVar(3); - + // begin dock space if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_DockingEnable) { @@ -232,24 +232,24 @@ void Editor::BeginWindow() ImGui::DockBuilderRemoveNode(window_id); ImGui::DockBuilderAddNode(window_id, ImGuiDockNodeFlags_None); ImGui::DockBuilderSetNodeSize(window_id, ImGui::GetMainViewport()->Size); - + // dockBuilderSplitNode(ImGuiID node_id, ImGuiDir split_dir, float size_ratio_for_node_at_dir, ImGuiID* out_id_dir, ImGuiID* out_id_other); ImGuiID dock_main_id = window_id; ImGuiID dock_right_id = ImGui::DockBuilderSplitNode(dock_main_id, ImGuiDir_Right, 0.17f, nullptr, &dock_main_id); ImGuiID dock_right_down_id = ImGui::DockBuilderSplitNode(dock_right_id, ImGuiDir_Down, 0.6f, nullptr, &dock_right_id); ImGuiID dock_down_id = ImGui::DockBuilderSplitNode(dock_main_id, ImGuiDir_Down, 0.22f, nullptr, &dock_main_id); ImGuiID dock_down_right_id = ImGui::DockBuilderSplitNode(dock_down_id, ImGuiDir_Right, 0.5f, nullptr, &dock_down_id); - + // dock windows ImGui::DockBuilderDockWindow("World", dock_right_id); ImGui::DockBuilderDockWindow("Properties", dock_right_down_id); ImGui::DockBuilderDockWindow("Console", dock_down_id); ImGui::DockBuilderDockWindow("Assets", dock_down_right_id); ImGui::DockBuilderDockWindow("Viewport", dock_main_id); - + ImGui::DockBuilderFinish(dock_main_id); } - + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); ImGui::DockSpace(window_id, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_PassthruCentralNode); ImGui::PopStyleVar(); diff --git a/editor/Widgets/Properties.cpp b/editor/Widgets/Properties.cpp index 7c89fa414..e179b2b9b 100644 --- a/editor/Widgets/Properties.cpp +++ b/editor/Widgets/Properties.cpp @@ -193,7 +193,7 @@ void Properties::Inspect(const shared_ptr entity) // If we were previously inspecting a material, save the changes if (!m_inspected_material.expired()) { - m_inspected_material.lock()->SaveToFile(m_inspected_material.lock()->GetResourceFilePathNative()); + m_inspected_material.lock()->SaveToFile(m_inspected_material.lock()->GetResourceFilePath()); } m_inspected_material.reset(); } diff --git a/editor/Widgets/ResourceViewer.cpp b/editor/Widgets/ResourceViewer.cpp index 1867f03d0..5640fa18e 100644 --- a/editor/Widgets/ResourceViewer.cpp +++ b/editor/Widgets/ResourceViewer.cpp @@ -72,14 +72,13 @@ void ResourceViewer::OnTickVisible() ImGuiTableFlags_ScrollY; // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. static ImVec2 size = ImVec2(-1.0f); - if (ImGui::BeginTable("##Widget_ResourceCache", 6, flags, size)) + if (ImGui::BeginTable("##Widget_ResourceCache", 5, flags, size)) { // Headers ImGui::TableSetupColumn("Type"); ImGui::TableSetupColumn("ID"); ImGui::TableSetupColumn("Name"); ImGui::TableSetupColumn("Path"); - ImGui::TableSetupColumn("Path (native)"); ImGui::TableSetupColumn("Size"); ImGui::TableHeadersRow(); @@ -106,12 +105,8 @@ void ResourceViewer::OnTickVisible() ImGui::TableSetColumnIndex(3); ImGui::Text(resource->GetResourceFilePath().c_str()); - // Path (native) - ImGui::TableSetColumnIndex(4); - ImGui::Text(resource->GetResourceFilePathNative().c_str()); - // Memory - ImGui::TableSetColumnIndex(5); + ImGui::TableSetColumnIndex(4); print_memory(object->GetObjectSize()); } } diff --git a/editor/Widgets/TitleBar.cpp b/editor/Widgets/TitleBar.cpp index 970026896..4b5083cf7 100644 --- a/editor/Widgets/TitleBar.cpp +++ b/editor/Widgets/TitleBar.cpp @@ -269,22 +269,28 @@ void TitleBar::EntryWorld() ImGui::Separator(); - if (ImGui::MenuItem("Load")) + // the engine has changed a lot, so I need to re-write resource cache serialization/deserialization + // grey out the options so users know that the functionality is part of the engine but currently disabled + ImGui::BeginDisabled(true); { - ShowWorldLoadDialog(); - } + if (ImGui::MenuItem("Load")) + { + ShowWorldLoadDialog(); + } - ImGui::Separator(); + ImGui::Separator(); - if (ImGui::MenuItem("Save", "Ctrl+S")) - { - ShowWorldSaveDialog(); - } + if (ImGui::MenuItem("Save", "Ctrl+S")) + { + ShowWorldSaveDialog(); + } - if (ImGui::MenuItem("Save As...", "Ctrl+S")) - { - ShowWorldSaveDialog(); + if (ImGui::MenuItem("Save As...", "Ctrl+S")) + { + ShowWorldSaveDialog(); + } } + ImGui::EndDisabled(); ImGui::EndMenu(); } diff --git a/runtime/Core/FileSystem.cpp b/runtime/Core/FileSystem.cpp index b247f5259..6c3384b05 100644 --- a/runtime/Core/FileSystem.cpp +++ b/runtime/Core/FileSystem.cpp @@ -273,20 +273,6 @@ namespace Spartan return extension; } - string FileSystem::NativizeFilePath(const string& path) - { - const string file_path_no_ext = GetFilePathWithoutExtension(path); - - if (IsSupportedAudioFile(path)) return file_path_no_ext + EXTENSION_AUDIO; - if (IsSupportedImageFile(path)) return file_path_no_ext + EXTENSION_TEXTURE; - if (IsSupportedModelFile(path)) return file_path_no_ext + EXTENSION_MODEL; - if (IsSupportedFontFile(path)) return file_path_no_ext + EXTENSION_FONT; - if (IsSupportedShaderFile(path)) return file_path_no_ext + EXTENSION_SHADER; - - SP_LOG_WARNING("Failed to nativize file path"); - return path; - } - vector FileSystem::GetDirectoriesInDirectory(const string& path) { vector directories; diff --git a/runtime/Core/FileSystem.h b/runtime/Core/FileSystem.h index c7cd166ad..c7a9584ed 100644 --- a/runtime/Core/FileSystem.h +++ b/runtime/Core/FileSystem.h @@ -75,7 +75,6 @@ namespace Spartan static std::string GetFilePathWithoutExtension(const std::string& path); static std::string ReplaceExtension(const std::string& path, const std::string& extension); static std::string GetExtensionFromFilePath(const std::string& path); - static std::string NativizeFilePath(const std::string& path); static std::string GetRelativePath(const std::string& path); static std::string GetWorkingDirectory(); static std::string GetRootDirectory(const std::string& path); diff --git a/runtime/Rendering/Material.cpp b/runtime/Rendering/Material.cpp index a867222f8..0bd911dba 100644 --- a/runtime/Rendering/Material.cpp +++ b/runtime/Rendering/Material.cpp @@ -212,7 +212,7 @@ namespace Spartan textureNode.append_attribute("texture_type").set_value(i); textureNode.append_attribute("texture_name").set_value(m_textures[i] ? m_textures[i]->GetObjectName().c_str() : ""); - textureNode.append_attribute("texture_path").set_value(m_textures[i] ? m_textures[i]->GetResourceFilePathNative().c_str() : ""); + textureNode.append_attribute("texture_path").set_value(m_textures[i] ? m_textures[i]->GetResourceFilePath().c_str() : ""); } doc.save_file(file_path.c_str()); @@ -274,7 +274,7 @@ namespace Spartan if (!texture) continue; - if (texture->GetResourceFilePathNative() == path) + if (texture->GetResourceFilePath() == path) return true; } @@ -297,7 +297,7 @@ namespace Spartan if (!HasTextureOfType(texture_type)) return ""; - return m_textures[static_cast(texture_type)]->GetResourceFilePathNative(); + return m_textures[static_cast(texture_type)]->GetResourceFilePath(); } vector Material::GetTexturePaths() @@ -308,7 +308,7 @@ namespace Spartan if (!texture) continue; - paths.emplace_back(texture->GetResourceFilePathNative()); + paths.emplace_back(texture->GetResourceFilePath()); } return paths; diff --git a/runtime/Rendering/Mesh.cpp b/runtime/Rendering/Mesh.cpp index c7ef10766..2b1290783 100644 --- a/runtime/Rendering/Mesh.cpp +++ b/runtime/Rendering/Mesh.cpp @@ -362,7 +362,7 @@ namespace Spartan SP_ASSERT(entity != nullptr); // create a file path for this material (required for the material to be able to be cached by the resource cache) - const string spartan_asset_path = FileSystem::GetDirectoryFromFilePath(GetResourceFilePathNative()) + material->GetObjectName() + EXTENSION_MATERIAL; + const string spartan_asset_path = FileSystem::GetDirectoryFromFilePath(GetResourceFilePath()) + material->GetObjectName() + EXTENSION_MATERIAL; material->SetResourceFilePath(spartan_asset_path); // create a Renderable and pass the material to it diff --git a/runtime/Resource/IResource.h b/runtime/Resource/IResource.h index 6d0630b92..0d19ffa99 100644 --- a/runtime/Resource/IResource.h +++ b/runtime/Resource/IResource.h @@ -59,32 +59,14 @@ namespace Spartan void SetResourceFilePath(const std::string& path) { - const bool is_native_file = FileSystem::IsEngineMaterialFile(path) || FileSystem::IsEngineModelFile(path); - const std::string file_path_relative = FileSystem::GetRelativePath(path); - - // foreign file - if (!FileSystem::IsEngineFile(path)) - { - m_resource_file_path_foreign = file_path_relative; - m_resource_file_path_native = FileSystem::NativizeFilePath(file_path_relative); - } - // engine file - else - { - m_resource_file_path_foreign.clear(); - m_resource_file_path_native = file_path_relative; - } - - m_resource_directory = FileSystem::GetDirectoryFromFilePath(file_path_relative); - m_object_name = FileSystem::GetFileNameWithoutExtensionFromFilePath(file_path_relative); + m_resource_file_path = FileSystem::GetRelativePath(path); + m_object_name = FileSystem::GetFileNameWithoutExtensionFromFilePath(m_resource_file_path); } - ResourceType GetResourceType() const { return m_resource_type; } - const char* GetResourceTypeCstr() const { return typeid(*this).name(); } - bool HasFilePathNative() const { return !m_resource_file_path_native.empty(); } - const std::string& GetResourceFilePath() const { return m_resource_file_path_foreign; } - const std::string& GetResourceFilePathNative() const { return m_resource_file_path_native; } - const std::string& GetResourceDirectory() const { return m_resource_directory; } + ResourceType GetResourceType() const { return m_resource_type; } + const char* GetResourceTypeCstr() const { return typeid(*this).name(); } + const std::string& GetResourceFilePath() const { return m_resource_file_path; } + const std::string& GetResourceDirectory() const { return FileSystem::GetDirectoryFromFilePath(m_resource_file_path); } // flags void SetFlag(const uint32_t flag, bool enabled = true) @@ -117,8 +99,6 @@ namespace Spartan uint32_t m_flags = 0; private: - std::string m_resource_directory; - std::string m_resource_file_path_native; - std::string m_resource_file_path_foreign; + std::string m_resource_file_path; }; } diff --git a/runtime/Resource/ResourceCache.cpp b/runtime/Resource/ResourceCache.cpp index 1321a20cd..47913ca2d 100644 --- a/runtime/Resource/ResourceCache.cpp +++ b/runtime/Resource/ResourceCache.cpp @@ -66,9 +66,9 @@ namespace Spartan SP_SUBSCRIBE_TO_EVENT(EventType::WorldClear, SP_EVENT_HANDLER_STATIC(Shutdown)); } - bool ResourceCache::IsCached(const string& resource_file_path_native, const ResourceType resource_type) + bool ResourceCache::IsCached(const string& file_path, const ResourceType resource_type) { - SP_ASSERT(!resource_file_path_native.empty()); + SP_ASSERT(!file_path.empty()); lock_guard guard(m_mutex); @@ -77,7 +77,7 @@ namespace Spartan if (resource->GetResourceType() != resource_type) continue; - if (resource_file_path_native == resource->GetResourceFilePathNative()) + if (file_path == resource->GetResourceFilePath()) return true; } @@ -148,72 +148,12 @@ namespace Spartan void ResourceCache::Serialize() { - // create resource list file - string file_path = GetProjectDirectoryAbsolute() + World::GetName() + ".resource"; - auto file = make_unique(file_path, FileStream_Write); - if (!file->IsOpen()) - { - SP_LOG_ERROR("Failed to open file."); - return; - } - - const uint32_t resource_count = GetResourceCount(); - - // start progress report - ProgressTracker::GetProgress(ProgressType::Resource).Start(resource_count, "Loading resources..."); - - // save resource count - file->Write(resource_count); - - // save all the currently used resources to disk - for (shared_ptr& resource : m_resources) - { - if (resource->HasFilePathNative()) - { - SP_ASSERT_MSG(!resource->GetResourceFilePathNative().empty(), "Resources must have a native file path"); - SP_ASSERT_MSG(resource->GetResourceType() != ResourceType::Max, "Resources must have a type"); - - file->Write(resource->GetResourceFilePathNative()); // file path - file->Write(static_cast(resource->GetResourceType())); // type - resource->SaveToFile(resource->GetResourceFilePathNative()); // save - } - - // update progress - ProgressTracker::GetProgress(ProgressType::Resource).JobDone(); - } + // todo: since we won't be using custom file formats, we just need to save the resource paths, simple and reliable } void ResourceCache::Deserialize() { - // open file - string file_path = GetProjectDirectoryAbsolute() + World::GetName() + ".resource"; - unique_ptr file = make_unique(file_path, FileStream_Read); - if (!file->IsOpen()) - return; - - // go through each resource and load it - const uint32_t resource_count = file->ReadAs(); - for (uint32_t i = 0; i < resource_count; i++) - { - string file_path = file->ReadAs(); - const ResourceType type = static_cast(file->ReadAs()); - - switch (type) - { - case ResourceType::Mesh: - Load(file_path); - break; - case ResourceType::Material: - Load(file_path); - break; - case ResourceType::Texture: - Load(file_path); - break; - case ResourceType::Audio: - Load(file_path); - break; - } - } + // todo: we just need to load the resource paths, simple and reliable } void ResourceCache::Shutdown() diff --git a/runtime/Resource/ResourceCache.h b/runtime/Resource/ResourceCache.h index aa1dc824f..1110c9e5c 100644 --- a/runtime/Resource/ResourceCache.h +++ b/runtime/Resource/ResourceCache.h @@ -61,7 +61,7 @@ namespace Spartan { for (std::shared_ptr& resource : GetResources()) { - if (path == resource->GetResourceFilePathNative()) + if (path == resource->GetResourceFilePath()) return std::static_pointer_cast(resource); } @@ -72,29 +72,14 @@ namespace Spartan template static std::shared_ptr Cache(const std::shared_ptr resource) { - // validate resource if (!resource) return nullptr; - // validate resource file path - if (!resource->HasFilePathNative() && !FileSystem::IsDirectory(resource->GetResourceFilePathNative())) - { - SP_LOG_ERROR("A resource must have a valid file path in order to be cached"); - return nullptr; - } - - // validate resource file path - if (!FileSystem::IsEngineFile(resource->GetResourceFilePathNative())) - { - SP_LOG_ERROR("A resource must have a native file format in order to be cached, provide format was %s", FileSystem::GetExtensionFromFilePath(resource->GetResourceFilePathNative()).c_str()); - return nullptr; - } - - // ensure that this resource is not already cached - if (IsCached(resource->GetResourceFilePathNative(), resource->GetResourceType())) - return GetByPath(resource->GetResourceFilePathNative()); + // if cached, return the cached resource + if (IsCached(resource->GetResourceFilePath(), resource->GetResourceType())) + return GetByPath(resource->GetResourceFilePath()); - // cache it + // if not, cache it and return the cached resource std::lock_guard guard(GetMutex()); return std::static_pointer_cast(GetResources().emplace_back(resource)); } @@ -173,7 +158,7 @@ namespace Spartan private: static bool IsCached(const uint64_t resource_id); - static bool IsCached(const std::string& resource_name, const ResourceType resource_type); + static bool IsCached(const std::string& file_path, const ResourceType resource_type); // event handlers static void Serialize();