diff --git a/Nuake/Engine.cpp b/Nuake/Engine.cpp index 8423ae00..5a1cb935 100644 --- a/Nuake/Engine.cpp +++ b/Nuake/Engine.cpp @@ -21,6 +21,8 @@ #include #include +#include + #ifdef NK_VK #include "src/Rendering/Vulkan/VulkanRenderer.h" #endif @@ -371,12 +373,17 @@ namespace Nuake { currentProject = project; + // TODO(antopilo) only generate manifest in editor context + + FileSystem::SetRootDirectory(FileSystem::GetParentPath(project->FullPath)); + + GenerateManifest(project); + if (!Engine::SetCurrentScene(currentProject->DefaultScene)) { return false; } - FileSystem::SetRootDirectory(FileSystem::GetParentPath(project->FullPath)); ScriptingEngineNet::Get().Initialize(); ScriptingEngineNet::Get().LoadProjectAssembly(project); @@ -387,4 +394,25 @@ namespace Nuake { return currentWindow; } + + void Engine::GenerateManifest() + { + // This will auto generate a manifest entry for all assets in the project + ResourceManifest& manifest = ResourceManager::Manifest; + ResourceResolverManager& resolverManager = ResourceResolverManager::Get(); + OnFileFunc onFileScanFunc = [&resolverManager, &manifest](Ref file) + { + if (!resolverManager.IsFileTypeResolvable(file->GetExtension())) + { + return; // We don't care about this file type, we dont support it. + } + + // Register the resource in the manifest + const std::string& path = file->GetRelativePath(); + const UUID uuid = resolverManager.ResolveUUID(file); + manifest.RegisterResource(uuid, path); + }; + + FileSystem::ForeachFile(onFileScanFunc); + } } diff --git a/Nuake/Engine.h b/Nuake/Engine.h index c9563837..83b91930 100644 --- a/Nuake/Engine.h +++ b/Nuake/Engine.h @@ -85,6 +85,8 @@ namespace Nuake static Timestep timeStep; static float timeScale; + private: + static void GenerateManifest(); }; } diff --git a/Nuake/src/FileSystem/FileSystem.cpp b/Nuake/src/FileSystem/FileSystem.cpp index 5fe21154..1e63c947 100644 --- a/Nuake/src/FileSystem/FileSystem.cpp +++ b/Nuake/src/FileSystem/FileSystem.cpp @@ -18,12 +18,12 @@ std::string FileSystem::Root = ""; Ref FileSystem::RootDirectory; Ref> FileSystem::RootFileWatch; -void FileSystem::ForeachFile(std::function)> func) +void FileSystem::ForeachFile(OnFileFunc func) { ForeachFile(func, RootDirectory); } -void FileSystem::ForeachFile(std::function)> func, Ref dir) +void FileSystem::ForeachFile(OnFileFunc func, Ref dir) { for(auto& file : RootDirectory->Files) { diff --git a/Nuake/src/FileSystem/FileSystem.h b/Nuake/src/FileSystem/FileSystem.h index 316979a2..0130b849 100644 --- a/Nuake/src/FileSystem/FileSystem.h +++ b/Nuake/src/FileSystem/FileSystem.h @@ -15,6 +15,8 @@ namespace Nuake class Directory; class File; + using OnFileFunc = std::function)>; + class FileSystem { public: @@ -25,10 +27,10 @@ namespace Nuake static void SetRootDirectory(const std::string path); // Starts from root - static void ForeachFile(std::function)> func); + static void ForeachFile(OnFileFunc func); // Strats from specified folder - static void ForeachFile(std::function)> func, Ref dir); + static void ForeachFile(OnFileFunc func, Ref dir); static void Scan(); static std::string AbsoluteToRelative(const std::string& path); diff --git a/Nuake/src/Resource/Resolvers/IResourceResolver.h b/Nuake/src/Resource/Resolvers/IResourceResolver.h index c1199fee..0e466a7b 100644 --- a/Nuake/src/Resource/Resolvers/IResourceResolver.h +++ b/Nuake/src/Resource/Resolvers/IResourceResolver.h @@ -20,6 +20,7 @@ namespace Nuake virtual ~IResourceResolver() = default; // Converts a file to a resource UUID + virtual UUID ResolveUUID(const Ref& file) = 0; virtual Ref Resolve(const Ref& file) = 0; std::string GetExtension() const { return Extension; } diff --git a/Nuake/src/Resource/Resolvers/MeshResolver.cpp b/Nuake/src/Resource/Resolvers/MeshResolver.cpp index 27acaf4b..47f46a8b 100644 --- a/Nuake/src/Resource/Resolvers/MeshResolver.cpp +++ b/Nuake/src/Resource/Resolvers/MeshResolver.cpp @@ -8,12 +8,30 @@ using namespace Nuake; +UUID MeshResolver::ResolveUUID(const Ref& file) +{ + BinarySerializer deserializer = BinarySerializer(); + return deserializer.DeserializeUUID(file->GetRelativePath()); +} + Ref MeshResolver::Resolve(const Ref& file) { BinarySerializer deserializer = BinarySerializer(); return deserializer.DeserializeModel(file->GetRelativePath()); } +UUID MaterialResolver::ResolveUUID(const Ref& file) +{ + std::string fileContent = FileSystem::ReadFile(file->GetRelativePath()); + json jsonData = json::parse(fileContent); + if (jsonData.contains("UUID")) + { + return static_cast(jsonData["UUID"]); + } + + return UUID(); +} + Ref MaterialResolver::Resolve(const Ref& file) { // Read json content diff --git a/Nuake/src/Resource/Resolvers/MeshResolver.h b/Nuake/src/Resource/Resolvers/MeshResolver.h index 65de7a81..9d29e746 100644 --- a/Nuake/src/Resource/Resolvers/MeshResolver.h +++ b/Nuake/src/Resource/Resolvers/MeshResolver.h @@ -9,6 +9,7 @@ namespace Nuake { public: MeshResolver() : IResourceResolver(".nkmesh") {} + UUID ResolveUUID(const Ref& file) override; Ref Resolve(const Ref& file) override; }; @@ -16,6 +17,7 @@ namespace Nuake { public: MaterialResolver() : IResourceResolver(".material") {} + UUID ResolveUUID(const Ref& file) override; Ref Resolve(const Ref& file) override; }; } \ No newline at end of file diff --git a/Nuake/src/Resource/Resolvers/ResolverManager.h b/Nuake/src/Resource/Resolvers/ResolverManager.h index f10811c5..f5d675b3 100644 --- a/Nuake/src/Resource/Resolvers/ResolverManager.h +++ b/Nuake/src/Resource/Resolvers/ResolverManager.h @@ -27,16 +27,45 @@ namespace Nuake Resolvers[resolver->GetExtension()] = resolver; } - Ref Resolve(const Ref file) + bool IsFileTypeResolvable(const std::string& extension) { - std::string extension = file->GetExtension(); - if (Resolvers.find(extension) != Resolvers.end()) + return Resolvers.find(extension) != Resolvers.end(); + } + + Ref GetResolverForFile(const Ref& file) + { + const std::string extension = file->GetExtension(); + if (IsFileTypeResolvable(extension)) { - return Resolvers[extension]->Resolve(file); + return Resolvers[extension]; } Logger::Log("Failed to find resolver for file type: " + extension, "resolver", CRITICAL); return nullptr; } + + // This will only read the UUID of a resource file + UUID ResolveUUID(const Ref file) + { + Ref resolver = GetResolverForFile(file); + if (resolver) + { + return resolver->ResolveUUID(file); + } + + return UUID(0); + } + + Ref Resolve(const Ref file) + { + Ref resolver = GetResolverForFile(file); + if (resolver) + { + return resolver->Resolve(file); + } + + Logger::Log("Failed to resolve file: " + file->GetRelativePath(), "resolver", CRITICAL); + return nullptr; + } }; } diff --git a/Nuake/src/Resource/Serializer/BinarySerializer.cpp b/Nuake/src/Resource/Serializer/BinarySerializer.cpp index a895fb55..b4cd1224 100644 --- a/Nuake/src/Resource/Serializer/BinarySerializer.cpp +++ b/Nuake/src/Resource/Serializer/BinarySerializer.cpp @@ -77,6 +77,19 @@ public: } }; +UUID BinarySerializer::DeserializeUUID(const std::string& path) +{ + BinaryReader reader = BinaryReader(FileSystem::RelativeToAbsolute(path)); + if (!reader.IsOpen()) + { + return UUID(0); + } + + uint64_t rid; + reader.Read(&rid); + return rid; +} + Ref BinarySerializer::DeserializeMaterial(const std::string& path) { BinaryReader reader = BinaryReader(path); diff --git a/Nuake/src/Resource/Serializer/BinarySerializer.h b/Nuake/src/Resource/Serializer/BinarySerializer.h index 3ad665ff..b8161a78 100644 --- a/Nuake/src/Resource/Serializer/BinarySerializer.h +++ b/Nuake/src/Resource/Serializer/BinarySerializer.h @@ -15,6 +15,8 @@ namespace Nuake ~BinarySerializer() = default; public: + UUID DeserializeUUID(const std::string& path); + Ref DeserializeMaterial(const std::string& path) override; bool SerializeMaterial(const std::string& path, Ref material) override; diff --git a/Nuake/src/Scripting/NetModules/SceneNetAPI.cpp b/Nuake/src/Scripting/NetModules/SceneNetAPI.cpp index 7820b108..833a616d 100644 --- a/Nuake/src/Scripting/NetModules/SceneNetAPI.cpp +++ b/Nuake/src/Scripting/NetModules/SceneNetAPI.cpp @@ -57,8 +57,7 @@ namespace Nuake { if (scriptingEngine.HasEntityScriptInstance(entity)) { auto instance = scriptingEngine.GetEntityScript(entity); - outInstance->m_Handle = instance->m_Handle; - outInstance->m_Type = instance->m_Type; + *outInstance= *instance; } }