Horde3D http://www.horde3d.org/forums/ |
|
Easy to use ResourceManager(Updated windows) http://www.horde3d.org/forums/viewtopic.php?f=1&t=468 |
Page 1 of 1 |
Author: | wild13 [ 23.08.2008, 03:28 ] |
Post subject: | Easy to use ResourceManager(Updated windows) |
Alright so i got sick of how horde manages its resource. i was tired of always adding the resource then creating the node. most of all setting the directory and calling Horde3DUtils::loadResourcesFromDisk( "" ); So i came up with a simple resource manager that can be used like this. Edit: Decided to make the manager better and for it to be able to hold its own without need for horde3dutils check latest post bottom of page free to use if you like easy to modify nothing great i just took the tedious task of doing it. |
Author: | DDd [ 24.08.2008, 18:56 ] |
Post subject: | Re: Easy to use ResourceManager |
Oh this is handy Thanks. |
Author: | wild13 [ 24.08.2008, 20:08 ] |
Post subject: | Re: Easy to use ResourceManager |
Alright here is a major update you really want this version it is what i like to call a smart resource manager . The previous one to my understanding still relied on the loadresourcefromdisk and well that wouldn't do. So i ventured forth and decided what if i could grab the directory to look in from the given path and search that directory for all its subdirectorys. then what if i could check to make sure its done for all new paths also . So thats what i did. It even checks to make sure it dosnt check the same directory twice and to make sure it dosnt add the same data to the known list. Best of all it no longer relies on loadresourcefromdisk i actually winged it completely off the horde 3d utils Code: Here is a better explanation createResource("media/materials/logo.material.xml"); from there the manager snips everything up to the first "/". it then stores the snipped string including the "/" . so "media/" is added to a vector1. the manager then searches the media/ directory for all its sub directory's and adds it to vector2. when load is called it starts making strings and passes it to the load function. the manager gets a resource from the query and trys to load it. vector1[i] + vector2[i] + "/" +Horde3D::getResourceName(ress); after it is loaded it moves onto the next in the list. if createResource is called again with the same "media/" it does not check the directory for sub directorys or add anything to vector 1 or 2. the manager cycles threw every possible string combination that can be made out of vecto1 + vector 2 + "\" + horde::getResourceName(ress); to find the desired resource. then loads it if not found it will tell horde to use its defualt resource. Now for code : Code: #ifndef IRESOURCEMANAGER_H_INCLUDED #define IRESOURCEMANAGER_H_INCLUDED #include <string> #include "IResource.h" class IResource; enum ResourceType{ mesh,geometry,pipeline,animation,material,shadercode,shader,texture,cubemap,effect}; class IResourceManager{ public: virtual void createResource(ResourceType type,std::string identifier, std::string path) = 0; virtual IResource *getResource(std::string identifier) = 0; virtual int getNode(std::string identifier) = 0; virtual int getRes(std::string identifier) = 0; virtual void destroyAll() = 0; }; extern "C" IResourceManager* getResourceManager(void); #endif // IRESOURCEMANAGER_H_INCLUDED Code: #ifndef CRESOURCEMANAGER_H_INCLUDED #define CRESOURCEMANAGER_H_INCLUDED #include <Horde3D.h> #include <map> #include "IResourceManager.h" #include "CResource.h" class IResource; class CResourceManager: public IResourceManager{ public: //! Create a Resource void createResource(ResourceType type,std::string identifier, std::string path); //! Returns the entire IResource Object IResource *getResource(std::string identifier); //! Returns the selected object node int getNode(std::string identifier); //! Returns the selected object resource int getRes(std::string identifier); //! Destroys all void destroyAll(); static CResourceManager* Instance() { return &m_CResourceManager; } protected: CResourceManager(){} private: static CResourceManager m_CResourceManager; std::map<std::string,CResource*>resourceMap; }; #endif // CRESOURCEMANAGER_H_INCLUDED Code: #include "CResourceManager.h" CResourceManager CResourceManager::m_CResourceManager; extern "C" { IResourceManager* getResourceManager(void) { return CResourceManager::Instance(); } } void CResourceManager::createResource(ResourceType type, std::string identifier, std::string path){ resourceMap[identifier] = new CResource; if(type == mesh){ resourceMap[identifier]->loadMesh(path);} if(type == geometry){ resourceMap[identifier]->loadGeometry(path);} if(type == animation){ resourceMap[identifier]->loadAnimation(path);} if(type == material){ resourceMap[identifier]->loadMaterial(path);} if(type == shadercode){ resourceMap[identifier]->loadShaderCode(path);} if(type == shader){ resourceMap[identifier]->loadShader(path);} if(type == texture){ resourceMap[identifier]->loadTexture(path);} if(type == cubemap){ resourceMap[identifier]->loadCubeMap(path);} if(type == effect){ resourceMap[identifier]->loadEffect(path);} if(type == pipeline){ resourceMap[identifier]->loadPipeLine(path);} } IResource *CResourceManager::getResource(std::string identifier){ std::map<std::string,CResource*>::iterator i = resourceMap.find(identifier); if (i == resourceMap.end()) return NULL; return i->second; } int CResourceManager::getNode(std::string identifier){ std::map<std::string,CResource*>::iterator i = resourceMap.find(identifier); if (i == resourceMap.end()) return NULL; return i->second->getNode(); } int CResourceManager::getRes(std::string identifier){ std::map<std::string,CResource*>::iterator i = resourceMap.find(identifier); if (i == resourceMap.end()) return NULL; return i->second->getResource(); } void CResourceManager::destroyAll(){ std::map<std::string,CResource*>::iterator i = resourceMap.begin(); while ( i != resourceMap.end()) { delete i->second; resourceMap.erase(i++); } } Code: #ifndef IRESOURCE_H_INCLUDED #define IRESOURCE_H_INCLUDED #include <Horde3D.h> #include <string> #include <map> #include <vector> class IResource{ public: virtual void loadMesh(std::string resourcepath) = 0; virtual void loadGeometry(std::string resourcepath) = 0; virtual void loadAnimation(std::string resourcepath) = 0; virtual void loadMaterial(std::string resourcepath) = 0; virtual void loadShaderCode(std::string resourcepath) = 0; virtual void loadShader(std::string resourcepath) = 0; virtual void loadTexture(std::string resourcepath) = 0; virtual void loadCubeMap(std::string resourcepath) = 0; virtual void loadEffect(std::string resourcepath) = 0; virtual void loadPipeLine(std::string resourcepath)= 0; virtual int getResource() = 0; virtual int getNode() = 0; protected: virtual bool loadFile() = 0; virtual bool checkPath(std::string path) = 0; int node; int res; }; #endif // IRESOURCE_H_INCLUDED Code: #ifndef CRESOURCE_H_INCLUDED #define CRESOURCE_H_INCLUDED #include <Horde3D.h> #include <Horde3DUtils.h> #include <fstream> #include <vector> #include <map> #include <iostream> #include <vector> #include <dirent.h> #include "IResource.h" class CResource : public IResource{ public: CResource(); ~CResource(); //!Load a mesh file node is created. void loadMesh(std::string resourcepath); //!Load a geo file node is created. void loadGeometry(std::string resourcepath); //!Load a file with animation information. void loadAnimation(std::string resourcepath); //!Load a material. void loadMaterial(std::string resourcepath); //!Load a file with shader code. void loadShaderCode(std::string resourcepath); //!Load a shader. void loadShader(std::string resourcepath); //!Load a texutre. void loadTexture(std::string resourcepath); //!Load a cubemap. void loadCubeMap(std::string resourcepath); //!Load a effect. void loadEffect(std::string resourcepath); //!Load a pipeline. void loadPipeLine(std::string resourcepath); //!Returns the resource created. int getResource(); //!Returns the node created if one was. int getNode(); static std::vector<CResource*> resourcehold;//Holds all CResource objects protected: bool loadFile();//does the tedious task of creating all the search strings and finding the file void searchDir(std::string dir);//searchs a givin directory for all its subdirectorys then stores in knownSubDirectory bool checkPath(std::string path);//checks to make sure the given then stores part of it in knownDirectory std::string resource;// stores the full resource path std::string resourcecut;//stores the cut path of a file from the last / down . ex. test.test.xml std::string resourcedir;//stores the directory of a given path up tot he first / ex. media/ DIR *dp;//our directory poi8nter struct dirent *dirp;//our dirent structure pointer bool result;// result bool to see if loaded or not private: static std::vector<std::string> knownDirectorys;//vector that stores all know directorys ex. media/ static std::vector<std::string> knownSubDirectorys;//vector that stores all subdirectorys ex. /test static bool onetime;//static bool so the first directory is added only one time size_t found;//stores location of a character }; #endif // CRESOURCE_H_INCLUDED Code: #include "CResource.h" std::vector<CResource*> CResource::resourcehold; std::vector<std::string> CResource::knownDirectorys; std::vector<std::string> CResource::knownSubDirectorys; bool CResource::onetime = false; CResource::CResource(){ resourcehold.push_back(this); } CResource::~CResource(){ Horde3D::removeResource(res); } void CResource::loadMesh(std::string resourcepath){ if(checkPath(resourcepath) != false){ res = Horde3D::addResource(ResourceTypes::SceneGraph,resourcecut.c_str(),0); loadFile(); node = Horde3D::addNodes(RootNode,res); } } void CResource::loadGeometry(std::string resourcepath){ if(checkPath(resourcepath) != false){ res = Horde3D::addResource(ResourceTypes::Geometry,resourcecut.c_str(),0); loadFile(); node = Horde3D::addNodes(RootNode,res); } } void CResource::loadAnimation(std::string resourcepath){ if(checkPath(resourcepath) != false){ res = Horde3D::addResource(ResourceTypes::Animation,resourcecut.c_str(),0); loadFile(); } } void CResource::loadMaterial(std::string resourcepath){ if(checkPath(resourcepath) != false){ res = Horde3D::addResource(ResourceTypes::Material,resourcecut.c_str(),0); loadFile(); } } void CResource::loadShaderCode(std::string resourcepath){ if(checkPath(resourcepath) != false){ res = Horde3D::addResource(ResourceTypes::Code,resourcecut.c_str(),0); loadFile(); } } void CResource::loadShader(std::string resourcepath){ if(checkPath(resourcepath) != false){ res = Horde3D::addResource(ResourceTypes::Shader,resourcecut.c_str(),0); loadFile(); } } void CResource::loadTexture(std::string resourcepath){ if(checkPath(resourcepath) != false){ res = Horde3D::addResource(ResourceTypes::Texture2D,resourcecut.c_str(),0); loadFile(); } } void CResource::loadCubeMap(std::string resourcepath){ if(checkPath(resourcepath) != false){ res = Horde3D::addResource(ResourceTypes::TextureCube,resourcecut.c_str(),0); loadFile(); } } void CResource::loadEffect(std::string resourcepath){ if(checkPath(resourcepath) != false){ res = Horde3D::addResource(ResourceTypes::Effect,resourcecut.c_str(),0); loadFile(); } } void CResource::loadPipeLine(std::string resourcepath){ if(checkPath(resourcepath) != false){ res = Horde3D::addResource(ResourceTypes::Pipeline,resourcecut.c_str(),0); loadFile(); } } int CResource::getResource(){ return res; } int CResource::getNode(){ return node; } bool CResource::loadFile(){ std::ifstream inf; result = true; int ress = Horde3D::queryUnloadedResource(); while(ress != 0){ for( unsigned int i = 0; i < knownDirectorys.size(); ++i ){ for(unsigned int j = 0; i < knownSubDirectorys.size(); ++j){ std::string fileName = knownDirectorys[i] + knownSubDirectorys[j] + "/" + Horde3D::getResourceName( ress ); inf.clear(); inf.open( fileName.c_str(), std::ios::binary ); std::cout<<fileName<<std::endl; if( inf.good()) break; } if(inf.good())break; } if( inf.good() ){ // Resource file found //string filename = // Find size of resource file inf.seekg( 0, std::ios::end ); int size = inf.tellg(); // Copy resource file to memory char *data = new char[size + 1]; inf.seekg( 0 ); inf.read( data, size ); inf.close(); // Null-terminate buffer - this is important for XML data data[size] = '\0'; // Send resource data to engine result &= Horde3D::loadResource( ress, data, size + 1 ); delete[] data; }else{ // Resource file not found // Tell engine to use the dafault resource by using NULL as data pointer Horde3D::loadResource( ress, 0x0, 0 ); result = false; } ress = Horde3D::queryUnloadedResource(); } return result; } bool CResource::checkPath(std::string path){ if(path.empty() != true){ resource = path; found = path.find_last_of("/"); resourcecut = path.substr(found+1); found = path.find_first_of("/"); resourcedir = path.substr(0,found+1); if(onetime == false){ onetime = true; knownDirectorys.push_back(resourcedir); searchDir(resourcedir); } std::vector<std::string>::iterator i = knownDirectorys.begin(); bool there = false; for (i = knownDirectorys.begin(); i != knownDirectorys.end() ; i++){ if( *i == resourcedir){ there = true; } } if(there == false){ knownDirectorys.push_back(resourcedir); searchDir(resourcedir); } return true; }else{ return false; } } void CResource::searchDir(std::string dir){ dp = opendir(dir.c_str()); if(dp != NULL){ while((dirp = readdir(dp)) != NULL){ if(strcmp(".", dirp->d_name ) != 0 && strcmp("..",dirp->d_name) != 0){ bool there2 = false; std::vector<std::string>::iterator i = knownSubDirectorys.begin(); for (i = knownSubDirectorys.begin(); i != knownSubDirectorys.end() ; i++){ if( *i == std::string(dirp->d_name)){ there2 = true; } } if(there2 == false){ knownSubDirectorys.push_back(std::string(dirp->d_name)); std::cout<<knownSubDirectorys.back();} } } closedir(dp); } } Same thing has before free to use free to modify have at it |
Author: | swiftcoder [ 24.08.2008, 22:47 ] |
Post subject: | Re: Easy to use ResourceManager(Updated must see) |
You might want to also add in support for Windows - mainly you need to #ifdef that directory walking code, and write it again in Win32. |
Author: | wild13 [ 30.08.2008, 16:07 ] |
Post subject: | Re: Easy to use ResourceManager(Updated windows) |
Alright sorry for the week of no responce college and highschool has been giving me quite a bit to do. I just got the windows support working you only need to add two files and change one file so all is easy Anyways enjoy the code and talk to you all later. anyways first off you want to change the CResource.h file Code: #ifndef CRESOURCE_H_INCLUDED #define CRESOURCE_H_INCLUDED #include <Horde3D.h> #include <Horde3DUtils.h> #include <fstream> #include <vector> #include <map> #include <iostream> #include <vector> #include "IResource.h" #ifdef WIN32 #include "CDirSearch.h" #else #include <dirent.h> #endif namespace DTEngine{ class CResource : public IResource{ public: CResource(); ~CResource(); //!Load a mesh file node is created. void loadMesh(std::string resourcepath); //!Load a geo file node is created. void loadGeometry(std::string resourcepath); //!Load a file with animation information. void loadAnimation(std::string resourcepath); //!Load a material. void loadMaterial(std::string resourcepath); //!Load a file with shader code. void loadShaderCode(std::string resourcepath); //!Load a shader. void loadShader(std::string resourcepath); //!Load a texutre. void loadTexture(std::string resourcepath); //!Load a cubemap. void loadCubeMap(std::string resourcepath); //!Load a effect. void loadEffect(std::string resourcepath); //!Load a pipeline. void loadPipeLine(std::string resourcepath); //!Returns the resource created. int getResource(); //!Returns the node created if one was. int getNode(); static std::vector<CResource*> resourcehold;//Holds all CResource objects protected: bool loadFile();//does the tedious task of creating all the search strings and finding the file void searchDir(std::string dir);//searchs a givin directory for all its subdirectorys then stores in knownSubDirectory bool checkPath(std::string path);//checks to make sure the given then stores part of it in knownDirectory std::string resource;// stores the full resource path std::string resourcecut;//stores the cut path of a file from the last / down . ex. test.test.xml std::string resourcedir;//stores the directory of a given path up tot he first / ex. media/ DIR *dp;//our directory poi8nter struct dirent *dirp;//our dirent structure pointer bool result;// result bool to see if loaded or not private: static std::vector<std::string> knownDirectorys;//vector that stores all know directorys ex. media/ static std::vector<std::string> knownSubDirectorys;//vector that stores all subdirectorys ex. /test static bool onetime;//static bool so the first directory is added only one time size_t found;//stores location of a character }; } #endif // CRESOURCE_H_INCLUDED Then you want to create two more files one called CDirSearch.h and CDirSearch.cpp it is basically a version of dirent that has been ported to windows so the directory walking code dos not have to change. I added a ifdef into the CDirSearch.cpp so users on linux who try compiling it wont have any troubles. Code: #ifndef CDIRSEARCH_H_INCLUDED #define CDIRSEARCH_H_INCLUDED //This is included if the compiler is compiling under windows. //If it isnt it uses the standard dirent.h #include <stdio.h> struct dirent { char d_name[FILENAME_MAX+1]; }; typedef struct DIR DIR; DIR * opendir ( const char * dirname ); struct dirent * readdir ( DIR * dir ); int closedir ( DIR * dir ); void rewinddir ( DIR * dir ); #endif // CDIRSEARCH_H_INCLUDED Code: #ifdef WIN32
#include <windows.h> #include <errno.h> #include <sys/stat.h> #include <string.h> #include <malloc.h> #include "CDirSearch.h" struct DIR { HANDLE hFind; char szDirName[1]; }; //-------------------------------------------------------------------------- // Name countslashes // // Description //-------------------------------------------------------------------------- static int countslashes(const char *dirname) { const char *p; int n; n = 0; p = dirname; while (*p) if (*p++ == '\\') ++n; return n; } //-------------------------------------------------------------------------- // Name opendir // // Description //-------------------------------------------------------------------------- DIR * opendir ( const char * dirname ) { DIR * dir; int nameLen; struct stat st; unsigned char flagNetPath; unsigned char flagRootOnly; if (dirname == NULL || *dirname == 0) { errno = EINVAL; return NULL; } nameLen = strlen( dirname ); flagNetPath = 0; if (dirname[0] == '\\' && dirname[1] == '\\') flagNetPath = 1; /* we have to check for root-dir-only case */ flagRootOnly = 0; if (flagNetPath) { if (countslashes(&dirname[2]) == 2) /* only the separation for server_name and the root*/ flagRootOnly = 1; } if ((dirname[nameLen-1] == '/' || dirname[nameLen-1] == '\\') && (nameLen != 3 || dirname[1] != ':') && nameLen != 1 && !flagRootOnly) { char * t = alloca( nameLen ); memcpy( t, dirname, nameLen ); t[nameLen-1] = 0; dirname = t; --nameLen; } if (stat( dirname, &st )) return NULL; if ((st.st_mode & S_IFDIR) == 0) { // this is not a DIR errno = ENOTDIR; return NULL; } if ((dir = malloc( sizeof( DIR ) + nameLen + 2 )) == NULL) { errno = ENOMEM; return NULL; } dir->hFind = INVALID_HANDLE_VALUE; memcpy( dir->szDirName, dirname, nameLen ); if (nameLen && dirname[nameLen-1] != ':' && dirname[nameLen-1] != '\\' && dirname[nameLen-1] != '/') { dir->szDirName[nameLen++] = '\\'; } dir->szDirName[nameLen] = '*'; dir->szDirName[nameLen+1] = 0; return dir; }; //-------------------------------------------------------------------------- // Name readdir // // Description //-------------------------------------------------------------------------- struct dirent * readdir ( DIR * dir ) { static WIN32_FIND_DATA fData; if (dir == NULL) { errno = EBADF; return NULL; } do { int ok = 1; if (dir->hFind == INVALID_HANDLE_VALUE) { dir->hFind = FindFirstFile( dir->szDirName, &fData ); if (dir->hFind == INVALID_HANDLE_VALUE) ok = 0; } else if (!FindNextFile( dir->hFind, &fData )) ok = 0; if (!ok) { switch (GetLastError()) { case ERROR_NO_MORE_FILES: case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; case ERROR_NOT_ENOUGH_MEMORY: errno = ENOMEM; break; default: errno = EINVAL; break; } return NULL; } } while (fData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN); return (struct dirent *)&fData.cFileName; }; //-------------------------------------------------------------------------- // Name closedir // // Description //-------------------------------------------------------------------------- int closedir ( DIR * dir ) { if (dir == NULL) { errno = EBADF; return -1; } if (dir->hFind != INVALID_HANDLE_VALUE) FindClose( dir->hFind ); free( dir ); return 0; }; //-------------------------------------------------------------------------- // Name rewinddir // // Description //-------------------------------------------------------------------------- void rewinddir ( DIR * dir ) { if (dir) { if (dir->hFind != INVALID_HANDLE_VALUE) FindClose( dir->hFind ); dir->hFind = INVALID_HANDLE_VALUE; } }; #endif |
Page 1 of 1 | All times are UTC + 1 hour |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |