Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: totally remastered the ResourceManager.
Now it takes MultiTypes instead of (void*) as parameters

  1. This is TypeSafe
  2. This is easier to use
  3. This makes much more sense, and is objectOriented

also made some minor adjustments to the MultiType, some comparisons

also fixed the loading in all the Other classes like material md2 and so on

File size: 28.3 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  switch (type)
1011  {
1012#ifndef NO_MODEL
1013  case OBJ:
1014    return "ObjectModel";
1015    break;
1016  case PRIM:
1017    return "PrimitiveModel";
1018    break;
1019  case MD2:
1020    return "MD2-Data";
1021    break;
1022#endif
1023#ifndef NO_TEXTURES
1024  case IMAGE:
1025    return "ImageFile (Texture)";
1026    break;
1027#endif
1028#ifndef NO_AUDIO
1029  case WAV:
1030    return "SoundFile";
1031    break;
1032  case OGG:
1033    return "MusicFile";
1034    break;
1035#endif
1036#ifndef NO_TEXT
1037  case TTF:
1038    return "Font (TTF)";
1039    break;
1040#endif
1041#ifndef NO_SHADERS
1042  case SHADER:
1043    return "Shader";
1044    break;
1045#endif
1046  default:
1047    return "unknown Format";
1048    break;
1049  }
1050}
Note: See TracBrowser for help on using the repository browser.