Transition

This commit is contained in:
Chewico 2026-03-09 23:16:47 +01:00
parent b72fb412a7
commit 76f2204074
14 changed files with 77 additions and 131 deletions

View File

@ -3,8 +3,8 @@
#ifdef DEER_RENDER #ifdef DEER_RENDER
#include "DeerRender/Mesh.h" #include "DeerRender/Mesh.h"
#include "DeerRender/Shader.h"
#include "DeerRender/Resource.h" #include "DeerRender/Resource.h"
#include "DeerRender/Shader.h"
#include "DeerRender/Tools/Memory.h" #include "DeerRender/Tools/Memory.h"
#include <functional> #include <functional>
@ -16,8 +16,8 @@ namespace Deer {
bool includeServer = false; bool includeServer = false;
bool includeClient = true; bool includeClient = true;
std::function<Resource<GPUMesh>(StorageType)> meshLoadingFunction = nullptr; std::function<Resource<GPUMesh>(ResourceId)> meshLoadingFunction = nullptr;
std::function<Resource<Shader>(StorageType)> shaderLoadingFunction = nullptr; std::function<Resource<Shader>(ResourceId)> shaderLoadingFunction = nullptr;
#else #else
bool includeServer = true; bool includeServer = true;
bool includeClient = false; bool includeClient = false;

View File

@ -11,23 +11,23 @@
namespace Deer { namespace Deer {
template <typename T> template <typename T>
class ResourceManager; class ResourceManager;
typedef uint32_t StorageType; typedef uint32_t ResourceId;
StorageType generatePhyisicalStorageId(); ResourceId generatePhyisicalStorageId();
StorageType generateRuntimeStorageId(); ResourceId generateRuntimeStorageId();
template <typename DataSource> template <typename DataSource>
class StorageBackend { class StorageBackend {
public: public:
template <typename T> template <typename T>
static Scope<T> load(StorageType storageId); static Scope<T> load(ResourceId storageId);
}; };
template <typename T> template <typename T>
class Resource { class Resource {
public: public:
int32_t getResourceId() const { return resourceId; } int32_t getResourceId() const { return resourceId; }
StorageType getStorageId() const { return ResourceManager<T>::getStorageId(*this); } ResourceId getStorageId() const { return ResourceManager<T>::getStorageId(*this); }
bool isValid() const { return ResourceManager<T>::isValid(*this); } bool isValid() const { return ResourceManager<T>::isValid(*this); }
T& getData() { return ResourceManager<T>::getResourceData(*this); } T& getData() { return ResourceManager<T>::getResourceData(*this); }
@ -61,15 +61,15 @@ namespace Deer {
struct ResourceData { struct ResourceData {
public: public:
Scope<T> data = nullptr; Scope<T> data = nullptr;
StorageType storageId = 0; ResourceId storageId = 0;
}; };
static std::vector<ResourceData> resources; static std::vector<ResourceData> resources;
static std::unordered_map<StorageType, Resource<T>> resourceCache; static std::unordered_map<ResourceId, Resource<T>> resourceCache;
public: public:
template <typename DataSource> template <typename DataSource>
static Resource<T> loadResource(StorageType storageId) { static Resource<T> loadResource(ResourceId storageId) {
if (resourceCache.contains(storageId)) if (resourceCache.contains(storageId))
return resourceCache[storageId]; return resourceCache[storageId];
@ -91,14 +91,14 @@ namespace Deer {
return resource; return resource;
} }
static Resource<T> getResource(StorageType storageId) { static Resource<T> getResource(ResourceId storageId) {
if (resourceCache.contains(storageId)) if (resourceCache.contains(storageId))
return resourceCache[storageId]; return resourceCache[storageId];
return Resource<T>(); return Resource<T>();
} }
static Resource<T> loadResourceFromData(const typename ResourceBuilder<T>::BaseDataType& resourceData, StorageType storageId) { static Resource<T> loadResourceFromData(const typename ResourceBuilder<T>::BaseDataType& resourceData, ResourceId storageId) {
if (resourceCache.contains(storageId)) if (resourceCache.contains(storageId))
return resourceCache[storageId]; return resourceCache[storageId];
@ -123,7 +123,7 @@ namespace Deer {
return res.resourceId >= 0 && res.resourceId < static_cast<int32_t>(resources.size()); return res.resourceId >= 0 && res.resourceId < static_cast<int32_t>(resources.size());
} }
static inline StorageType getStorageId(Resource<T> res) { static inline ResourceId getStorageId(Resource<T> res) {
if (!isValid(res)) if (!isValid(res))
return 0; return 0;
@ -138,7 +138,7 @@ namespace Deer {
template <typename T> template <typename T>
std::vector<typename ResourceManager<T>::ResourceData> ResourceManager<T>::resources; std::vector<typename ResourceManager<T>::ResourceData> ResourceManager<T>::resources;
template <typename T> template <typename T>
std::unordered_map<StorageType, Resource<T>> ResourceManager<T>::resourceCache; std::unordered_map<ResourceId, Resource<T>> ResourceManager<T>::resourceCache;
} // namespace Deer } // namespace Deer
// BUILTIN RESOURCE IDS // BUILTIN RESOURCE IDS

View File

@ -3,11 +3,11 @@
#include <random> #include <random>
namespace Deer { namespace Deer {
StorageType generatePhyisicalStorageId() { ResourceId generatePhyisicalStorageId() {
return std::random_device{}() | 0x80000000; return std::random_device{}() | 0x80000000;
} }
StorageType generateRuntimeStorageId() { ResourceId generateRuntimeStorageId() {
return std::random_device{}() & 0x7FFFFFF; return std::random_device{}() & 0x7FFFFFF;
} }
} // namespace Deer } // namespace Deer

View File

@ -29,6 +29,10 @@ namespace Deer {
return ResourceManager<FrameBuffer>::loadResourceFromData(spec, generateRuntimeStorageId()); return ResourceManager<FrameBuffer>::loadResourceFromData(spec, generateRuntimeStorageId());
} }
void resource_defaultConstructor(void* mem) {
new (mem) ResourceId(0);
}
int frameBuffer_getWidth(Resource<FrameBuffer>& frameBuffer) { int frameBuffer_getWidth(Resource<FrameBuffer>& frameBuffer) {
return frameBuffer.getData().getSpecification().width; return frameBuffer.getData().getSpecification().width;
} }

View File

@ -13,16 +13,6 @@ namespace Deer {
class Shader; class Shader;
namespace Scripting { namespace Scripting {
template <typename T>
std::string resource_getPath(Resource<T> resource) {
return ResourceManager<T>::getStorageId(resource);
}
template <typename T>
std::string resource_getName(Resource<T> resource) {
return ResourceManager<T>::getStorageId(resource).stem().string();
}
enum ResourceType : uint32_t { enum ResourceType : uint32_t {
NONE = 0, NONE = 0,
MESH = 1, MESH = 1,
@ -33,6 +23,7 @@ namespace Deer {
// GENERIC RESOURCE // GENERIC RESOURCE
template <typename T> template <typename T>
bool resource_isValid(Resource<T>& resource) { return resource.isValid(); } bool resource_isValid(Resource<T>& resource) { return resource.isValid(); }
void resource_defaultConstructor(void*);
// Frame Buffer // Frame Buffer
int frameBuffer_getWidth(Resource<FrameBuffer>&); int frameBuffer_getWidth(Resource<FrameBuffer>&);

View File

@ -25,7 +25,7 @@ namespace Deer {
} // namespace Scripting } // namespace Scripting
void Scripting::registerResourceStructs() { void Scripting::registerResourceStructs() {
AS_CHECK(scriptEngine->RegisterObjectType("StorageId", sizeof(StorageType), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<StorageType>())); AS_CHECK(scriptEngine->RegisterObjectType("StorageId", sizeof(ResourceId), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<ResourceId>()));
AS_CHECK(scriptEngine->RegisterObjectType("GPUMesh", sizeof(Resource<GPUMesh>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<GPUMesh>>())); AS_CHECK(scriptEngine->RegisterObjectType("GPUMesh", sizeof(Resource<GPUMesh>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<GPUMesh>>()));
AS_CHECK(scriptEngine->RegisterObjectType("Shader", sizeof(Resource<Shader>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<Shader>>())); AS_CHECK(scriptEngine->RegisterObjectType("Shader", sizeof(Resource<Shader>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<Shader>>()));
@ -36,8 +36,10 @@ namespace Deer {
Resource<FrameBuffer> createFrameBuffer(const std::string name, int sixeX, int sizeY); Resource<FrameBuffer> createFrameBuffer(const std::string name, int sixeX, int sizeY);
void Scripting::registerResourceFunctions() { void Scripting::registerResourceFunctions() {
REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "StorageId", "void f()", resource_defaultConstructor);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "int get_width() const property", frameBuffer_getWidth); REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "int get_width() const property", frameBuffer_getWidth);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "int get_height() const property", frameBuffer_getHeight); REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "int get_heighqt() const property", frameBuffer_getHeight);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "bool isValid()", frameBuffer_isValid); REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "bool isValid()", frameBuffer_isValid);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "void resize(int, int)", frameBuffer_resize); REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "void resize(int, int)", frameBuffer_resize);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "void clearRGBA(int, int, int, int)", frameBuffer_clearRGBA); REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "void clearRGBA(int, int, int, int)", frameBuffer_clearRGBA);

View File

@ -19,21 +19,15 @@ namespace Deer {
template <class Archive> template <class Archive>
void load(Archive& archive) { void load(Archive& archive) {
StorageType storageId_mesh; ResourceId storageId_mesh;
StorageType storageId_shader; ResourceId storageId_shader;
archive(cereal::make_nvp("IsActive", component.active)); archive(cereal::make_nvp("IsActive", component.active));
archive(cereal::make_nvp("Mesh", storageId_mesh)); archive(cereal::make_nvp("Mesh", storageId_mesh));
archive(cereal::make_nvp("Shader", storageId_shader)); archive(cereal::make_nvp("Shader", storageId_shader));
Scope<MeshData> meshData = settings.meshLoadingFunction(storageId_mesh); component.mesh = settings.meshLoadingFunction(storageId_mesh);
Scope<ShaderData> shaderData = settings.shaderLoadingFunction(storageId_shader); component.shader = settings.shaderLoadingFunction(storageId_shader);
Resource<GPUMesh> mesh = ResourceManager<GPUMesh>::loadResourceFromData(*meshData.get(), storageId_mesh);
component.mesh = mesh;
Resource<Shader> shader = ResourceManager<Shader>::loadResourceFromData(*shaderData.get(), storageId_shader);
component.shader = shader;
} }
}; };
} // namespace Deer } // namespace Deer

View File

@ -21,15 +21,9 @@ namespace Deer {
int32_t resourceFolder_getResourceCount(int32_t&); int32_t resourceFolder_getResourceCount(int32_t&);
int32_t resourceFolder_getResourceIdByIndex(int32_t&); int32_t resourceFolder_getResourceIdByIndex(int32_t&);
Resource<Texture> std::string resourceId_getName(ResourceId&);
getIcon(std::string&); std::string resourceId_getPath(ResourceId&);
int32_t resourceId_getFolder(ResourceId&);
CScriptArray* getResourceFolders(std::string& path); ResourceType resourceId_getType(ResourceId&);
CScriptArray* getResourceFiles(std::string& path);
CScriptDictionary* getResourceMetadata(std::string& resource);
CScriptDictionary* setResourceMetadata(std::string& resource);
ResourceType getResourceType(std::string&);
} // namespace StudioAPI } // namespace StudioAPI
} // namespace Deer } // namespace Deer

View File

@ -3,7 +3,6 @@
#include "DeerRender/Tools/Path.h" #include "DeerRender/Tools/Path.h"
#include "cereal/cereal.hpp" #include "cereal/cereal.hpp"
#include <string> #include <string>
namespace Deer { namespace Deer {
@ -41,25 +40,33 @@ namespace Deer {
} }
}; };
struct FolderInfo {
std::string name;
std::string parent;
std::string fullPath;
std::vector<uint32_t> resources;
std::vector<std::string> subfolders;
};
namespace StudioResources { namespace StudioResources {
ResourceInformation* getResourceInfoFromPath(const std::string& path); ResourceInformation* getResourceInfoFromPath(const std::string& path);
ResourceInformation* getResourceInfoFromId(uint32_t resource); ResourceInformation* getResourceInfoFromId(uint32_t resource);
FolderInfo* getFolderInfoFromPath(std::string folderStr);
void scanResources(); void scanResources();
} // namespace StudioResources } // namespace StudioResources
template <> template <>
class StorageBackend<EditorDataSource> { class StorageBackend<EditorDataSource> {
public: public:
template <typename T> template <typename T>
static Scope<T> load(StorageType storageId); static Scope<T> load(ResourceId storageId);
template <> template <>
Scope<MeshData> load(StorageType storageId); Scope<MeshData> load(ResourceId storageId);
template <> template <>
Scope<ShaderData> load(StorageType storageId); Scope<ShaderData> load(ResourceId storageId);
template <> template <>
Scope<TextureData> load(StorageType storageId); Scope<TextureData> load(ResourceId storageId);
}; };
} // namespace Deer } // namespace Deer

View File

@ -15,7 +15,7 @@ namespace Deer {
Scope<MeshData> convertAssimpMesh(const aiMesh* mesh); Scope<MeshData> convertAssimpMesh(const aiMesh* mesh);
template <> template <>
Scope<MeshData> StorageBackend<EditorDataSource>::load(StorageType storageId) { Scope<MeshData> StorageBackend<EditorDataSource>::load(ResourceId storageId) {
ResourceInformation* info = StudioResources::getResourceInfoFromId(storageId); ResourceInformation* info = StudioResources::getResourceInfoFromId(storageId);
if (!info) if (!info)
return Scope<MeshData>(); return Scope<MeshData>();

View File

@ -32,7 +32,7 @@ namespace Deer {
} }
template <> template <>
Scope<ShaderData> StorageBackend<EditorDataSource>::load(StorageType storageId) { Scope<ShaderData> StorageBackend<EditorDataSource>::load(ResourceId storageId) {
ResourceInformation* info = StudioResources::getResourceInfoFromId(storageId); ResourceInformation* info = StudioResources::getResourceInfoFromId(storageId);
if (!info) if (!info)
return Scope<ShaderData>(); return Scope<ShaderData>();

View File

@ -8,7 +8,7 @@
namespace Deer { namespace Deer {
template <> template <>
Scope<TextureData> StorageBackend<EditorDataSource>::load(StorageType storageId) { Scope<TextureData> StorageBackend<EditorDataSource>::load(ResourceId storageId) {
ResourceInformation* info = StudioResources::getResourceInfoFromId(storageId); ResourceInformation* info = StudioResources::getResourceInfoFromId(storageId);
if (!info) if (!info)
return Scope<TextureData>(); return Scope<TextureData>();

View File

@ -10,65 +10,20 @@
#include "scriptdictionary.h" #include "scriptdictionary.h"
namespace Deer { namespace Deer {
ResourceType StudioAPI::getResourceType(std::string& dir) { int32_t StudioAPI::getResourceFolder(std::string& path) {
Path path(dir);
std::string extension = path.extension().string();
if (extension == ".obj" || extension == ".fbx" || extension == ".dae" ||
extension == ".3ds" || extension == ".ply" || extension == ".stl" ||
extension == ".glb" || extension == ".gltf") {
return ResourceType::MESH;
} }
bool StudioAPI::resourceFolder_isValid(int32_t&);
bool StudioAPI::resourceFolder_isRoot(int32_t&);
std::string StudioAPI::resourceFolder_getName(int32_t&);
std::string StudioAPI::resourceFolder_getFullPath(int32_t&);
int32_t StudioAPI::resourceFolder_getParentFolder(int32_t&);
int32_t StudioAPI::resourceFolder_getSubFolderCount(int32_t&);
int32_t StudioAPI::resourceFolder_getSubfolderByIndex(int32_t, int32_t&);
int32_t StudioAPI::resourceFolder_getResourceCount(int32_t&);
int32_t StudioAPI::resourceFolder_getResourceIdByIndex(int32_t&);
if (extension == ".glsl") std::string StudioAPI::resourceId_getName(ResourceId&);
return ResourceType::SHADER; std::string StudioAPI::resourceId_getPath(ResourceId&);
int32_t StudioAPI::resourceId_getFolder(ResourceId&);
if (extension == ".png") ResourceType StudioAPI::resourceId_getType(ResourceId&);
return ResourceType::TEXTURE;
return ResourceType::NONE;
};
CScriptArray* StudioAPI::getResourceFolders(std::string& path_s) {
asITypeInfo* arrayString = Scripting::getScriptEngine()->GetTypeInfoByDecl("array<string>");
CScriptArray* array = CScriptArray::Create(arrayString);
Path path_p = Path("Resources") / Path(path_s).lexically_normal();
try {
for (const auto& entry : std::filesystem::directory_iterator(path_p)) {
if (entry.is_directory()) {
std::string s = entry.path().lexically_relative("Resources").string();
array->Resize(array->GetSize() + 1);
array->SetValue(array->GetSize() - 1, &s);
}
}
} catch (const std::exception& e) {
DEER_EDITOR_ENGINE_ERROR("Error in getResourceFolders(), {}", e.what());
}
return array;
}
CScriptArray* StudioAPI::getResourceFiles(std::string& path_s) {
asITypeInfo* arrayString = Scripting::getScriptEngine()->GetTypeInfoByDecl("array<string>");
CScriptArray* array = CScriptArray::Create(arrayString);
Path path_p = Path("Resources") / Path(path_s).lexically_normal();
try {
for (const auto& entry : std::filesystem::directory_iterator(path_p)) {
if (entry.is_regular_file()) {
std::string s = entry.path().lexically_relative("Resources").string();
array->Resize(array->GetSize() + 1);
array->SetValue(array->GetSize() - 1, &s);
}
}
} catch (const std::exception& e) {
DEER_EDITOR_ENGINE_ERROR("Error in getResourceFiles(), {}", e.what());
}
return array;
}
} // namespace Deer } // namespace Deer

View File

@ -45,14 +45,6 @@ namespace cereal {
} // namespace cereal } // namespace cereal
namespace Deer { namespace Deer {
struct FolderInfo {
std::string name;
std::string parent;
std::string fullPath;
std::vector<uint32_t> resources;
std::vector<std::string> subfolders;
};
namespace StudioResources { namespace StudioResources {
std::vector<ResourceInformation> resources; std::vector<ResourceInformation> resources;
std::unordered_map<std::string, size_t> resourcePathToIndex; std::unordered_map<std::string, size_t> resourcePathToIndex;
@ -62,7 +54,7 @@ namespace Deer {
std::unordered_map<std::string, size_t> folderPathToFolderIndex; std::unordered_map<std::string, size_t> folderPathToFolderIndex;
void registerResource(ResourceInformation& resource, size_t index); void registerResource(ResourceInformation& resource, size_t index);
FolderInfo& getFolderInfo(std::string folderStr); FolderInfo& getCreateFolderInfo(std::string folderStr);
ResourceType getResourceType(const std::string& dir) { ResourceType getResourceType(const std::string& dir) {
Path path(dir); Path path(dir);
@ -84,6 +76,13 @@ namespace Deer {
}; };
} // namespace StudioResources } // namespace StudioResources
FolderInfo* StudioResources::getFolderInfoFromPath(std::string path) {
if (!folderPathToFolderIndex.contains(path))
return nullptr;
return &folders[folderPathToFolderIndex[path]];
}
ResourceInformation* StudioResources::getResourceInfoFromPath(const std::string& path) { ResourceInformation* StudioResources::getResourceInfoFromPath(const std::string& path) {
if (!resourcePathToIndex.contains(path)) if (!resourcePathToIndex.contains(path))
return nullptr; return nullptr;
@ -98,7 +97,7 @@ namespace Deer {
return &resources[resourceIdToIndex[resource]]; return &resources[resourceIdToIndex[resource]];
} }
FolderInfo& StudioResources::getFolderInfo(std::string folderStr) { FolderInfo& getCreateFolderInfo(std::string folderStr) {
FolderInfo* folderInfo; FolderInfo* folderInfo;
if (folderPathToFolderIndex.contains(folderStr)) { if (folderPathToFolderIndex.contains(folderStr)) {
size_t folderIndex = folderPathToFolderIndex[folderStr]; size_t folderIndex = folderPathToFolderIndex[folderStr];
@ -117,7 +116,7 @@ namespace Deer {
folderPathToFolderIndex[folderStr] = folders.size() - 1; folderPathToFolderIndex[folderStr] = folders.size() - 1;
if (!folderStr.empty()) { if (!folderStr.empty()) {
FolderInfo& parentPathInfo = getFolderInfo(folderInfo->parent); FolderInfo& parentPathInfo = getCreateFolderInfo(folderInfo->parent);
parentPathInfo.subfolders.push_back(folderStr); parentPathInfo.subfolders.push_back(folderStr);
} }
} }
@ -135,7 +134,7 @@ namespace Deer {
resourceIdToIndex[resource.resourceId] = index; resourceIdToIndex[resource.resourceId] = index;
resourcePathToIndex[resource.resourcePath] = index; resourcePathToIndex[resource.resourcePath] = index;
FolderInfo& folderInfo = getFolderInfo(resource.folderPath); FolderInfo& folderInfo = getCreateFolderInfo(resource.folderPath);
folderInfo.resources.push_back(resource.resourceId); folderInfo.resources.push_back(resource.resourceId);
} }