#ifndef DMSDK_RESOURCE_H
#define DMSDK_RESOURCE_H
#include <stdint.h>
#include <dmsdk/dlib/align.h>
#include <dmsdk/dlib/hash.h>
#include <dmsdk/dlib/hashtable.h>
namespace dmResource
{
typedef struct SResourceFactory* HFactory;
typedef struct ResourcePreloader* HPreloader;
typedef struct PreloadHintInfo* HPreloadHintInfo;
typedef struct SResourceDescriptor* HResourceDescriptor;
enum Result
{
RESULT_OK = 0,
RESULT_INVALID_DATA = -1,
RESULT_DDF_ERROR = -2,
RESULT_RESOURCE_NOT_FOUND = -3,
RESULT_MISSING_FILE_EXTENSION = -4,
RESULT_ALREADY_REGISTERED = -5,
RESULT_INVAL = -6,
RESULT_UNKNOWN_RESOURCE_TYPE = -7,
RESULT_OUT_OF_MEMORY = -8,
RESULT_IO_ERROR = -9,
RESULT_NOT_LOADED = -10,
RESULT_OUT_OF_RESOURCES = -11,
RESULT_STREAMBUFFER_TOO_SMALL = -12,
RESULT_FORMAT_ERROR = -13,
RESULT_CONSTANT_ERROR = -14,
RESULT_NOT_SUPPORTED = -15,
RESULT_RESOURCE_LOOP_ERROR = -16,
RESULT_PENDING = -17,
RESULT_INVALID_FILE_EXTENSION = -18,
RESULT_VERSION_MISMATCH = -19,
RESULT_SIGNATURE_MISMATCH = -20,
RESULT_UNKNOWN_ERROR = -21,
};
struct ResourcePreloadParams
{
HFactory m_Factory;
void* m_Context;
const char* m_Filename;
const void* m_Buffer;
uint32_t m_BufferSize;
HPreloadHintInfo m_HintInfo;
void** m_PreloadData;
};
struct SResourceDescriptor
{
uint64_t m_NameHash;
void* m_Resource;
void* m_PrevResource;
uint32_t m_ResourceSize;
uint32_t m_ResourceSizeOnDisc;
void* m_ResourceType;
uint32_t m_ReferenceCount;
};
typedef Result (*FResourcePreload)(const ResourcePreloadParams& params);
struct ResourceCreateParams
{
HFactory m_Factory;
void* m_Context;
const char* m_Filename;
const void* m_Buffer;
uint32_t m_BufferSize;
void* m_PreloadData;
HResourceDescriptor m_Resource;
};
typedef Result (*FResourceCreate)(const ResourceCreateParams& params);
struct ResourcePostCreateParams
{
HFactory m_Factory;
void* m_Context;
void* m_PreloadData;
HResourceDescriptor m_Resource;
};
typedef Result (*FResourcePostCreate)(const ResourcePostCreateParams& params);
struct ResourceDestroyParams
{
HFactory m_Factory;
void* m_Context;
HResourceDescriptor m_Resource;
};
typedef Result (*FResourceDestroy)(const ResourceDestroyParams& params);
struct ResourceRecreateParams
{
HFactory m_Factory;
void* m_Context;
uint64_t m_NameHash;
const char* m_Filename;
const void* m_Buffer;
uint32_t m_BufferSize;
const void* m_Message;
HResourceDescriptor m_Resource;
};
typedef Result (*FResourceRecreate)(const ResourceRecreateParams& params);
Result RegisterType(HFactory factory,
const char* extension,
void* context,
FResourcePreload preload_function,
FResourceCreate create_function,
FResourcePostCreate post_create_function,
FResourceDestroy destroy_function,
FResourceRecreate recreate_function);
struct ResourceReloadedParams
{
void* m_UserData;
HResourceDescriptor m_Resource;
const char* m_Name;
uint64_t m_NameHash;
};
typedef void (*ResourceReloadedCallback)(const ResourceReloadedParams& params);
void RegisterResourceReloadedCallback(HFactory factory, ResourceReloadedCallback callback, void* user_data);
void UnregisterResourceReloadedCallback(HFactory factory, ResourceReloadedCallback callback, void* user_data);
dmhash_t GetNameHash(HResourceDescriptor desc);
void* GetResource(HResourceDescriptor desc);
void* GetPreviousResource(HResourceDescriptor desc);
void SetResource(HResourceDescriptor desc, void* resource);
void SetResourceSize(HResourceDescriptor desc, uint32_t size);
struct ResourceTypeRegisterContext
{
HFactory m_Factory;
const char* m_Name; uint64_t m_NameHash;
dmHashTable64<void*>* m_Contexts;
};
typedef Result (*FResourceTypeRegister)(ResourceTypeRegisterContext& ctx);
typedef Result (*FResourceTypeDeregister)(ResourceTypeRegisterContext& ctx);
const size_t s_ResourceTypeCreatorDescBufferSize = 128;
struct TypeCreatorDesc;
void RegisterTypeCreatorDesc(TypeCreatorDesc* desc, uint32_t size, const char *name, FResourceTypeRegister register_fn, FResourceTypeDeregister deregister_fn);
#define DM_RESOURCE_PASTE_SYMREG(x, y) x ## y
#define DM_RESOURCE_PASTE_SYMREG2(x, y) DM_RESOURCE_PASTE_SYMREG(x, y)
#ifdef __GNUC__
#define DM_REGISTER_RESOURCE_TYPE(symbol, desc, desc_size, suffix, register_fn, deregister_fn) extern "C" void __attribute__((constructor)) symbol () { \
dmResource::RegisterTypeCreatorDesc((struct dmResource::TypeCreatorDesc*) &desc, desc_size, suffix, register_fn, deregister_fn); \
}
#else
#define DM_REGISTER_RESOURCE_TYPE(symbol, desc, desc_size, suffix, register_fn, deregister_fn) extern "C" void symbol () { \
dmResource::RegisterTypeCreatorDesc((struct dmResource::TypeCreatorDesc*) &desc, desc_size, suffix, register_fn, deregister_fn); \
}\
int symbol ## Wrapper(void) { symbol(); return 0; } \
__pragma(section(".CRT$XCU",read)) \
__declspec(allocate(".CRT$XCU")) int (* _Fp ## symbol)(void) = symbol ## Wrapper;
#endif
#define DM_DECLARE_RESOURCE_TYPE(symbol, suffix, register_fn, deregister_fn) \
uint8_t DM_ALIGNED(16) DM_RESOURCE_PASTE_SYMREG2(symbol, __LINE__)[dmResource::s_ResourceTypeCreatorDescBufferSize]; \
DM_REGISTER_RESOURCE_TYPE(symbol, DM_RESOURCE_PASTE_SYMREG2(symbol, __LINE__), sizeof(DM_RESOURCE_PASTE_SYMREG2(symbol, __LINE__)), suffix, register_fn, deregister_fn);
Result Get(HFactory factory, const char* name, void** resource);
void Release(HFactory factory, void* resource);
bool PreloadHint(HPreloadHintInfo preloader, const char *name);
Result GetPath(HFactory factory, const void* resource, uint64_t* hash);
}
#endif