Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/qt_gui/src/lib/util/loading/resource_manager.cc @ 7612

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

File stuff started

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