Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/lib/util/loading/resource_manager.cc @ 9715

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

renamed newclassid to classid and newobjectlist to objectlist

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