// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors. // All rights reserved. // Code licensed under the BSD License. // http://www.anki3d.org/LICENSE #pragma once #include #include #include #include namespace anki { // Forward class ConfigSet; class GrManager; class PhysicsWorld; class ResourceManager; class AsyncLoader; class ResourceManagerModel; class ShaderCompilerCache; class ShaderProgramResourceSystem; /// @addtogroup resource /// @{ /// Manage resources of a certain type template class TypeResourceManager { protected: TypeResourceManager() { } ~TypeResourceManager() { ANKI_ASSERT(m_ptrs.isEmpty() && "Forgot to delete some resources"); m_ptrs.destroy(m_alloc); } Type* findLoadedResource(const CString& filename) { auto it = find(filename); return (it != m_ptrs.end()) ? *it : nullptr; } void registerResource(Type* ptr) { ANKI_ASSERT(find(ptr->getFilename()) == m_ptrs.getEnd()); m_ptrs.pushBack(m_alloc, ptr); } void unregisterResource(Type* ptr) { auto it = find(ptr->getFilename()); ANKI_ASSERT(it != m_ptrs.end()); m_ptrs.erase(m_alloc, it); } void init(ResourceAllocator alloc) { m_alloc = alloc; } private: using Container = List; ResourceAllocator m_alloc; Container m_ptrs; typename Container::Iterator find(const CString& filename) { typename Container::Iterator it; for(it = m_ptrs.getBegin(); it != m_ptrs.getEnd(); ++it) { if((*it)->getFilename() == filename) { break; } } return it; } }; class ResourceManagerInitInfo { public: GrManager* m_gr = nullptr; PhysicsWorld* m_physics = nullptr; ResourceFilesystem* m_resourceFs = nullptr; const ConfigSet* m_config = nullptr; CString m_cacheDir; AllocAlignedCallback m_allocCallback = 0; void* m_allocCallbackData = nullptr; }; /// Resource manager. It holds a few global variables class ResourceManager: #define ANKI_INSTANTIATE_RESOURCE(rsrc_, ptr_) \ public \ TypeResourceManager #define ANKI_INSTANSIATE_RESOURCE_DELIMITER() , #include #undef ANKI_INSTANTIATE_RESOURCE #undef ANKI_INSTANSIATE_RESOURCE_DELIMITER { template friend class ResourcePtrDeleter; public: ResourceManager(); ~ResourceManager(); ANKI_USE_RESULT Error init(ResourceManagerInitInfo& init); /// Load a resource. template ANKI_USE_RESULT Error loadResource(const CString& filename, ResourcePtr& out, Bool async = true); // Internals: ANKI_INTERNAL U32 getMaxImageSize() const { return m_maxImageSize; } ANKI_INTERNAL Bool getDumpShaderSource() const { return m_dumpShaderSource; } ANKI_INTERNAL ResourceAllocator& getAllocator() { return m_alloc; } ANKI_INTERNAL TempResourceAllocator& getTempAllocator() { return m_tmpAlloc; } ANKI_INTERNAL GrManager& getGrManager() { ANKI_ASSERT(m_gr); return *m_gr; } ANKI_INTERNAL TransferGpuAllocator& getTransferGpuAllocator() { return *m_transferGpuAlloc; } ANKI_INTERNAL PhysicsWorld& getPhysicsWorld() { ANKI_ASSERT(m_physics); return *m_physics; } ANKI_INTERNAL ResourceFilesystem& getFilesystem() { ANKI_ASSERT(m_fs); return *m_fs; } ANKI_INTERNAL const String& getCacheDirectory() const { return m_cacheDir; } template ANKI_INTERNAL T* findLoadedResource(const CString& filename) { return TypeResourceManager::findLoadedResource(filename); } template ANKI_INTERNAL void registerResource(T* ptr) { TypeResourceManager::registerResource(ptr); } template ANKI_INTERNAL void unregisterResource(T* ptr) { TypeResourceManager::unregisterResource(ptr); } ANKI_INTERNAL AsyncLoader& getAsyncLoader() { return *m_asyncLoader; } /// Get the number of times loadResource() was called. ANKI_INTERNAL U64 getLoadingRequestCount() const { return m_loadRequestCount; } /// Get the total number of completed async tasks. ANKI_INTERNAL U64 getAsyncTaskCompletedCount() const; /// Return the container of program libraries. const ShaderProgramResourceSystem& getShaderProgramResourceSystem() const { return *m_shaderProgramSystem; } private: GrManager* m_gr = nullptr; PhysicsWorld* m_physics = nullptr; ResourceFilesystem* m_fs = nullptr; ResourceAllocator m_alloc; TempResourceAllocator m_tmpAlloc; String m_cacheDir; U32 m_maxImageSize; AsyncLoader* m_asyncLoader = nullptr; ///< Async loading thread ShaderProgramResourceSystem* m_shaderProgramSystem = nullptr; U64 m_uuid = 0; U64 m_loadRequestCount = 0; TransferGpuAllocator* m_transferGpuAlloc = nullptr; Bool m_dumpShaderSource = false; }; /// @} } // end namespace anki