diff --git a/Code/Misc/Misc.vcxproj b/Code/Misc/Misc.vcxproj index 3adbb7c8..743cea70 100644 --- a/Code/Misc/Misc.vcxproj +++ b/Code/Misc/Misc.vcxproj @@ -146,14 +146,15 @@ - + + + - diff --git a/Code/Misc/Misc.vcxproj.filters b/Code/Misc/Misc.vcxproj.filters index 03a248f4..f3ea3d1f 100644 --- a/Code/Misc/Misc.vcxproj.filters +++ b/Code/Misc/Misc.vcxproj.filters @@ -21,15 +21,21 @@ Source Files - - Source Files - Source Files Source Files + + Source Files + + + Source Files + + + Source Files + @@ -47,8 +53,5 @@ Header Files - - Header Files - \ No newline at end of file diff --git a/Code/Misc/Resource/Loaders/Textloader.cpp b/Code/Misc/Resource/Loaders/ByteLoader.cpp similarity index 87% rename from Code/Misc/Resource/Loaders/Textloader.cpp rename to Code/Misc/Resource/Loaders/ByteLoader.cpp index b42891cc..86a571ca 100644 --- a/Code/Misc/Resource/Loaders/Textloader.cpp +++ b/Code/Misc/Resource/Loaders/ByteLoader.cpp @@ -103,16 +103,15 @@ bool ReadFromFile(const wchar_t fileName[], const char openFlag[], std::string& } -OResource* OResource::ByteLoader(const wchar_t filename[], ResourceType type) +OResource* OResource::ByteLoader(const wchar_t filename[], ResourceType type, OResource* old) { - OResource *resource = 0; + OResource *resource = old; std::wstring wOut; std::string sOut; bool success = false; switch (type) { - case Oyster::Resource::ResourceType_UNKNOWN: case Oyster::Resource::ResourceType_Byte_Raw: success = ReadFromFile(filename, "rb", sOut, sizeof(char)); break; @@ -147,10 +146,28 @@ OResource* OResource::ByteLoader(const wchar_t filename[], ResourceType type) char *data = new char[sOut.size()+1]; data[sOut.size()] = '\0'; memcpy(&data[0], &sOut[0], sOut.size()); - resource = new OResource((OHRESOURCE)data, type, (sizeof(char) * sOut.size()), sizeof(char), filename); - + + if(!old) + { + resource = new OResource((OHRESOURCE)data, type, (sizeof(char) * sOut.size()), sizeof(char), filename); + } + else + { + old->resourceData = (OHRESOURCE)data; + } } return resource; } +void OResource::ByteUnloader() +{ + delete [] ((char*)this->resourceData); + this->resourceData = 0; +} + +OResource* OResource::ByteReloader() +{ + ByteUnloader(); + return ByteLoader(this->resourceFilename.c_str(), this->resourceType, this); +} diff --git a/Code/Misc/Resource/Loaders/CustomLoader.cpp b/Code/Misc/Resource/Loaders/CustomLoader.cpp new file mode 100644 index 00000000..84cb9302 --- /dev/null +++ b/Code/Misc/Resource/Loaders/CustomLoader.cpp @@ -0,0 +1,42 @@ + +#include "..\OResource.h" +#include "..\..\Utilities.h" + +#include + +using namespace Oyster::Resource; + + +OResource* OResource::CustomLoader(const wchar_t filename[], CustomLoadFunction fnc) +{ + const CustomData &data = fnc(); + + if(!data.loadedData) return 0; + if(!data.resourceUnloadFnc) return 0; + + OResource *resource = new OResource((OHRESOURCE)data.loadedData, ResourceType_UNKNOWN, 0, 0, filename); + + resource->customData = new CustomResourceData(); + resource->customData->unloadingFunction = data.resourceUnloadFnc; + resource->resourceData = (OHRESOURCE)data.loadedData; + resource->customData->loadingFunction = fnc; + + return resource; +} +void OResource::CustomUnloader() +{ + this->customData->unloadingFunction((void*)this->resourceData); +} +OResource* OResource::CustomReloader() +{ + CustomUnloader(); + + const CustomData &data = this->customData->loadingFunction(); + this->resourceData = (OHRESOURCE)data.loadedData; + + if(data.resourceUnloadFnc) + this->customData->unloadingFunction = data.resourceUnloadFnc; + + return this; +} + diff --git a/Code/Misc/Resource/OResource.cpp b/Code/Misc/Resource/OResource.cpp index 9bd9e83b..af0bc14a 100644 --- a/Code/Misc/Resource/OResource.cpp +++ b/Code/Misc/Resource/OResource.cpp @@ -8,57 +8,75 @@ OResource::OResource(OHRESOURCE handle, ResourceType type, size_t resourceSize, , resourceSize (resourceSize) , resourceElementSize (elementSize) , resourceType (type) + , customData (0) { } OResource::~OResource() {} -bool OResource::Release() + +OResource* OResource::Load (const wchar_t filename[], ResourceType type) { - if(this->resourceRef.Decref() == 0) + switch (type) { - Remove(this->resourceType, this->resourceData); - return true; - } - return false; -} - -void OResource::Remove(ResourceType t, OHRESOURCE& r) -{ - switch (t) - { - case Oyster::Resource::ResourceType_Texture_PNG: - case Oyster::Resource::ResourceType_Texture_DDS: - case Oyster::Resource::ResourceType_Texture_JPG: - - break; - - case Oyster::Resource::ResourceType_Mesh_VertexData: - case Oyster::Resource::ResourceType_Mesh_AnimationData: - - break; - - case Oyster::Resource::ResourceType_Audio_mp3: - - break; - - case Oyster::Resource::ResourceType_Shader_Vertex: - case Oyster::Resource::ResourceType_Shader_Hull: - case Oyster::Resource::ResourceType_Shader_Domain: - case Oyster::Resource::ResourceType_Shader_Geometry: - case Oyster::Resource::ResourceType_Shader_Pixel: - case Oyster::Resource::ResourceType_Shader_Compute: - - break; - - case Oyster::Resource::ResourceType_UNKNOWN: case Oyster::Resource::ResourceType_Byte_Raw: case Oyster::Resource::ResourceType_Byte_ANSI: case Oyster::Resource::ResourceType_Byte_UTF8: case Oyster::Resource::ResourceType_Byte_UNICODE: case Oyster::Resource::ResourceType_Byte_UTF16LE: - delete ((char*)r); + return OResource::ByteLoader(filename, type); break; } -} \ No newline at end of file + + return 0; +} +OResource* OResource::Load (const wchar_t filename[], CustomLoadFunction loadFnc) +{ + return OResource::CustomLoader(filename, loadFnc); +} +OResource* OResource::Reload (OResource* resource) +{ + if(!resource) return 0; + + switch (resource->resourceType) + { + case Oyster::Resource::ResourceType_Byte_Raw: + case Oyster::Resource::ResourceType_Byte_ANSI: + case Oyster::Resource::ResourceType_Byte_UTF8: + case Oyster::Resource::ResourceType_Byte_UNICODE: + case Oyster::Resource::ResourceType_Byte_UTF16LE: + resource->ByteReloader(); + break; + + case Oyster::Resource::ResourceType_UNKNOWN: + resource->CustomReloader(); + break; + } + + return resource; +} +bool OResource::Release (OResource* resource) +{ + if(resource->resourceRef.Decref() == 0) + { + switch (resource->resourceType) + { + case Oyster::Resource::ResourceType_Byte_Raw: + case Oyster::Resource::ResourceType_Byte_ANSI: + case Oyster::Resource::ResourceType_Byte_UTF8: + case Oyster::Resource::ResourceType_Byte_UNICODE: + case Oyster::Resource::ResourceType_Byte_UTF16LE: + resource->ByteUnloader(); + break; + + case Oyster::Resource::ResourceType_UNKNOWN: + resource->CustomUnloader(); + break; + } + return true; + } + return false; +} + + diff --git a/Code/Misc/Resource/OResource.h b/Code/Misc/Resource/OResource.h index e9af19b0..221fb3ad 100644 --- a/Code/Misc/Resource/OResource.h +++ b/Code/Misc/Resource/OResource.h @@ -15,10 +15,16 @@ namespace Oyster { class OResource { + public: + struct CustomResourceData + { + CustomLoadFunction loadingFunction; + CustomUnloadFunction unloadingFunction; + }; + public: OResource(OHRESOURCE handle, ResourceType type, size_t size, size_t elementSize, ::std::wstring resourceFilename); virtual~ OResource(); - bool Release(); inline ResourceType GetResourceType() const { return this->resourceType; } @@ -36,23 +42,30 @@ namespace Oyster { this->resourceID = id; } public: - static OResource* TextureLoader (const wchar_t filename[], ResourceType type) {return 0;} - static OResource* MeshLoader (const wchar_t filename[], ResourceType type) {return 0;}; - static OResource* AudioLoader (const wchar_t filename[], ResourceType type) {return 0;}; - static OResource* ShaderLoader (const wchar_t filename[], ResourceType type) {return 0;}; - static OResource* ByteLoader (const wchar_t filename[], ResourceType type); + static OResource* Load (const wchar_t filename[], ResourceType type); + static OResource* Load (const wchar_t filename[], CustomLoadFunction loadFnc); + static OResource* Reload (OResource* resource); + static bool Release (OResource* resource); Utility::DynamicMemory::RefCount resourceRef; private: - static void Remove (ResourceType t, OHRESOURCE& r); + static OResource* ByteLoader (const wchar_t filename[], ResourceType type, OResource* old = 0); + void ByteUnloader (); + OResource* ByteReloader (); - OHRESOURCE resourceData; - ResourceType resourceType; - size_t resourceSize; - size_t resourceElementSize; - ::std::wstring resourceFilename; - unsigned int resourceID; + static OResource* CustomLoader (const wchar_t filename[], CustomLoadFunction loadFnc); + void CustomUnloader (); + OResource* CustomReloader (); + + OHRESOURCE resourceData; + ResourceType resourceType; + size_t resourceSize; + size_t resourceElementSize; + ::std::wstring resourceFilename; + unsigned int resourceID; + + CustomResourceData *customData; }; } } diff --git a/Code/Misc/Resource/OResourceHandler.cpp b/Code/Misc/Resource/OResourceHandler.cpp index 3db14dfb..a6fcffbc 100644 --- a/Code/Misc/Resource/OResourceHandler.cpp +++ b/Code/Misc/Resource/OResourceHandler.cpp @@ -23,18 +23,72 @@ public: } resourcePrivate; -void IResourceHandler::Release() +OHRESOURCE OysterResource::LoadResource(const wchar_t* filename, ResourceType type) { - IResourceHandler::Clean(); + if(!filename) return 0; + + OResource *resourceData = resourcePrivate.FindResource(filename); + if(resourceData) + { + //Add new reference + resourcePrivate.SaveResource(resourceData, false); + return resourceData->GetResourceHandle(); + } + + resourceData = OResource::Load(filename, type); + + if(!resourceData) return 0; + + resourcePrivate.SaveResource(resourceData); + + return resourceData->GetResourceHandle(); } -void IResourceHandler::Clean() +OHRESOURCE OysterResource::LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc, unsigned int CustomId) +{ + if(!filename) return 0; + if(!loadFnc) return 0; + + OResource *resourceData = resourcePrivate.FindResource(filename); + if(resourceData) + { + //Add new reference + resourcePrivate.SaveResource(resourceData, false); + return resourceData->GetResourceHandle(); + } + + resourceData = OResource::Load(filename, loadFnc); + + if(!resourceData) return 0; + + if(resourceData) resourceData->SetResourceID(CustomId); + resourcePrivate.SaveResource(resourceData); + + return (OHRESOURCE)resourceData->GetResourceHandle(); +} + +OHRESOURCE ReloadResource(const wchar_t filename[]) +{ + OResource *resourceData = resourcePrivate.FindResource(filename); + if(!resourceData) return 0; //The resource has not been loaded + + return OResource::Reload(resourceData)->GetResourceHandle(); +} +OHRESOURCE ReloadResource(OHRESOURCE resource) +{ + OResource *resourceData = resourcePrivate.FindResource(resource); + if(!resourceData) return 0; //The resource has not been loaded + + return OResource::Reload(resourceData)->GetResourceHandle(); +} + +void OysterResource::Clean() { auto i = resourcePrivate.resources.begin(); auto last = resourcePrivate.resources.end(); for (i; i != last; i++) { - if(i->second->Release()) + if(OResource::Release(i->second)) { const wchar_t* temp = i->second->GetResourceFilename(); delete resourcePrivate.resources[temp]; @@ -42,67 +96,12 @@ void IResourceHandler::Clean() } } } -OHRESOURCE IResourceHandler::LoadResource(const wchar_t* filename, ResourceType type, bool force) -{ - OResource *resourceData = resourcePrivate.FindResource(filename); - if(resourceData) - { - resourcePrivate.SaveResource(resourceData, false); - return resourceData->GetResourceHandle(); - } - - switch (type) - { - case Oyster::Resource::ResourceType_Texture_PNG: - case Oyster::Resource::ResourceType_Texture_DDS: - case Oyster::Resource::ResourceType_Texture_JPG: - resourceData = OResource::TextureLoader(filename, type); - break; - - case Oyster::Resource::ResourceType_Mesh_VertexData: - case Oyster::Resource::ResourceType_Mesh_AnimationData: - resourceData = OResource::MeshLoader(filename, type); - break; - - case Oyster::Resource::ResourceType_Audio_mp3: - resourceData = OResource::AudioLoader(filename, type); - break; - - case Oyster::Resource::ResourceType_Shader_Vertex: - case Oyster::Resource::ResourceType_Shader_Hull: - case Oyster::Resource::ResourceType_Shader_Domain: - case Oyster::Resource::ResourceType_Shader_Geometry: - case Oyster::Resource::ResourceType_Shader_Pixel: - case Oyster::Resource::ResourceType_Shader_Compute: - resourceData = OResource::ShaderLoader(filename, type); - break; - - case Oyster::Resource::ResourceType_UNKNOWN: - case Oyster::Resource::ResourceType_Byte_Raw: - case Oyster::Resource::ResourceType_Byte_ANSI: - case Oyster::Resource::ResourceType_Byte_UTF8: - case Oyster::Resource::ResourceType_Byte_UNICODE: - case Oyster::Resource::ResourceType_Byte_UTF16LE: - resourceData = OResource::ByteLoader(filename, type); - break; - - default: - //The format is not supported. - printf("(%i) is not a resourceData type or it is currently not supported!", type); - break; - } - - //Resource exists! It's a miracle =D. - resourcePrivate.SaveResource(resourceData); - - return resourceData->GetResourceHandle(); -} -void IResourceHandler::ReleaseResource(const OHRESOURCE& resourceData) +void OysterResource::ReleaseResource(const OHRESOURCE& resourceData) { OResource* t = resourcePrivate.FindResource(resourceData); if(t) { - if(t->Release()) + if(OResource::Release(t)) { const wchar_t* temp = t->GetResourceFilename(); delete resourcePrivate.resources[temp]; @@ -110,13 +109,14 @@ void IResourceHandler::ReleaseResource(const OHRESOURCE& resourceData) } } } -void IResourceHandler::SetResourceId (const OHRESOURCE& resourceData, unsigned int id) + +void OysterResource::SetResourceId (const OHRESOURCE& resourceData, unsigned int id) { OResource* t = resourcePrivate.FindResource(resourceData); if(t) t->SetResourceID(id); } -ResourceType IResourceHandler::GetResourceType (const OHRESOURCE& resourceData) +ResourceType OysterResource::GetResourceType (const OHRESOURCE& resourceData) { OResource* t = resourcePrivate.FindResource(resourceData); @@ -124,7 +124,7 @@ ResourceType IResourceHandler::GetResourceType (const OHRESOURCE& resourceData) return ResourceType_UNKNOWN; } -const wchar_t* IResourceHandler::GetResourceFilename (const OHRESOURCE& resourceData) +const wchar_t* OysterResource::GetResourceFilename (const OHRESOURCE& resourceData) { OResource* t = resourcePrivate.FindResource(resourceData); @@ -132,7 +132,7 @@ const wchar_t* IResourceHandler::GetResourceFilename (const OHRESOURCE& resource return 0; } -unsigned int IResourceHandler::GetResourceId (const OHRESOURCE& resourceData) +unsigned int OysterResource::GetResourceId (const OHRESOURCE& resourceData) { OResource* t = resourcePrivate.FindResource(resourceData); @@ -166,15 +166,12 @@ void ResourcePrivate::SaveResource( OResource* r, bool addNew ) { if(!r) return; - if(!addNew) - { - r->resourceRef.Incref(); - } - else + if(addNew) { this->resources[r->GetResourceFilename()] = r; - r->resourceRef.Incref(); } + + r->resourceRef.Incref(); } diff --git a/Code/Misc/Resource/OResourceHandler.h b/Code/Misc/Resource/OResourceHandler.h deleted file mode 100644 index 6f853571..00000000 --- a/Code/Misc/Resource/OResourceHandler.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef MISC_O_RESOURCE_HANLDER_H -#define MISC_O_RESOURCE_HANLDER_H - - -#include "OysterResource.h" - -#include - -///////////////////////////////////////////////////////////////////// -// Created by [Dennis Andersen] [2013] -///////////////////////////////////////////////////////////////////// - - - - -namespace Oyster -{ - namespace Resource - { - class OResourceHandler :public IResourceHandler - { - public: - OResourceHandler (); - virtual~ OResourceHandler (); - void Release () override; - void Clean () override; - OHRESOURCE LoadResource (const wchar_t filename[], ResourceType type, bool force) override; - void ReleaseResource (const OHRESOURCE& resource) override; - void SetResourceId (const OHRESOURCE& resource, unsigned int id) override; - ResourceType GetResourceType (const OHRESOURCE& resource) const override; - const wchar_t* GetResourceFilename (const OHRESOURCE& resource) const override; - unsigned int GetResourceId (const OHRESOURCE& resource) const override; - }; - } -} - -#endif \ No newline at end of file diff --git a/Code/Misc/Resource/OysterResource.h b/Code/Misc/Resource/OysterResource.h index 3dd54acb..3e449196 100644 --- a/Code/Misc/Resource/OysterResource.h +++ b/Code/Misc/Resource/OysterResource.h @@ -10,34 +10,15 @@ namespace Oyster { namespace Resource { + struct CustomData; /** A Resource handle representing various resources */ typedef unsigned long OHRESOURCE; + typedef void(*CustomUnloadFunction)(void*); + typedef const CustomData&(*CustomLoadFunction)(); /** An enum class representing all avalible resources that is supported. */ enum ResourceType { - //Texture - ResourceType_Texture_PNG, /**< Handle can be interpeted as ID3D11ShaderResourceView */ - ResourceType_Texture_DDS, /**< Handle can be interpeted as ID3D11ShaderResourceView */ - ResourceType_Texture_JPG, /**< Handle can be interpeted as ID3D11ShaderResourceView */ - - //Mesh - ResourceType_Mesh_AllInOne, /**< Handle can be interpeted as ? */ - ResourceType_Mesh_VertexData, /**< Handle can be interpeted as ? */ - ResourceType_Mesh_AnimationData, /**< Handle can be interpeted as ? */ - - //Audio - ResourceType_Audio_mp3, /**< Handle can be interpeted as ? */ - - //Shaders - ResourceType_Shader_Vertex, /**< Handle can be interpeted as ? */ - ResourceType_Shader_VertexBLOB, /**< Handle can be interpeted as ID3Blob */ - ResourceType_Shader_Hull, /**< Handle can be interpeted as ? */ - ResourceType_Shader_Domain, /**< Handle can be interpeted as ? */ - ResourceType_Shader_Geometry, /**< Handle can be interpeted as ? */ - ResourceType_Shader_Pixel, /**< Handle can be interpeted as ? */ - ResourceType_Shader_Compute, /**< Handle can be interpeted as ? */ - //Byte ResourceType_Byte_Raw, /**< Handle can be interpeted as char[] or char* */ ResourceType_Byte_ANSI, /**< Handle can be interpeted as char[] or char* */ @@ -46,22 +27,25 @@ namespace Oyster ResourceType_Byte_UTF16LE, /**< Handle can be interpeted as char[] or char* */ ResourceType_COUNT, /**< Handle can be interpeted as ? */ - ResourceType_UNKNOWN = -1 /**< Handle can be interpeted as char[] or char* */ + + ResourceType_UNKNOWN = -1, /**< Handle can be interpeted as void* */ + }; + + /** A struct to return when doing a custom resource Load + * By loading this way you are handing over the ownership to the resource loaded. + */ + struct CustomData + { + void* loadedData; ///count++; } - void Incref(int c) { this->count += c; } - int Decref() { return --this->count;} - void Reset() { this->count = 0; } + RefCount() :count(0) { } + RefCount(const RefCount& o) { count = o.count; } + const RefCount& operator=(const RefCount& o) { count = o.count; return *this;} + void Incref() { this->count++; } + void Incref(int c) { this->count += c; } + int Decref() { return --this->count;} + void Reset() { this->count = 0; } }; }