Horde3D

Next-Generation Graphics Engine
It is currently 30.04.2024, 15:05

All times are UTC + 1 hour




Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: 23.08.2008, 03:28 
Offline

Joined: 23.07.2008, 06:25
Posts: 13
Location: Texas/CyberSpace
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.


Last edited by wild13 on 30.08.2008, 16:30, edited 2 times in total.

Top
 Profile  
Reply with quote  
PostPosted: 24.08.2008, 18:56 
Offline

Joined: 26.03.2008, 02:58
Posts: 160
Oh this is handy ;) Thanks.


Top
 Profile  
Reply with quote  
PostPosted: 24.08.2008, 20:08 
Offline

Joined: 23.07.2008, 06:25
Posts: 13
Location: Texas/CyberSpace
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 :shock: . 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 :)


Top
 Profile  
Reply with quote  
PostPosted: 24.08.2008, 22:47 
Offline

Joined: 22.11.2007, 17:05
Posts: 707
Location: Boston, MA
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.

_________________
Tristam MacDonald - [swiftcoding]


Top
 Profile  
Reply with quote  
PostPosted: 30.08.2008, 16:07 
Offline

Joined: 23.07.2008, 06:25
Posts: 13
Location: Texas/CyberSpace
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


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group