Compare commits

..

No commits in common. "0b1dcb5e55ad883c7b6b5af93a3fbc7a0ceadd6b" and "b72fb412a7136ebffd6a31cd0b8919b759cbe7d0" have entirely different histories.

14 changed files with 132 additions and 78 deletions

View File

@ -3,8 +3,8 @@
#ifdef DEER_RENDER #ifdef DEER_RENDER
#include "DeerRender/Mesh.h" #include "DeerRender/Mesh.h"
#include "DeerRender/Resource.h"
#include "DeerRender/Shader.h" #include "DeerRender/Shader.h"
#include "DeerRender/Resource.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>(ResourceId)> meshLoadingFunction = nullptr; std::function<Resource<GPUMesh>(StorageType)> meshLoadingFunction = nullptr;
std::function<Resource<Shader>(ResourceId)> shaderLoadingFunction = nullptr; std::function<Resource<Shader>(StorageType)> 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 ResourceId; typedef uint32_t StorageType;
ResourceId generatePhyisicalStorageId(); StorageType generatePhyisicalStorageId();
ResourceId generateRuntimeStorageId(); StorageType generateRuntimeStorageId();
template <typename DataSource> template <typename DataSource>
class StorageBackend { class StorageBackend {
public: public:
template <typename T> template <typename T>
static Scope<T> load(ResourceId storageId); static Scope<T> load(StorageType 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; }
ResourceId getStorageId() const { return ResourceManager<T>::getStorageId(*this); } StorageType 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;
ResourceId storageId = 0; StorageType storageId = 0;
}; };
static std::vector<ResourceData> resources; static std::vector<ResourceData> resources;
static std::unordered_map<ResourceId, Resource<T>> resourceCache; static std::unordered_map<StorageType, Resource<T>> resourceCache;
public: public:
template <typename DataSource> template <typename DataSource>
static Resource<T> loadResource(ResourceId storageId) { static Resource<T> loadResource(StorageType 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(ResourceId storageId) { static Resource<T> getResource(StorageType 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, ResourceId storageId) { static Resource<T> loadResourceFromData(const typename ResourceBuilder<T>::BaseDataType& resourceData, StorageType 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 ResourceId getStorageId(Resource<T> res) { static inline StorageType 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<ResourceId, Resource<T>> ResourceManager<T>::resourceCache; std::unordered_map<StorageType, 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 {
ResourceId generatePhyisicalStorageId() { StorageType generatePhyisicalStorageId() {
return std::random_device{}() | 0x80000000; return std::random_device{}() | 0x80000000;
} }
ResourceId generateRuntimeStorageId() { StorageType generateRuntimeStorageId() {
return std::random_device{}() & 0x7FFFFFF; return std::random_device{}() & 0x7FFFFFF;
} }
} // namespace Deer } // namespace Deer

View File

@ -29,10 +29,6 @@ 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,6 +13,16 @@ 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,
@ -23,7 +33,6 @@ 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(ResourceId), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<ResourceId>())); AS_CHECK(scriptEngine->RegisterObjectType("StorageId", sizeof(StorageType), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<StorageType>()));
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,10 +36,8 @@ 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_heighqt() const property", frameBuffer_getHeight); REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "int get_height() 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,15 +19,21 @@ namespace Deer {
template <class Archive> template <class Archive>
void load(Archive& archive) { void load(Archive& archive) {
ResourceId storageId_mesh; StorageType storageId_mesh;
ResourceId storageId_shader; StorageType 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));
component.mesh = settings.meshLoadingFunction(storageId_mesh); Scope<MeshData> meshData = settings.meshLoadingFunction(storageId_mesh);
component.shader = settings.shaderLoadingFunction(storageId_shader); Scope<ShaderData> shaderData = 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,9 +21,15 @@ 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&);
std::string resourceId_getName(ResourceId&); Resource<Texture>
std::string resourceId_getPath(ResourceId&); getIcon(std::string&);
int32_t resourceId_getFolder(ResourceId&);
ResourceType resourceId_getType(ResourceId&); CScriptArray* getResourceFolders(std::string& path);
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,6 +3,7 @@
#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 {
@ -40,33 +41,25 @@ 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(ResourceId storageId); static Scope<T> load(StorageType storageId);
template <> template <>
Scope<MeshData> load(ResourceId storageId); Scope<MeshData> load(StorageType storageId);
template <> template <>
Scope<ShaderData> load(ResourceId storageId); Scope<ShaderData> load(StorageType storageId);
template <> template <>
Scope<TextureData> load(ResourceId storageId); Scope<TextureData> load(StorageType 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(ResourceId storageId) { Scope<MeshData> StorageBackend<EditorDataSource>::load(StorageType 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(ResourceId storageId) { Scope<ShaderData> StorageBackend<EditorDataSource>::load(StorageType 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(ResourceId storageId) { Scope<TextureData> StorageBackend<EditorDataSource>::load(StorageType storageId) {
ResourceInformation* info = StudioResources::getResourceInfoFromId(storageId); ResourceInformation* info = StudioResources::getResourceInfoFromId(storageId);
if (!info) if (!info)
return Scope<TextureData>(); return Scope<TextureData>();

View File

@ -10,20 +10,65 @@
#include "scriptdictionary.h" #include "scriptdictionary.h"
namespace Deer { namespace Deer {
int32_t StudioAPI::getResourceFolder(std::string& path) { ResourceType StudioAPI::getResourceType(std::string& dir) {
} Path path(dir);
bool StudioAPI::resourceFolder_isValid(int32_t&); std::string extension = path.extension().string();
bool StudioAPI::resourceFolder_isRoot(int32_t&);
std::string StudioAPI::resourceFolder_getName(int32_t&); if (extension == ".obj" || extension == ".fbx" || extension == ".dae" ||
std::string StudioAPI::resourceFolder_getFullPath(int32_t&); extension == ".3ds" || extension == ".ply" || extension == ".stl" ||
int32_t StudioAPI::resourceFolder_getParentFolder(int32_t&); extension == ".glb" || extension == ".gltf") {
int32_t StudioAPI::resourceFolder_getSubFolderCount(int32_t&); return ResourceType::MESH;
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")
return ResourceType::SHADER;
if (extension == ".png")
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;
}
std::string StudioAPI::resourceId_getName(ResourceId&);
std::string StudioAPI::resourceId_getPath(ResourceId&);
int32_t StudioAPI::resourceId_getFolder(ResourceId&);
ResourceType StudioAPI::resourceId_getType(ResourceId&);
} // namespace Deer } // namespace Deer

View File

@ -45,6 +45,14 @@ 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;
@ -54,7 +62,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& getCreateFolderInfo(std::string folderStr); FolderInfo& getFolderInfo(std::string folderStr);
ResourceType getResourceType(const std::string& dir) { ResourceType getResourceType(const std::string& dir) {
Path path(dir); Path path(dir);
@ -76,13 +84,6 @@ 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;
@ -97,7 +98,7 @@ namespace Deer {
return &resources[resourceIdToIndex[resource]]; return &resources[resourceIdToIndex[resource]];
} }
FolderInfo& getCreateFolderInfo(std::string folderStr) { FolderInfo& StudioResources::getFolderInfo(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];
@ -116,7 +117,7 @@ namespace Deer {
folderPathToFolderIndex[folderStr] = folders.size() - 1; folderPathToFolderIndex[folderStr] = folders.size() - 1;
if (!folderStr.empty()) { if (!folderStr.empty()) {
FolderInfo& parentPathInfo = getCreateFolderInfo(folderInfo->parent); FolderInfo& parentPathInfo = getFolderInfo(folderInfo->parent);
parentPathInfo.subfolders.push_back(folderStr); parentPathInfo.subfolders.push_back(folderStr);
} }
} }
@ -134,7 +135,7 @@ namespace Deer {
resourceIdToIndex[resource.resourceId] = index; resourceIdToIndex[resource.resourceId] = index;
resourcePathToIndex[resource.resourcePath] = index; resourcePathToIndex[resource.resourcePath] = index;
FolderInfo& folderInfo = getCreateFolderInfo(resource.folderPath); FolderInfo& folderInfo = getFolderInfo(resource.folderPath);
folderInfo.resources.push_back(resource.resourceId); folderInfo.resources.push_back(resource.resourceId);
} }