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 ![]() |
Author: | DDd [ 24.08.2008, 18:56 ] |
Post subject: | Re: Easy to use ResourceManager |
Oh this is handy ![]() |
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 ![]() ![]() 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 ![]() ![]() ![]() 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 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/ |