Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/util/loading/resource_manager.cc @ 6646

Last change on this file since 6646 was 6646, checked in by bensch, 18 years ago

trunk: ResourceManeger names

File size: 28.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: Patrick Boenzli
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
17
18#include "resource_manager.h"
19
20#include "debug.h"
21
22#include <algorithm>
23
24// different resource Types
25#ifndef NO_MODEL
26#include "objModel.h"
27#include "primitive_model.h"
28#include "md2Model.h"
29#endif /* NO_MODEL */
30#ifndef NO_TEXTURES
31#include "texture.h"
32#endif /* NO_TEXTURES */
33#ifndef NO_TEXT
34#include "font.h"
35#endif /* NO_TEXT */
36#ifndef NO_AUDIO
37#include "sound_buffer.h"
38#include "ogg_player.h"
39#endif /* NO_AUDIO */
40#ifndef NO_SHADERS
41#include "shader.h"
42#endif /* NO_SHADERS */
43
44// File Handling Includes
45#include <sys/types.h>
46#include <sys/stat.h>
47#include <unistd.h>
48
49using namespace std;
50
51/**
52 *  standard constructor
53*/
54ResourceManager::ResourceManager ()
55{
56  this->setClassID(CL_RESOURCE_MANAGER, "ResourceManager");
57  this->setName("ResourceManager");
58
59  this->dataDir = new char[3];
60  strcpy(this->dataDir, "./");
61  this->tryDataDir("./data");
62}
63
64//! Singleton Reference to the ResourceManager
65ResourceManager* ResourceManager::singletonRef = NULL;
66
67/**
68 *  standard destructor
69*/
70ResourceManager::~ResourceManager ()
71{
72  // deleting the Resources-List
73  this->unloadAllByPriority(RP_GAME);
74
75  if (!this->resourceList.empty())
76    PRINTF(1)("Not removed all Resources, since there are still %d resources registered\n", this->resourceList.size());
77
78  // deleting the Directorie Lists
79  while (!this->imageDirs.empty())
80  {
81    delete[] this->imageDirs.back();
82    this->imageDirs.pop_back();
83  }
84
85  delete[] this->dataDir;
86
87  ResourceManager::singletonRef = NULL;
88}
89
90/**
91 *  sets the data main directory
92 * @param dataDir the DataDirectory.
93 */
94bool ResourceManager::setDataDir(const char* dataDir)
95{
96  char* realDir = ResourceManager::homeDirCheck(dataDir);
97  if (isDir(realDir))
98  {
99    delete[] this->dataDir;
100    if (dataDir[strlen(dataDir)-1] == '/' || dataDir[strlen(dataDir)-1] == '\\')
101    {
102      this->dataDir = new char[strlen(realDir)+1];
103      strcpy(this->dataDir, realDir);
104    }
105    else
106    {
107      this->dataDir = new char[strlen(realDir)+2];
108      strcpy(this->dataDir, realDir);
109      this->dataDir[strlen(realDir)] = '/';
110      this->dataDir[strlen(realDir)+1] = '\0';
111    }
112    delete[] realDir;
113    return true;
114  }
115  else
116  {
117    PRINTF(1)("%s is not a Directory, and can not be the Data Directory, leaving as %s \n", realDir, this->dataDir);
118    delete[] realDir;
119    return false;
120  }
121}
122
123/**
124 * sets the data main directory
125 * @param dataDir the DataDirectory.
126 *
127 * this is essentially the same as setDataDir, but it ommits the error-message
128 */
129bool ResourceManager::tryDataDir(const char* dataDir)
130{
131  char* realDir = ResourceManager::homeDirCheck(dataDir);
132  if (isDir(realDir))
133  {
134    delete[] this->dataDir;
135    if (dataDir[strlen(dataDir)-1] == '/' || dataDir[strlen(dataDir)-1] == '\\')
136    {
137      this->dataDir = new char[strlen(realDir)+1];
138      strcpy(this->dataDir, realDir);
139    }
140    else
141    {
142      this->dataDir = new char[strlen(realDir)+2];
143      strcpy(this->dataDir, realDir);
144      this->dataDir[strlen(realDir)] = '/';
145      this->dataDir[strlen(realDir)+1] = '\0';
146    }
147    delete[] realDir;
148    return true;
149  }
150  delete[] realDir;
151  return false;
152}
153
154
155
156/**
157 * checks for the DataDirectory, by looking if
158 * @param fileInside is iniside of the given directory.
159*/
160bool ResourceManager::verifyDataDir(const char* fileInside)
161{
162  bool retVal;
163  if (!isDir(this->dataDir))
164  {
165    PRINTF(1)("%s is not a directory\n", this->dataDir);
166    return false;
167  }
168
169  char* testFile = new char[strlen(this->dataDir)+strlen(fileInside)+1];
170  sprintf(testFile, "%s%s", this->dataDir, fileInside);
171  retVal = isFile(testFile);
172  delete[] testFile;
173  return retVal;
174}
175
176#ifndef NO_TEXTURES
177/**
178 *  adds a new Path for Images
179 * @param imageDir The path to insert
180 * @returns true, if the Path was well and injected (or already existent within the list)
181   false otherwise
182*/
183bool ResourceManager::addImageDir(const char* imageDir)
184{
185  if (imageDir == NULL)
186    return false;
187
188  char* newDir;
189  if (imageDir[strlen(imageDir)-1] == '/' || imageDir[strlen(imageDir)-1] == '\\')
190  {
191    newDir = new char[strlen(imageDir)+1];
192    strcpy(newDir, imageDir);
193  }
194  else
195  {
196    newDir = new char[strlen(imageDir)+2];
197    strcpy(newDir, imageDir);
198    newDir[strlen(imageDir)] = '/';
199    newDir[strlen(imageDir)+1] = '\0';
200  }
201  // check if the param is a Directory
202  if (isDir(newDir))
203  {
204    // check if the Directory has been added before
205    std::vector<char*>::const_iterator imageDir;
206    for (imageDir = this->imageDirs.begin(); imageDir != this->imageDirs.end(); imageDir++)
207    {
208      if (!strcmp(*imageDir, newDir))
209      {
210        PRINTF(3)("Path %s already loaded\n", newDir);
211        delete[] newDir;
212        return true;
213      }
214    }
215    // adding the directory to the List
216    this->imageDirs.push_back(newDir);
217    return true;
218  }
219  else
220  {
221    PRINTF(1)("%s is not a Directory, and can not be added to the Paths of Images\n", newDir);
222    delete[] newDir;
223    return false;
224  }
225}
226#endif /* NO_TEXTURES */
227
228/**
229 *  loads resources
230 * @param fileName: The fileName of the resource to load
231 * @param prio: The ResourcePriority of this resource (will only be increased)
232 * @param param0: an additional option to parse (see the constuctors for more help)
233 * @param param1: an additional option to parse (see the constuctors for more help)
234 * @param param2: an additional option to parse (see the constuctors for more help)
235 * @returns a pointer to a desired Resource.
236*/
237BaseObject* ResourceManager::load(const char* fileName, ResourcePriority prio,
238                                   const MultiType& param0, const MultiType& param1, const MultiType& param2)
239{
240  if (fileName == NULL)
241    return NULL;
242  ResourceType tmpType;
243#ifndef NO_MODEL
244#define __IF_OK
245  if (!strncasecmp(fileName+(strlen(fileName)-4), ".obj", 4))
246    tmpType = OBJ;
247  else if (!strncmp(fileName+(strlen(fileName)-4), ".md2", 4))
248    tmpType = MD2;
249  else if (!strcasecmp(fileName, "cube") ||
250           !strcasecmp(fileName, "sphere") ||
251           !strcasecmp(fileName, "plane") ||
252           !strcasecmp(fileName, "cylinder") ||
253           !strcasecmp(fileName, "cone"))
254    tmpType = PRIM;
255#endif /* NO_MODEL */
256#ifndef NO_AUDIO
257#ifdef __IF_OK
258  else
259#endif
260#define __IF_OK
261    if (!strncasecmp(fileName+(strlen(fileName)-4), ".wav", 4))
262      tmpType = WAV;
263    else if (!strncasecmp(fileName+(strlen(fileName)-4), ".mp3", 4))
264      tmpType = MP3;
265    else if (!strncasecmp(fileName+(strlen(fileName)-4), ".ogg", 4))
266      tmpType = OGG;
267#endif /* NO_AUDIO */
268#ifndef NO_TEXT
269#ifdef __IF_OK
270    else
271#endif
272#define __IF_OK
273      if (!strncasecmp(fileName+(strlen(fileName)-4), ".ttf", 4))
274        tmpType = TTF;
275#endif /* NO_TEXT */
276#ifndef NO_SHADERS
277#ifdef __IF_OK
278      else
279#endif
280#define __IF_OK
281        if (!strncasecmp(fileName+(strlen(fileName)-5), ".vert", 5))
282          tmpType = SHADER;
283#endif /* NO_SHADERS */
284#ifndef NO_TEXTURES
285#ifdef __IF_OK
286        else
287#else
288  if
289#endif
290          tmpType = IMAGE;
291#endif /* NO_TEXTURES */
292#undef __IF_OK
293  return this->load(fileName, tmpType, prio, param0, param1, param2);
294}
295
296/**
297 * caches a Resource
298 *
299 * @see load;
300 *
301 * This function loads a Resource without applying it to an Object.
302 * This is for loading purposes, e.g, when the user is loading a Resource
303 * during the initialisation instead of at Runtime.
304 */
305void ResourceManager::cache(const char* fileName, ResourceType type, ResourcePriority prio,
306                            const MultiType& param0, const MultiType& param1, const MultiType& param2)
307{
308  assert(fileName != NULL);
309
310  // searching if the resource was loaded before.
311  Resource* tmpResource;
312  // check if we already loaded this Resource
313  tmpResource = this->locateResourceByInfo(fileName, type, param0, param1, param2);
314  // otherwise load it
315  if (tmpResource == NULL)
316    tmpResource = this->loadResource(fileName, type, prio, param0, param1, param2);
317  // return cached pointer.
318  if (tmpResource != NULL) // if the resource was loaded before.
319    if(tmpResource->prio < prio)
320      tmpResource->prio = prio;
321}
322
323
324/**
325 * loads resources
326 * @param fileName: The fileName of the resource to load
327 * @param type: The Type of Resource to load.
328 * @param prio: The ResourcePriority of this resource (will only be increased)
329 * @param param0: an additional option to parse (see the constuctors for more help)
330 * @param param1: an additional option to parse (see the constuctors for more help)
331 * @param param2: an additional option to parse (see the constuctors for more help)
332 * @returns a pointer to a desired Resource.
333*/
334BaseObject* ResourceManager::load(const char* fileName, ResourceType type, ResourcePriority prio,
335                                  const MultiType& param0, const MultiType& param1, const MultiType& param2)
336{
337  assert(fileName != NULL);
338
339  // searching if the resource was loaded before.
340  Resource* tmpResource;
341  // check if we already loaded this Resource
342  tmpResource = this->locateResourceByInfo(fileName, type, param0, param1, param2);
343  // otherwise load it
344  if (tmpResource == NULL)
345    tmpResource = this->loadResource(fileName, type, prio, param0, param1, param2);
346  // return cached pointer.
347  if (tmpResource != NULL) // if the resource was loaded before.
348  {
349    tmpResource->count++;
350    if(tmpResource->prio < prio)
351      tmpResource->prio = prio;
352    return tmpResource->pointer;
353  }
354  else
355    return NULL;
356}
357
358
359/**
360 * loads resources for internal purposes
361 * @param fileName: The fileName of the resource to load
362 * @param type: The Type of Resource to load.
363 * @param prio: The ResourcePriority of this resource (will only be increased)
364 * @param param0: an additional option to parse (see the constuctors for more help)
365 * @param param1: an additional option to parse (see the constuctors for more help)
366 * @param param2: an additional option to parse (see the constuctors for more help)
367 * @returns a pointer to a desired Resource.
368 */
369Resource* ResourceManager::loadResource(const char* fileName, ResourceType type, ResourcePriority prio,
370                                        const MultiType& param0, const MultiType& param1, const MultiType& param2)
371{
372  // Setting up the new Resource
373  Resource* tmpResource = new Resource;
374  tmpResource->count = 0;
375  tmpResource->type = type;
376  tmpResource->prio = prio;
377  tmpResource->pointer = NULL;
378  tmpResource->name = new char[strlen(fileName)+1];
379  strcpy(tmpResource->name, fileName);
380
381  // creating the full name. (directoryName + FileName)
382  char* fullName = ResourceManager::getFullName(fileName);
383  // Checking for the type of resource \see ResourceType
384  switch(type)
385  {
386#ifndef NO_MODEL
387  case OBJ:
388    if (param0.getType() != MT_NULL)
389      tmpResource->param[0] = param0;
390    else
391      tmpResource->param[0] = 1.0f;
392
393    if(ResourceManager::isFile(fullName))
394      tmpResource->pointer = new OBJModel(fullName, tmpResource->param[0].getFloat());
395    else
396    {
397      PRINTF(2)("File %s in %s does not exist. Loading a cube-Model instead\n", fileName, dataDir);
398      tmpResource->pointer = ResourceManager::load("cube", PRIM, prio, tmpResource->param[0].getFloat());
399    }
400    break;
401  case PRIM:
402    if (param0 != MT_NULL)
403      tmpResource->param[0] = param0;
404    else
405      tmpResource->param[0] = 1.0f;
406
407    if (!strcmp(tmpResource->name, "cube"))
408      tmpResource->pointer = new PrimitiveModel(PRIM_CUBE, tmpResource->param[0].getFloat());
409    else if (!strcmp(tmpResource->name, "sphere"))
410      tmpResource->pointer = new PrimitiveModel(PRIM_SPHERE, tmpResource->param[0].getFloat());
411    else if (!strcmp(tmpResource->name, "plane"))
412      tmpResource->pointer = new PrimitiveModel(PRIM_PLANE, tmpResource->param[0].getFloat());
413    else if (!strcmp(tmpResource->name, "cylinder"))
414      tmpResource->pointer = new PrimitiveModel(PRIM_CYLINDER, tmpResource->param[0].getFloat());
415    else if (!strcmp(tmpResource->name, "cone"))
416      tmpResource->pointer = new PrimitiveModel(PRIM_CONE, tmpResource->param[0].getFloat());
417    break;
418  case MD2:
419    if(ResourceManager::isFile(fullName))
420    {
421      tmpResource->param[0] = param0;
422      tmpResource->pointer = new MD2Data(fullName, tmpResource->param[0].getString());
423      //               tmpResource->pointer = new MD2Model(fullName, tmpResource->secFileName);
424
425    }
426    break;
427#endif /* NO_MODEL */
428#ifndef NO_TEXT
429  case TTF:
430    if (param0 != MT_NULL)
431    {
432      assert(param0.getInt() >= 0);
433      tmpResource->param[0] = param0;
434    }
435    else
436      tmpResource->param[0] = FONT_DEFAULT_RENDER_SIZE;
437
438    if(isFile(fullName))
439      tmpResource->pointer = new Font(fullName, (unsigned int) tmpResource->param[0].getInt());
440    else
441      PRINTF(2)("%s does not exist in %s. Not loading Font\n", fileName, this->dataDir);
442    break;
443#endif /* NO_TEXT */
444#ifndef NO_AUDIO
445  case WAV:
446    if(isFile(fullName))
447      tmpResource->pointer = new SoundBuffer(fullName);
448    break;
449  case OGG:
450    if (isFile(fullName))
451      tmpResource->pointer = new OggPlayer(fullName);
452    break;
453#endif /* NO_AUDIO */
454#ifndef NO_TEXTURES
455  case IMAGE:
456    if (param0 != MT_NULL)
457      tmpResource->param[0] = param0;
458    else
459      tmpResource->param[0] = GL_TEXTURE_2D;
460    if(isFile(fullName))
461    {
462      PRINTF(4)("Image %s resides to %s\n", fileName, fullName);
463      tmpResource->pointer = new Texture(fullName);
464    }
465    else
466    {
467      std::vector<char*>::iterator imageDir;
468      for (imageDir = this->imageDirs.begin(); imageDir != this->imageDirs.end(); imageDir++)
469      {
470        char* imgName = new char[strlen(*imageDir)+strlen(fileName)+1];
471        sprintf(imgName, "%s%s", *imageDir, fileName);
472        if(isFile(imgName))
473        {
474          PRINTF(4)("Image %s resides to %s\n", fileName, imgName);
475          tmpResource->pointer = new Texture(imgName, tmpResource->param[0].getInt());
476          delete[] imgName;
477          break;
478        }
479        delete[] imgName;
480      }
481    }
482    if(!tmpResource)
483      PRINTF(2)("!!Image %s not Found!!\n", fileName);
484    break;
485#endif /* NO_TEXTURES */
486#ifndef NO_SHADERS
487  case SHADER:
488    if(ResourceManager::isFile(fullName))
489    {
490      if (param0 != MT_NULL)
491      {
492        MultiType param = param0; /// HACK
493        char* secFullName = ResourceManager::getFullName(param.getString());
494        if (ResourceManager::isFile(secFullName))
495        {
496          tmpResource->param[0] = secFullName;
497          tmpResource->pointer = new Shader(fullName, secFullName);
498        }
499        delete[] secFullName;
500      }
501      else
502      {
503        tmpResource->param[0] = param0;
504        tmpResource->pointer = new Shader(fullName, NULL);
505      }
506    }
507    break;
508#endif /* NO_SHADERS */
509  default:
510    tmpResource->pointer = NULL;
511    PRINTF(1)("No type found for %s.\n   !!This should not happen unless the Type is not supported yet. JUST DO IT!!\n", tmpResource->name);
512    break;
513  }
514  if (tmpResource->pointer != NULL)
515    this->resourceList.push_back(tmpResource);
516  delete[] fullName;
517
518
519  if (tmpResource->pointer != NULL)
520    return tmpResource;
521  else
522  {
523    PRINTF(2)("Resource %s could not be loaded\n", fileName);
524    delete[] tmpResource->name;
525    delete tmpResource;
526    return NULL;
527  }
528}
529
530/**
531 * unloads a Resource
532 * @param pointer: The pointer to free
533 * @param prio: the PriorityLevel to unload this resource
534 * @returns true if successful (pointer found, and deleted), false otherwise
535*/
536bool ResourceManager::unload(void* pointer, ResourcePriority prio)
537{
538  if (pointer == NULL)
539    return false;
540  // if pointer is existent. and only one resource of this type exists.
541  Resource* tmpResource = this->locateResourceByPointer(pointer);
542  if (tmpResource != NULL)
543    return unload(tmpResource, prio);
544  else
545  {
546    PRINTF(2)("Resource not Found %p\n", pointer);
547    return false;
548  }
549}
550
551/**
552 * unloads a Resource
553 * @param resource: The resource to unloade
554 * @param prio the PriorityLevel to unload this resource
555 * @returns true on success, false otherwise.
556*/
557bool ResourceManager::unload(Resource* resource, ResourcePriority prio)
558{
559  if (resource == NULL)
560    return false;
561  if (resource->count > 0)
562    resource->count--;
563
564  if (resource->prio <= prio)
565  {
566    if (resource->count == 0)
567    {
568      // deleting the Resource
569      switch(resource->type)
570      {
571#ifndef NO_MODEL
572      case OBJ:
573      case PRIM:
574        delete (Model*)resource->pointer;
575        break;
576      case MD2:
577        delete (MD2Data*)resource->pointer;
578        break;
579#endif /* NO_MODEL */
580#ifndef NO_AUDIO
581      case WAV:
582        delete (SoundBuffer*)resource->pointer;
583        break;
584      case OGG:
585        delete (OggPlayer*)resource->pointer;
586        break;
587#endif /* NO_AUDIO */
588#ifndef NO_TEXT
589      case TTF:
590        delete (Font*)resource->pointer;
591        break;
592#endif /* NO_TEXT */
593#ifndef NO_TEXTURES
594      case IMAGE:
595        delete (Texture*)resource->pointer;
596        break;
597#endif /* NO_TEXTURES */
598#ifndef NO_SHADERS
599      case SHADER:
600        delete (Shader*)resource->pointer;
601        break;
602#endif /* NO_SHADERS */
603      default:
604        PRINTF(2)("NOT YET IMPLEMENTED !!FIX FIX!!\n");
605        return false;
606        break;
607      }
608      // deleting the List Entry:
609      PRINTF(4)("Resource %s safely removed.\n", resource->name);
610      delete[] resource->name;
611      std::vector<Resource*>::iterator resourceIT = std::find(this->resourceList.begin(), this->resourceList.end(), resource);
612      this->resourceList.erase(resourceIT);
613      delete resource;
614    }
615    else
616      PRINTF(4)("Resource %s not removed, because there are still %d References to it.\n", resource->name, resource->count);
617  }
618  else
619    PRINTF(4)("not deleting resource %s because DeleteLevel to high\n", resource->name);
620  return true;
621}
622
623
624/**
625 * unloads all alocated Memory of Resources with a pririty lower than prio
626 * @param prio The priority to delete
627*/
628bool ResourceManager::unloadAllByPriority(ResourcePriority prio)
629{
630  unsigned int removeCount;
631  for (unsigned int round = 0; round < 3; round++)
632  {
633    int index = this->resourceList.size() - 1;
634    removeCount = 0;
635    while (index >= 0)
636    {
637      if (this->resourceList[index]->prio <= prio)
638      {
639        if (this->resourceList[index]->count == 0)
640          unload(this->resourceList[index], prio);
641        else
642        {
643          PRINTF(2)("unable to unload %s because there are still %d references to it\n",
644                    this->resourceList[index]->name, this->resourceList[index]->count);
645          removeCount++;
646        }
647      }
648      index--;
649    }
650    if (removeCount == 0) break;
651  }
652}
653
654
655/**
656 * Searches for a Resource by some information
657 * @param fileName: The name to look for
658 * @param type the Type of resource to locate.
659 * @param param0: an additional option to parse (see the constuctors for more help)
660 * @param param1: an additional option to parse (see the constuctors for more help)
661 * @param param2: an additional option to parse (see the constuctors for more help)
662 * @returns a Pointer to the Resource if found, NULL otherwise.
663*/
664Resource* ResourceManager::locateResourceByInfo(const char* fileName, ResourceType type,
665        const MultiType& param0, const MultiType& param1, const MultiType& param2) const
666{
667  std::vector<Resource*>::const_iterator resource;
668  for (resource = this->resourceList.begin(); resource != this->resourceList.end(); resource++)
669  {
670    if ((*resource)->type == type && !strcmp(fileName, (*resource)->name))
671    {
672      bool match = false;
673
674      switch (type)
675      {
676#ifndef NO_MODEL
677      case PRIM:
678      case OBJ:
679        if (param0 == MT_NULL)
680        {
681          if ((*resource)->param[0] == 1.0f)
682            match = true;
683        }
684        else if ((*resource)->param[0] == param0)
685          match = true;
686        break;
687      case MD2:
688        if (param0 == MT_NULL)
689        {
690          if ((*resource)->param[0] == "")
691            match = true;
692        }
693        else if ((*resource)->param[0] == param0)
694          match = true;
695        break;
696#endif /* NO_MODEL */
697#ifndef NO_TEXT
698      case TTF:
699        if (param0 == MT_NULL)
700        {
701          if ((*resource)->param[0] == FONT_DEFAULT_RENDER_SIZE)
702            match = true;
703        }
704        else if ((*resource)->param[0] == param0)
705          match = true;
706        break;
707#endif /* NO_TEXT */
708#ifndef NO_SHADERS
709      case SHADER:
710        if (param0 == MT_NULL)
711        {
712          if ((*resource)->param[0] == "")
713            match = true;
714        }
715        else if ((*resource)->param[0] == param0)
716          match = true;
717#endif /* NO_SHADERS */
718#ifndef NO_TEXTURES
719      case IMAGE:
720        if (param0 == MT_NULL)
721        {
722          if ((*resource)->param[0] == GL_TEXTURE_2D)
723            match = true;
724        }
725        else if ((*resource)->param[0] ==  param0)
726          match = true;
727#endif /* NO_TEXTURES */
728      default:
729        match = true;
730        break;
731      }
732      if (match)
733      {
734        return (*resource);
735      }
736    }
737  }
738  return NULL;
739}
740
741/**
742 * Searches for a Resource by Pointer
743 * @param pointer the Pointer to search for
744 * @returns a Pointer to the Resource if found, NULL otherwise.
745*/
746Resource* ResourceManager::locateResourceByPointer(const void* pointer) const
747{
748  //  Resource* enumRes = resourceList->enumerate();
749  std::vector<Resource*>::const_iterator resource;
750  for (resource = this->resourceList.begin(); resource != this->resourceList.end(); resource++)
751    if (pointer == (*resource)->pointer)
752      return (*resource);
753  return NULL;
754}
755
756/**
757 * Checks if it is a Directory
758 * @param directoryName the Directory to check for
759 * @returns true if it is a directory/symlink false otherwise
760*/
761bool ResourceManager::isDir(const char* directoryName)
762{
763  if (directoryName == NULL)
764    return false;
765
766  char* tmpDirName = NULL;
767  struct stat status;
768
769  // checking for the termination of the string given. If there is a "/" at the end cut it away
770  if (directoryName[strlen(directoryName)-1] == '/' ||
771      directoryName[strlen(directoryName)-1] == '\\')
772  {
773    tmpDirName = new char[strlen(directoryName)];
774    strncpy(tmpDirName, directoryName, strlen(directoryName)-1);
775    tmpDirName[strlen(directoryName)-1] = '\0';
776  }
777  else
778  {
779    tmpDirName = new char[strlen(directoryName)+1];
780    strcpy(tmpDirName, directoryName);
781  }
782
783  if(!stat(tmpDirName, &status))
784  {
785    if (status.st_mode & (S_IFDIR
786#ifndef __WIN32__
787                          | S_IFLNK
788#endif
789                         ))
790    {
791      delete[] tmpDirName;
792      return true;
793    }
794    else
795    {
796      delete[] tmpDirName;
797      return false;
798    }
799  }
800  else
801  {
802    delete[] tmpDirName;
803    return false;
804  }
805}
806
807/**
808 * Checks if the file is either a Regular file or a Symlink
809 * @param fileName the File to check for
810 * @returns true if it is a regular file/symlink, false otherwise
811*/
812bool ResourceManager::isFile(const char* fileName)
813{
814  if (fileName == NULL)
815    return false;
816  char* tmpFileName = ResourceManager::homeDirCheck(fileName);
817  // actually checks the File
818  struct stat status;
819  if (!stat(tmpFileName, &status))
820  {
821    if (status.st_mode & (S_IFREG
822#ifndef __WIN32__
823                          | S_IFLNK
824#endif
825                         ))
826    {
827      delete[] tmpFileName;
828      return true;
829    }
830    else
831    {
832      delete[] tmpFileName;
833      return false;
834    }
835  }
836  else
837  {
838    delete[] tmpFileName;
839    return false;
840  }
841}
842
843/**
844 * touches a File on the disk (thereby creating it)
845 * @param fileName The file to touch
846*/
847bool ResourceManager::touchFile(const char* fileName)
848{
849  char* tmpName = ResourceManager::homeDirCheck(fileName);
850  if (tmpName == NULL)
851    return false;
852  FILE* stream;
853  if( (stream = fopen (tmpName, "w")) == NULL)
854  {
855    PRINTF(1)("could not open %s fro writing\n", fileName);
856    delete[] tmpName;
857    return false;
858  }
859  fclose(stream);
860
861  delete[] tmpName;
862}
863
864/**
865 * deletes a File from disk
866 * @param fileName the File to delete
867*/
868bool ResourceManager::deleteFile(const char* fileName)
869{
870  if (fileName == NULL)
871    return false;
872  char* tmpName = ResourceManager::homeDirCheck(fileName);
873  unlink(tmpName);
874  delete[] tmpName;
875}
876
877/**
878 * @param name the Name of the file to check
879 * @returns The name of the file, including the HomeDir
880 * IMPORTANT: this has to be deleted from the outside
881 */
882char* ResourceManager::homeDirCheck(const char* name)
883{
884  if (name == NULL)
885    return NULL;
886  char* retName;
887  if (!strncmp(name, "~/", 2))
888  {
889    char tmpFileName[500];
890#ifdef __WIN32__
891    strcpy(tmpFileName, getenv("USERPROFILE"));
892#else
893    strcpy(tmpFileName, getenv("HOME"));
894#endif
895    retName = new char[strlen(tmpFileName)+strlen(name)];
896    sprintf(retName, "%s%s", tmpFileName, name+1);
897  }
898  else
899  {
900    retName = new char[strlen(name)+1];
901    strcpy(retName, name);
902  }
903  return retName;
904}
905
906/**
907 * @param fileName the Name of the File to check
908 * @returns The full name of the file, including the DataDir, and NULL if the file does not exist
909 * !!IMPORTANT: this has to be deleted from the outside!!
910*/
911char* ResourceManager::getFullName(const char* fileName)
912{
913  if (fileName == NULL || ResourceManager::getInstance()->getDataDir() == NULL)
914    return NULL;
915
916  char* retName = new char[strlen(ResourceManager::getInstance()->getDataDir())
917                           + strlen(fileName) + 1];
918  sprintf(retName, "%s%s", ResourceManager::getInstance()->getDataDir(), fileName);
919  if (ResourceManager::isFile(retName) || ResourceManager::isDir(retName))
920    return retName;
921  else
922  {
923    delete[] retName;
924    return NULL;
925  }
926}
927
928
929/**
930 * checks wether a file is in the DataDir.
931 * @param fileName the File to check if it is in the Data-Dir structure.
932 * @returns true if the file exists, false otherwise
933 */
934bool ResourceManager::isInDataDir(const char* fileName)
935{
936  if (fileName == NULL || ResourceManager::getInstance()->getDataDir() == NULL)
937    return false;
938
939  bool retVal = false;
940  char* checkFile = new char[strlen(ResourceManager::getInstance()->getDataDir())
941                             + strlen(fileName) + 1];
942  sprintf(checkFile, "%s%s", ResourceManager::getInstance()->getDataDir(), fileName);
943
944  if (ResourceManager::isFile(checkFile) || ResourceManager::isDir(checkFile))
945    retVal = true;
946  else
947    retVal = false;
948  delete[] checkFile;
949  return retVal;
950}
951
952
953/**
954 * outputs debug information about the ResourceManager
955*/
956void ResourceManager::debug() const
957{
958  PRINT(0)("=RM===================================\n");
959  PRINT(0)("= RESOURCE-MANAGER DEBUG INFORMATION =\n");
960  PRINT(0)("======================================\n");
961  // if it is not initialized
962  PRINT(0)(" Reference is: %p\n", ResourceManager::singletonRef);
963  PRINT(0)(" Data-Directory is: %s\n", this->dataDir);
964  PRINT(0)(" List of Image-Directories: ");
965  std::vector<char*>::const_iterator imageDir;
966  for (imageDir = this->imageDirs.begin(); imageDir != this->imageDirs.end(); imageDir++)
967    PRINT(0)("%s ", (*imageDir));
968  PRINT(0)("\n");
969
970  PRINT(0)("List of all stored Resources:\n");
971  std::vector<Resource*>::const_iterator resource;
972  for (resource = this->resourceList.begin(); resource != this->resourceList.end(); resource++)
973
974  {
975    PRINT(0)("-----------------------------------------\n");
976    PRINT(0)("Name: %s; References: %d; Type: %s ", (*resource)->name, (*resource)->count, ResourceManager::ResourceTypeToChar((*resource)->type));
977
978    PRINT(0)("gets deleted at ");
979    switch((*resource)->prio)
980    {
981    default:
982    case RP_NO:
983      PRINT(0)("first posibility (0)\n");
984      break;
985    case RP_LEVEL:
986      PRINT(0)("the end of the Level (1)\n");
987      break;
988    case RP_CAMPAIGN:
989      PRINT(0)("the end of the campaign (2)\n");
990      break;
991    case RP_GAME:
992      PRINT(0)("when leaving the game (3)\n");
993      break;
994    }
995  }
996
997
998
999  PRINT(0)("==================================RM==\n");
1000}
1001
1002
1003/**
1004 * converts a ResourceType into the corresponding String
1005 * @param type the ResourceType to translate
1006 * @returns the converted String.
1007 */
1008const char* ResourceManager::ResourceTypeToChar(ResourceType type)
1009{
1010  return ResourceManager::resourceNames[type];
1011}
1012
1013/**
1014 * @brief converts a String into a ResourceType (good for loading)
1015 * @param resourceType the name of the Type
1016 * @returns the Number of the Type, or 0 (defautl) if not found.
1017 */
1018ResourceType ResourceManager::stringToResourceType(const char* resourceType)
1019{
1020  assert(resourceType != NULL);
1021  for (unsigned int i = 0; i < RESOURCE_TYPE_SIZE; i++)
1022    if (!strcmp(resourceType, ResourceManager::resourceNames[i]))
1023      return (ResourceType)i;
1024  return (ResourceType)0;
1025}
1026
1027/**
1028 * The Names of the ResourceTypes
1029 */
1030const char* ResourceManager::resourceNames[] =
1031{
1032#ifndef NO_MODEL
1033  "ObjectModel",
1034  "PrimitiveModel",
1035  "MD2-Data",
1036#endif
1037#ifndef NO_TEXTURES
1038  "Texture",
1039#endif
1040#ifndef NO_AUDIO
1041  "Sound",
1042  "Music",
1043#endif
1044#ifndef NO_TEXT
1045  "Font",
1046#endif
1047#ifndef NO_SHADERS
1048  "Shader",
1049#endif
1050};
Note: See TracBrowser for help on using the repository browser.