ソースを参照

Moved resource parsing to a dynamic ResourceLoader system. Added ability to provide custom resource loaders. Removed old addDirResource method, now resources are parsed using loadResourcesFromFolder method of ResourcePool

Ivan Safrin 10 年 前
コミット
d7af3ddc81

+ 3 - 2
build/osx/TemplateApp/TemplateApp/PolycodeTemplateApp.mm

@@ -9,8 +9,9 @@ PolycodeTemplateApp::PolycodeTemplateApp(PolycodeView *view) {
     core = new CocoaCore(view, 1280,720,false,false, 0,0,60);
     core = new CocoaCore(view, 1280,720,false,false, 0,0,60);
     
     
     core->addFileSource("archive", "default.pak");
     core->addFileSource("archive", "default.pak");
-	CoreServices::getInstance()->getResourceManager()->addDirResource("default");
-
+    ResourcePool *globalPool = Services()->getResourceManager()->getGlobalPool();
+    globalPool->loadResourcesFromFolder("default", true);
+    
 	// Write your code here!
 	// Write your code here!
     
     
     Scene *scene = new Scene(Scene::SCENE_2D);
     Scene *scene = new Scene(Scene::SCENE_2D);

+ 46 - 18
include/polycode/core/PolyResourceManager.h

@@ -33,6 +33,7 @@ namespace Polycode {
 	class Resource;
 	class Resource;
 	class PolycodeShaderModule;
 	class PolycodeShaderModule;
 	class String;
 	class String;
+    class ResourceLoader;
     
     
     class _PolyExport ResourcePool : public EventDispatcher {
     class _PolyExport ResourcePool : public EventDispatcher {
         public:
         public:
@@ -45,8 +46,9 @@ namespace Polycode {
 			void removeResource(Resource *resource);
 			void removeResource(Resource *resource);
             bool hasResource(Resource *resource);
             bool hasResource(Resource *resource);
         
         
-			Resource *getResource(int resourceType, const String& resourceName) const;
+            void loadResourcesFromFolder(const String &folder, bool recursive);
         
         
+			Resource *getResource(int resourceType, const String& resourceName) const;
             String getName();
             String getName();
             void setName(const String &name);
             void setName(const String &name);
         
         
@@ -67,13 +69,47 @@ namespace Polycode {
         
         
         private:
         private:
         
         
+            void loadResourcesFromFolderWithLoader(const String &folder, bool recursive, ResourceLoader *loader, const String &containingFolder);
+        
             ResourcePool *fallbackPool;
             ResourcePool *fallbackPool;
             String name;
             String name;
 			int ticksSinceCheck;
 			int ticksSinceCheck;
             std::vector <Resource*> resources;
             std::vector <Resource*> resources;
         
         
     };
     };
+    
+    class _PolyExport ResourceLoader {
+        public:
+            virtual ~ResourceLoader() {}
+            bool canHandleExtension(const String &extension);
+            virtual Resource *loadResource(const String &path, ResourcePool *targetPool) = 0;
+            std::vector<String> extensions;
+    };
+    
+    class _PolyExport TextureResourceLoader : public ResourceLoader {
+        public:
+            TextureResourceLoader();
+            Resource *loadResource(const String &path, ResourcePool *targetPool);
+    };
+    
+    class _PolyExport ProgramResourceLoader : public ResourceLoader {
+    public:
+        ProgramResourceLoader();
+        Resource *loadResource(const String &path, ResourcePool *targetPool);
+    };
 
 
+    class _PolyExport MaterialResourceLoader : public ResourceLoader {
+    public:
+            MaterialResourceLoader();
+            Resource *loadResource(const String &path, ResourcePool *targetPool);
+    };
+    
+    class _PolyExport FontResourceLoader : public ResourceLoader {
+    public:
+        FontResourceLoader();
+        Resource *loadResource(const String &path, ResourcePool *targetPool);
+    };
+    
 	/**
 	/**
 	* Manages loading and unloading of resources from directories and archives. Should only be accessed via the CoreServices singleton. 
 	* Manages loading and unloading of resources from directories and archives. Should only be accessed via the CoreServices singleton. 
 	*/ 
 	*/ 
@@ -81,26 +117,17 @@ namespace Polycode {
 		public:
 		public:
 			ResourceManager();
 			ResourceManager();
 			~ResourceManager();
 			~ResourceManager();
-			
-
-			/**
-			* Loads resources from a directory.
-			* @param dirPath Path to directory to load resources from.
-			* @param recursive If true, will recurse into subdirectories.
-			*/
-			void addDirResource(const String& dirPath, bool recursive=true);
-		
-			void parseTexturesIntoPool(ResourcePool *pool, const String& dirPath, bool recursive, const String& basePath);
-			void parseMaterialsIntoPool(ResourcePool *pool, const String& dirPath, bool recursive);
-			void parseShadersIntoPool(ResourcePool *pool, const String& dirPath, bool recursive);
-			void parseProgramsIntoPool(ResourcePool *pool, const String& dirPath, bool recursive);
-			void parseCubemapsIntoPool(ResourcePool *pool, const String& dirPath, bool recursive);
-            void parseOtherIntoPool(ResourcePool *pool, const String& dirPath, bool recursive);
-		
-            ResourcePool *getGlobalPool();
         
         
+            ResourcePool *getGlobalPool();
             ResourcePool *getResourcePoolByName(const String &name);
             ResourcePool *getResourcePoolByName(const String &name);
 		      
 		      
+            void addResourceLoader(ResourceLoader *loader);
+            ResourceLoader *getResourceLoaderForExtension(const String &extension);
+            void removeResourceLoader(ResourceLoader *loader);
+
+            unsigned int getNumResourceLoaders();
+            ResourceLoader *getResourceLoaderAtIndex(unsigned int index);
+        
             void addResourcePool(ResourcePool *pool);
             void addResourcePool(ResourcePool *pool);
             void removeResourcePool(ResourcePool *pool);
             void removeResourcePool(ResourcePool *pool);
         
         
@@ -116,6 +143,7 @@ namespace Polycode {
 		
 		
 		private:
 		private:
 		
 		
+            std::vector<ResourceLoader*> resourceLoaders;
             ResourcePool *globalPool;
             ResourcePool *globalPool;
             std::vector <ResourcePool*> pools;
             std::vector <ResourcePool*> pools;
 	};
 	};

BIN
lib/osx/libPolycore.a


+ 1 - 1
src/core/PolyMaterialManager.cpp

@@ -77,7 +77,7 @@ void MaterialManager::reloadPrograms() {
 }
 }
 
 
 void MaterialManager::loadMaterialLibraryIntoPool(ResourcePool *pool, const String &materialFile) {
 void MaterialManager::loadMaterialLibraryIntoPool(ResourcePool *pool, const String &materialFile) {
-    printf("LOADING [%s] into pool [%s]\n", materialFile.c_str(), pool->getName().c_str());
+    printf("LOADING MATERIAL [%s] into pool [%s]\n", materialFile.c_str(), pool->getName().c_str());
     std::vector<Shader*> shaders =loadShadersFromFile(pool, materialFile);
     std::vector<Shader*> shaders =loadShadersFromFile(pool, materialFile);
 
 
     for(int s=0; s < shaders.size(); s++) {
     for(int s=0; s < shaders.size(); s++) {

+ 121 - 131
src/core/PolyResourceManager.cpp

@@ -113,15 +113,65 @@ void ResourcePool::setFallbackPool(ResourcePool *pool) {
     fallbackPool = pool;
     fallbackPool = pool;
 }
 }
 
 
-void ResourceManager::addDirResource(const String& dirPath, bool recursive) {
-	parseTexturesIntoPool(globalPool, dirPath, recursive, "");
-	parseProgramsIntoPool(globalPool, dirPath, recursive);
-	parseShadersIntoPool(globalPool, dirPath, recursive);
-	parseCubemapsIntoPool(globalPool, dirPath, recursive);
-	parseMaterialsIntoPool(globalPool, dirPath, recursive);
-	parseOtherIntoPool(globalPool, dirPath, recursive);
+bool ResourceLoader::canHandleExtension(const String &extension) {
+    for(int i=0; i < extensions.size(); i++) {
+        if(extensions[i] == extension) {
+            return true;
+        }
+    }
+    return false;
+}
+
+TextureResourceLoader::TextureResourceLoader() {
+    extensions.push_back("png");
+    extensions.push_back("hdr");
+    extensions.push_back("jpg");
+    extensions.push_back("tga");
+    extensions.push_back("psd");
+}
+
+Resource *TextureResourceLoader::loadResource(const String &path,  ResourcePool *targetPool) {
+    MaterialManager *materialManager = Services()->getMaterialManager();
+    Texture *texture = materialManager->createTextureFromFile(path, materialManager->clampDefault, materialManager->mipmapsDefault);
+    return texture;
+}
+
+void ResourcePool::loadResourcesFromFolderWithLoader(const String &folder, bool recursive, ResourceLoader *loader, const String &containingFolder) {
+    vector<OSFileEntry> resourceDir;
+    
+    resourceDir = Services()->getCore()->parseFolder(folder, false);
+    
+    for(int i=0; i < resourceDir.size(); i++) {
+        if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
+            Resource *newResource = NULL;
+            if(loader->canHandleExtension(resourceDir[i].extension)) {
+                newResource = loader->loadResource(resourceDir[i].fullPath, this);
+            }
+            if(newResource) {
+                newResource->setResourceName(resourceDir[i].name);
+                newResource->setResourcePath(resourceDir[i].fullPath);
+                addResource(newResource);
+            }
+        } else {
+            if(recursive) {
+                loadResourcesFromFolderWithLoader(folder+"/"+resourceDir[i].name, true, loader, containingFolder);
+            }
+        }
+    }
 }
 }
 
 
+void ResourcePool::loadResourcesFromFolder(const String &folder, bool recursive) {
+    
+    // need to do separate passes for each loader so that different types of resources load
+    // after each other
+    
+    for(int r = 0; r < Services()->getResourceManager()->getNumResourceLoaders(); r++) {
+        ResourceLoader *loader = Services()->getResourceManager()->getResourceLoaderAtIndex(r);
+        loadResourcesFromFolderWithLoader(folder, recursive, loader, "");
+    }
+}
+
+
 Resource *ResourcePool::getResourceByPath(const String& resourcePath) const {
 Resource *ResourcePool::getResourceByPath(const String& resourcePath) const {
 	for(int i =0; i < resources.size(); i++) {
 	for(int i =0; i < resources.size(); i++) {
 		if(resources[i]->getResourcePath() == resourcePath) {
 		if(resources[i]->getResourcePath() == resourcePath) {
@@ -186,11 +236,20 @@ void ResourcePool::checkForChangedFiles() {
 
 
 ResourceManager::ResourceManager() : EventDispatcher() {
 ResourceManager::ResourceManager() : EventDispatcher() {
     globalPool = new ResourcePool("Global", NULL);
     globalPool = new ResourcePool("Global", NULL);
+    
+    resourceLoaders.push_back(new TextureResourceLoader());
+    resourceLoaders.push_back(new ProgramResourceLoader());
+    resourceLoaders.push_back(new MaterialResourceLoader());
+    resourceLoaders.push_back(new FontResourceLoader());
 }
 }
 
 
 ResourceManager::~ResourceManager() {
 ResourceManager::~ResourceManager() {
     printf("Shutting down resource manager...\n");
     printf("Shutting down resource manager...\n");
 
 
+    for(int i=0; i < resourceLoaders.size(); i++)	{
+        delete resourceLoaders[i];
+    }
+    
     for(int i=0; i < pools.size(); i++)	{
     for(int i=0; i < pools.size(); i++)	{
         delete pools[i];
         delete pools[i];
     }
     }
@@ -208,108 +267,71 @@ void ResourcePool::Update(int elapsed) {
 	}
 	}
 }
 }
 
 
-void ResourceManager::parseShadersIntoPool(ResourcePool *pool, const String& dirPath, bool recursive) {
-	vector<OSFileEntry> resourceDir;
-	resourceDir = Services()->getCore()->parseFolder(dirPath, false);
-	
-	for(int i=0; i < resourceDir.size(); i++) {	
-		if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
-			if(resourceDir[i].extension == "mat") {
-				MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();
-				std::vector<Shader*> shaders = materialManager->loadShadersFromFile(pool, resourceDir[i].fullPath);
-				
-				for(int s=0; s < shaders.size(); s++) {
-					pool->addResource(shaders[s]);
-					materialManager->addShader(shaders[s]);
-				}
-			}
-		} else {
-			if(recursive)
-				parseShadersIntoPool(pool, dirPath+"/"+resourceDir[i].name, true);
-		}
-	}
+void ResourceManager::addResourceLoader(ResourceLoader *loader) {
+    resourceLoaders.push_back(loader);
 }
 }
 
 
-void ResourceManager::parseOtherIntoPool(ResourcePool *pool, const String& dirPath, bool recursive) {
-    vector<OSFileEntry> resourceDir;
-    resourceDir = Services()->getCore()->parseFolder(dirPath, false);
-    for(int i=0; i < resourceDir.size(); i++) {
-        if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
-            if(resourceDir[i].extension == "ttf") {
-                Logger::log("Registering font: %s\n", resourceDir[i].nameWithoutExtension.c_str());
-                CoreServices::getInstance()->getFontManager()->registerFont(resourceDir[i].nameWithoutExtension, resourceDir[i].fullPath);
-            }
-        } else {
-            if(recursive)
-                parseOtherIntoPool(pool, dirPath+"/"+resourceDir[i].name, true);
+ResourceLoader *ResourceManager::getResourceLoaderForExtension(const String &extension) {
+    for(int i=0; i < resourceLoaders.size(); i++) {
+        if(resourceLoaders[i]->canHandleExtension(extension)) {
+            return resourceLoaders[i];
         }
         }
     }
     }
+    return NULL;
 }
 }
 
 
-void ResourceManager::parseProgramsIntoPool(ResourcePool *pool, const String& dirPath, bool recursive) {
-	vector<OSFileEntry> resourceDir;
-	resourceDir = Services()->getCore()->parseFolder(dirPath, false);
-	for(int i=0; i < resourceDir.size(); i++) {	
-		if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
-			MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();
-            
-            if(resourceDir[i].extension == "vert" || resourceDir[i].extension == "frag") {
-                ShaderProgram *newProgram = materialManager->createProgramFromFile(resourceDir[i].fullPath);
-                if(newProgram) {
-                    newProgram->setResourceName(resourceDir[i].name);
-                    newProgram->setResourcePath(resourceDir[i].fullPath);
-                    pool->addResource(newProgram);
-                }
-            }
-		} else {
-			if(recursive)
-				parseProgramsIntoPool(pool, dirPath+"/"+resourceDir[i].name, true);
-		}
-	}	
+void ResourceManager::removeResourceLoader(ResourceLoader *loader) {
+    for(int i=0; i < resourceLoaders.size(); i++) {
+        if(resourceLoaders[i] == loader) {
+            delete resourceLoaders[i];
+            resourceLoaders.erase(resourceLoaders.begin() + i);
+            return;
+        }
+    }
 }
 }
 
 
-void ResourceManager::parseMaterialsIntoPool(ResourcePool *pool, const String& dirPath, bool recursive) {
-	vector<OSFileEntry> resourceDir;
-	resourceDir = Services()->getCore()->parseFolder(dirPath, false);
-	
-	for(int i=0; i < resourceDir.size(); i++) {	
-		if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
-			if(resourceDir[i].extension == "mat") {				
-				MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();			
-				std::vector<Material*> materials = materialManager->loadMaterialsFromFile(pool, resourceDir[i].fullPath);
-
-				for(int m=0; m < materials.size(); m++) {
-					materials[m]->setResourceName(materials[m]->getName());
-					pool->addResource(materials[m]);
-					materialManager->addMaterial(materials[m]);
-				}
-			}
-		} else {
-			if(recursive)
-				parseMaterialsIntoPool(pool, dirPath+"/"+resourceDir[i].name, true);
-		}
-	}
+unsigned int ResourceManager::getNumResourceLoaders() {
+    return resourceLoaders.size();
 }
 }
 
 
-void ResourceManager::parseCubemapsIntoPool(ResourcePool *pool, const String& dirPath, bool recursive) {
-	vector<OSFileEntry> resourceDir;
-	resourceDir = Services()->getCore()->parseFolder(dirPath, false);
-	
-	for(int i=0; i < resourceDir.size(); i++) {	
-		if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
-			if(resourceDir[i].extension == "mat") {
-			
-				MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();			
-				std::vector<Cubemap*> cubemaps = materialManager->loadCubemapsFromFile(resourceDir[i].fullPath);			
-				for(int c=0; c < cubemaps.size(); c++) {
-					pool->addResource(cubemaps[c]);
-				}			
-			}
-		} else {
-			if(recursive)
-				parseCubemapsIntoPool(pool, dirPath+"/"+resourceDir[i].name, true);
-		}
-	}	
+ResourceLoader *ResourceManager::getResourceLoaderAtIndex(unsigned int index) {
+    if(index <= resourceLoaders.size()) {
+        return resourceLoaders[index];
+    } else {
+        return NULL;
+    }
+}
+
+
+MaterialResourceLoader::MaterialResourceLoader() {
+    extensions.push_back("mat");
+}
+
+Resource *MaterialResourceLoader::loadResource(const String &path, ResourcePool *targetPool) {
+    Services()->getMaterialManager()->loadMaterialLibraryIntoPool(targetPool, path);
+    return NULL;
+}
+
+ProgramResourceLoader::ProgramResourceLoader() {
+    extensions.push_back("frag");
+    extensions.push_back("vert");
+}
+
+Resource *ProgramResourceLoader::loadResource(const String &path, ResourcePool *targetPool) {
+    ShaderProgram *newProgram = Services()->getMaterialManager()->createProgramFromFile(path);
+    return newProgram;
+}
+
+FontResourceLoader::FontResourceLoader() {
+    extensions.push_back("ttf");
+    extensions.push_back("otf");
+}
+
+Resource *FontResourceLoader::loadResource(const String &path, ResourcePool *targetPool) {
+    OSFileEntry entry = OSFileEntry(path, OSFileEntry::TYPE_FILE);
+    Services()->getFontManager()->registerFont(entry.nameWithoutExtension, path);
+    // TODO: make fonts resources, get rid of font manager
+    return NULL;
 }
 }
 
 
 void ResourceManager::handleEvent(Event *event) {
 void ResourceManager::handleEvent(Event *event) {
@@ -322,38 +344,6 @@ ResourcePool *ResourceManager::getGlobalPool() {
     return globalPool;
     return globalPool;
 }
 }
 
 
-void ResourceManager::parseTexturesIntoPool(ResourcePool *pool, const String& dirPath, bool recursive, const String& basePath) {
-	MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();
-	vector<OSFileEntry> resourceDir;
-	resourceDir = Services()->getCore()->parseFolder(dirPath, false);
-	for(int i=0; i < resourceDir.size(); i++) {	
-		if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
-			if(resourceDir[i].extension == "png") {
-				Logger::log("Adding texture %s\n", resourceDir[i].nameWithoutExtension.c_str());
-				Texture *t = materialManager->createTextureFromFile(resourceDir[i].fullPath, materialManager->clampDefault, materialManager->mipmapsDefault);
-				if(t) {
-					if(basePath == "") {
-						t->setResourceName(resourceDir[i].name);
-						t->setResourcePath(resourceDir[i].fullPath);
-					} else {
-						t->setResourceName(basePath+"/"+resourceDir[i].name);
-						t->setResourcePath(resourceDir[i].fullPath);						
-					}
-					pool->addResource(t);
-				}
-			}
-		} else {
-			if(recursive) {
-				if(basePath == "") {			
-					parseTexturesIntoPool(pool, dirPath+"/"+resourceDir[i].name, true, resourceDir[i].name);
-				} else {
-					parseTexturesIntoPool(pool, dirPath+"/"+resourceDir[i].name, true, basePath+"/"+resourceDir[i].name);
-				}
-			}
-		}
-	}
-}
-
 void ResourceManager::Update(int elapsed) {
 void ResourceManager::Update(int elapsed) {
     globalPool->Update(elapsed);
     globalPool->Update(elapsed);
     for(int i=0; i < pools.size(); i++) {
     for(int i=0; i < pools.size(); i++) {