Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/std/src/lib/util/loading/resource_manager.cc @ 7209

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

orxonox/std: less evil

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