Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/util/resource_manager.cc @ 3658

Last change on this file since 3658 was 3658, checked in by bensch, 19 years ago

orxonox/trunk: resource manager working, player uses it.

File size: 8.6 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
17
18#include "resource_manager.h"
19
20// different resource Types
21#include "objModel.h"
22#include "primitive_model.h"
23#include "texture.h"
24
25#include "list.h"
26
27// File Handling Includes
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <unistd.h>
31
32using namespace std;
33
34/**
35   \brief standard constructor
36*/
37ResourceManager::ResourceManager () 
38{
39   this->setClassName ("ResourceManager");
40   dataDir = NULL;
41   imageDirs = new tList<char>();
42   resourceList = new tList<Resource>();
43}
44
45ResourceManager* ResourceManager::getInstance(void)
46{
47  if (!ResourceManager::singletonRef)
48    ResourceManager::singletonRef = new ResourceManager();
49  return ResourceManager::singletonRef;
50}
51
52//! Singleton Reference to the ResourceManager
53ResourceManager* ResourceManager::singletonRef = NULL;
54//! The List of Resources, that has already been loaded.
55tList<Resource>* ResourceManager::resourceList = NULL;
56//! The Data Directory, where all relevant Data is stored.
57char* ResourceManager::dataDir = NULL;
58//! A list of directories in which images are stored.
59tList<char>* ResourceManager::imageDirs = NULL;
60
61/**
62   \brief standard deconstructor
63*/
64ResourceManager::~ResourceManager (void) 
65{
66
67  delete resourceList;
68  resourceList = NULL;
69  ResourceManager::singletonRef = NULL;
70}
71
72/**
73   \brief sets the data main directory
74   \param dataDir the DataDirectory.
75*/
76bool ResourceManager::setDataDir(char* dataDir)
77{
78  if (isDir(dataDir))
79    {
80      ResourceManager::dataDir = new char[strlen(dataDir)+1];
81      strcpy(ResourceManager::dataDir, dataDir);
82    }
83  else
84    {
85      PRINTF(1)("%s is not a Directory, and can not be the Data Directory\n", dataDir);
86    }
87}
88
89bool ResourceManager::addImageDir(char* imageDir)
90{
91  if (isDir(imageDir))
92    {
93      char* tmpDir  = new char[strlen(imageDir)+1];
94      strcpy(tmpDir, imageDir);
95      imageDirs->add(tmpDir);
96    }
97  else
98    {
99      PRINTF(1)("%s is not a Directory, and can not be added to the Paths of Images\n", dataDir);
100    }
101}
102
103/**
104   \brief loads resources
105   \param fileName The fileName of the resource to load
106   \returns a pointer to a desired Resource.
107*/
108void* ResourceManager::load(const char* fileName)
109{
110  ResourceType tmpType;
111  if (!strncmp(fileName+(strlen(fileName)-4), ".obj", 4))
112    tmpType = OBJ;
113  else if (!strncmp(fileName+(strlen(fileName)-4), ".wav", 4))
114    tmpType = WAV;
115  else if (!strncmp(fileName+(strlen(fileName)-4), ".mp3", 4))
116    tmpType = MP3;
117  else if (!strncmp(fileName+(strlen(fileName)-4), ".ogg", 4))
118    tmpType = OGG;
119  else if (!strcmp(fileName, "cube") ||
120           !strcmp(fileName, "sphere") ||
121           !strcmp(fileName, "plane") ||
122           !strcmp(fileName, "cylinder") ||
123           !strcmp(fileName, "cone"))
124    tmpType = PRIM;
125  else 
126    tmpType = IMAGE;
127
128  return ResourceManager::load(fileName, tmpType);
129}
130
131/**
132   \brief loads resources
133   \param fileName The fileName of the resource to load
134   \param type The Type of Resource to load (\see ResourceType)
135   \returns a pointer to a desired Resource.
136*/
137void* ResourceManager::load(const char* fileName, ResourceType type)
138{
139  // searching if the resource was loaded before.
140  Resource* tmpResource = ResourceManager::locateResourceByName(fileName);
141  char* tmpDir;
142  if (!tmpResource) // if the resource was not loaded before.
143    {
144      // Setting up the new Resource
145      tmpResource = new Resource;
146      tmpResource->count = 1;
147      tmpResource->type = type;
148      tmpResource->name = new char[strlen(fileName)+1];
149      strcpy(tmpResource->name, fileName);
150
151      // creating the full name. (directoryName + FileName)
152      char* fullName = new char[strlen(dataDir)+strlen(fileName)+1];
153      sprintf(fullName, "%s%s", dataDir, fileName);
154     
155      // Checking for the type of resource \see ResourceType
156      switch(type)
157        {
158        case OBJ:
159          if(isFile(fullName))
160            tmpResource->pointer = new OBJModel(fullName);
161          else
162            {
163              PRINTF(2)("Sorry, %s does not exist. Loading a cube-Model instead\n", fullName);
164              tmpResource->pointer = ResourceManager::load("cube", PRIM);
165            }
166          break;
167        case PRIM:
168          if (!strcmp(tmpResource->name, "cube"))
169            tmpResource->pointer = new PrimitiveModel(CUBE);
170          else if (!strcmp(tmpResource->name, "sphere"))
171            tmpResource->pointer = new PrimitiveModel(SPHERE);
172          else if (!strcmp(tmpResource->name, "plane"))
173            tmpResource->pointer = new PrimitiveModel(PLANE);
174          else if (!strcmp(tmpResource->name, "cylinder"))
175            tmpResource->pointer = new PrimitiveModel(CYLINDER);
176          else if (!strcmp(tmpResource->name, "cone"))
177            tmpResource->pointer = new PrimitiveModel(CONE);
178          break;
179        case IMAGE:
180          if(isFile(fullName))
181            {
182              tmpResource->pointer = new Texture(fullName);
183            }
184          else
185            {
186              tmpDir = imageDirs->enumerate();
187              while(tmpDir)
188                {
189                  char* imgName = new char[strlen(tmpDir)+strlen(fileName)+1];
190                  sprintf(imgName, "%s%s", tmpDir, fileName);
191                  if(isFile(imgName))
192                    tmpResource->pointer = new Texture(imgName);
193                  delete []imgName;
194                  tmpDir = imageDirs->nextElement();
195                }
196            }
197          if(!tmpResource)
198             PRINTF(2)("!!Image %s not Found!!\n", fileName);
199          break;
200        default:
201          tmpResource->pointer = NULL;
202          PRINTF(1)("No type found for %s.\n   !!This should not happen unless the Type is not supported yet.!!\n", tmpResource->name);
203          break;
204        }
205     
206      // checking if the File really exists.
207      if(!isFile(fullName))
208        {
209          PRINTF(2)("Sorry, %s is not a regular file.\n", fullName);
210          tmpResource->pointer = NULL;
211        }
212      resourceList->add(tmpResource);
213      delete []fullName;
214
215    }
216  else
217    {
218      tmpResource->count++;
219    }
220
221  return tmpResource->pointer;
222}
223
224/**
225   \brief unloads a Resource
226   \param pointer The pointer to free
227   \returns true if successful (pointer found, and deleted), false otherwise
228   
229*/
230bool ResourceManager::unload(void* pointer)
231{
232  // if pointer is existent. and only one resource of this type exists.
233  Resource* tmpResource = ResourceManager::locateResourceByPointer(pointer);
234  if (!tmpResource)
235    {
236      PRINTF(2)("Resource not Found %p\n", pointer);
237      return false;
238    }
239  tmpResource->count--;
240  if (tmpResource->count <= 0)
241    {
242      // deleting the Resource
243      switch(tmpResource->type)
244        {
245        case OBJ:
246        case PRIM:
247          delete (Model*)tmpResource->pointer;
248          break;
249        case IMAGE:
250          delete (Texture*)tmpResource->pointer;
251          break;
252        default:
253          PRINTF(1)("NOT YET IMPLEMENTED FIX FIX\n");
254          return false;
255          break;
256        }
257      // deleting the List Entry:
258      PRINTF(4)("Resource %s Safely removed.\n", tmpResource->name);
259      delete []tmpResource->name;
260      resourceList->remove(tmpResource);
261    }
262  else
263    PRINTF(4)("Resource not removed, because there are still %d References to it.\n", tmpResource->count);
264  return true;
265}
266
267/**
268   \brief Searches for a Resource by Name
269   \param fileName The name to look for
270   \returns a Pointer to the Resource if found, NULL otherwise.
271*/
272Resource* ResourceManager::locateResourceByName(const char* fileName)
273{
274  Resource* enumRes = resourceList->enumerate();
275  while (enumRes)
276    {
277      if (!strcmp(fileName, enumRes->name))
278        return enumRes;
279      enumRes = resourceList->nextElement();
280    }
281  return NULL;
282}
283
284/**
285   \brief Searches for a Resource by Pointer
286   \param pointer the Pointer to search for
287   \returns a Pointer to the Resource if found, NULL otherwise.
288*/
289Resource* ResourceManager::locateResourceByPointer(const void* pointer)
290{
291  Resource* enumRes = resourceList->enumerate();
292  while (enumRes)
293    {
294      if (pointer == enumRes->pointer);
295        return enumRes;
296      enumRes = resourceList->nextElement();
297    }
298  return NULL;
299}
300
301/**
302   \brief Checks if it is a Directory
303   \param directoryName the Directory to check for
304   \returns true if it is a directory/symlink false otherwise
305*/
306bool ResourceManager::isDir(const char* directoryName)
307{
308  struct stat status;
309  stat(directoryName, &status);
310  if (status.st_mode & (S_IFDIR | S_IFLNK))
311    return true;
312  else
313    return false;
314}
315
316/**
317   \brief Checks if the file is either a Regular file or a Symlink
318   \param fileName the File to check for
319   \returns true if it is a regular file/symlink, false otherwise
320*/
321bool ResourceManager::isFile(const char* fileName)
322{
323  struct stat status;
324  stat(fileName, &status);
325  if (status.st_mode & (S_IFREG | S_IFLNK))
326    return true;
327  else
328    return false;
329}
Note: See TracBrowser for help on using the repository browser.