Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: doxytag

File size: 21.1 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: Patrick Boenzli
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
17
18#include "resource_manager.h"
19
20// different resource Types
21#include "objModel.h"
22#include "primitive_model.h"
23#include "md2Model.h"
24#include "texture.h"
25#include "text_engine.h"
26
27#include "list.h"
28#include "sdlincl.h"
29
30// File Handling Includes
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <unistd.h>
34
35using namespace std;
36
37/**
38   \brief standard constructor
39*/
40ResourceManager::ResourceManager () 
41{
42   this->setClassID(CL_RESOURCE_MANAGER, "ResourceManager");
43   this->dataDir = NULL;
44   this->setDataDir("./");
45   this->imageDirs = new tList<char>();
46   this->resourceList = new tList<Resource>();
47}
48
49/**
50   \returns the Instance to this ResourceManager
51*/
52ResourceManager* ResourceManager::getInstance(void)
53{
54  if (!ResourceManager::singletonRef)
55    ResourceManager::singletonRef = new ResourceManager();
56  return ResourceManager::singletonRef;
57}
58
59//! Singleton Reference to the ResourceManager
60ResourceManager* ResourceManager::singletonRef = NULL;
61
62/**
63   \brief standard destructor
64*/
65ResourceManager::~ResourceManager (void) 
66{
67  // deleting the Resources-List
68  this->unloadAllByPriority(RP_GAME);
69  delete this->resourceList;
70  // deleting the Directorie Lists
71  tIterator<char>* tmpIt = imageDirs->getIterator();
72  char* tmpDir = tmpIt->nextElement();
73  while(tmpDir)
74    {
75      delete []tmpDir;
76      tmpDir = tmpIt->nextElement();
77    }
78  delete tmpIt;
79
80  delete this->imageDirs;
81
82  ResourceManager::singletonRef = NULL;
83}
84
85/**
86   \brief sets the data main directory
87   \param dataDir the DataDirectory.
88*/
89bool ResourceManager::setDataDir(const char* dataDir)
90{
91  char* realDir = ResourceManager::homeDirCheck(dataDir);
92  if (isDir(realDir))
93    {
94      delete this->dataDir;
95      this->dataDir = new char[strlen(realDir)+1];
96      strcpy(this->dataDir, realDir);
97      delete realDir;
98      return true;
99    }
100  else
101    {
102      PRINTF(1)("%s is not a Directory, and can not be the Data Directory, leaving as %s \n", dataDir, this->dataDir);
103      delete realDir;
104      return false;
105    }
106}
107
108/**
109   \brief checks for the DataDirectory, by looking if
110   \param fileInside is inisde??
111*/
112bool ResourceManager::checkDataDir(const char* fileInside)
113{
114  bool retVal;
115  if (!isDir(this->dataDir))
116    {
117      PRINTF(1)("%s is not a directory\n", this->dataDir);
118      return false;
119    }
120 
121  char* testFile = new char[strlen(this->dataDir)+strlen(fileInside)+1];
122  sprintf(testFile, "%s%s", this->dataDir, fileInside);
123  retVal = isFile(testFile);
124  delete testFile;
125  return retVal;
126}
127
128/**
129   \brief adds a new Path for Images
130   \param imageDir The path to insert
131   \returns true, if the Path was well and injected (or already existent within the list)
132   false otherwise
133*/
134bool ResourceManager::addImageDir(const char* imageDir)
135{
136  // check if the param is a Directory
137  if (isDir(imageDir))
138    {
139      // check if the Directory has been added before
140      tIterator<char>* tmpImageDirs = imageDirs->getIterator();
141      char* tmpDir = tmpImageDirs->nextElement();
142      while(tmpDir)
143        {
144          if (!strcmp(tmpDir, imageDir))
145            {
146              PRINTF(4)("Path %s already loaded\n", imageDir);
147              delete tmpImageDirs;
148              return true;
149            }
150          tmpDir = tmpImageDirs->nextElement();
151        }
152      delete tmpImageDirs;
153
154      // adding the directory to the List
155      tmpDir  = new char[strlen(imageDir)+1];
156      strcpy(tmpDir, imageDir);
157      this->imageDirs->add(tmpDir);
158      return true;
159    }
160  else
161    {
162      PRINTF(1)("%s is not a Directory, and can not be added to the Paths of Images\n", dataDir);
163      return false;
164    }
165}
166
167/**
168   \brief loads resources
169   \param fileName: The fileName of the resource to load
170   \param prio: The ResourcePriority of this resource (will only be increased)
171   \param param1: an additional option to parse (see the constuctors for more help)
172   \param param2: an additional option to parse (see the constuctors for more help)
173   \param param3: an additional option to parse (see the constuctors for more help)
174   \returns a pointer to a desired Resource.
175*/
176void* ResourceManager::load(const char* fileName, ResourcePriority prio, void* param1, void* param2, void* param3)
177{
178  ResourceType tmpType;
179
180  if (!strncmp(fileName+(strlen(fileName)-4), ".obj", 4))
181    tmpType = OBJ;
182  if (!strncmp(fileName+(strlen(fileName)-4), ".md2", 4))
183    tmpType = MD2;
184  else if (!strncmp(fileName+(strlen(fileName)-4), ".wav", 4))
185    tmpType = WAV;
186  else if (!strncmp(fileName+(strlen(fileName)-4), ".mp3", 4))
187    tmpType = MP3;
188  else if (!strncmp(fileName+(strlen(fileName)-4), ".ogg", 4))
189    tmpType = OGG;
190  else if (!strcmp(fileName, "cube") ||
191           !strcmp(fileName, "sphere") ||
192           !strcmp(fileName, "plane") ||
193           !strcmp(fileName, "cylinder") ||
194           !strcmp(fileName, "cone"))
195    tmpType = PRIM;
196  else if (!strncmp(fileName+(strlen(fileName)-4), ".ttf", 4))
197    tmpType = TTF;
198  else 
199    tmpType = IMAGE;
200
201  return this->load(fileName, tmpType, prio, param1, param2, param3);
202}
203
204/**
205   \brief loads resources
206   \param fileName: The fileName of the resource to load
207   \param type: The Type of Resource to load (\see ResourceType)
208   \param prio: The ResourcePriority of this resource (will only be increased)
209   \param param1: an additional option to parse (see the constuctors for more help)
210   \param param2: an additional option to parse (see the constuctors for more help)
211   \param param3: an additional option to parse (see the constuctors for more help)
212   \returns a pointer to a desired Resource.
213*/
214void* ResourceManager::load(const char* fileName, ResourceType type, ResourcePriority prio,
215                            void* param1, void* param2, void* param3)
216{
217  // searching if the resource was loaded before.
218  Resource* tmpResource = this->locateResourceByInfo(fileName, type, param1, param2,param3);
219  if (tmpResource) // if the resource was loaded before.
220    {
221      PRINTF(4)("not loading cached resource %s\n", tmpResource->name);
222      tmpResource->count++;
223      if(tmpResource->prio < prio)
224        tmpResource->prio = prio;
225    }
226  else
227    {
228      char* tmpDir;
229      // Setting up the new Resource
230      tmpResource = new Resource;
231      tmpResource->count = 1;
232      tmpResource->type = type;
233      tmpResource->prio = prio;
234      tmpResource->pointer = NULL;
235      tmpResource->name = new char[strlen(fileName)+1];
236      strcpy(tmpResource->name, fileName);
237
238      // creating the full name. (directoryName + FileName)
239      char* fullName = ResourceManager::getFullName(fileName);
240      // Checking for the type of resource \see ResourceType
241      switch(type)
242        {
243        case OBJ:
244          if (param1)
245            tmpResource->modelSize = *(float*)param1;
246          else
247            tmpResource->modelSize = 1.0;
248
249          if(ResourceManager::isFile(fullName))
250            tmpResource->pointer = new OBJModel(fullName, tmpResource->modelSize);
251          else
252            {
253              PRINTF(2)("Sorry, %s does not exist. Loading a cube-Model instead\n", fullName);
254              tmpResource->pointer = ResourceManager::load("cube", PRIM, prio, &tmpResource->modelSize);
255            }
256          break;
257        case PRIM:
258          if (param1)
259            tmpResource->modelSize = *(float*)param1;
260          else
261            tmpResource->modelSize = 1.0;
262
263          if (!strcmp(tmpResource->name, "cube"))
264            tmpResource->pointer = new PrimitiveModel(PRIM_CUBE, tmpResource->modelSize);
265          else if (!strcmp(tmpResource->name, "sphere"))
266            tmpResource->pointer = new PrimitiveModel(PRIM_SPHERE, tmpResource->modelSize);
267          else if (!strcmp(tmpResource->name, "plane"))
268            tmpResource->pointer = new PrimitiveModel(PRIM_PLANE, tmpResource->modelSize);
269          else if (!strcmp(tmpResource->name, "cylinder"))
270            tmpResource->pointer = new PrimitiveModel(PRIM_CYLINDER, tmpResource->modelSize);
271          else if (!strcmp(tmpResource->name, "cone"))
272            tmpResource->pointer = new PrimitiveModel(PRIM_CONE, tmpResource->modelSize);
273          break;
274        case MD2:
275          if(ResourceManager::isFile(fullName))
276            {
277              if (param1)
278                {
279                  tmpResource->skinFileName = new char[strlen((const char*)param1)+1];
280                  strcpy(tmpResource->skinFileName, (const char*) param1);
281                }
282              else
283                tmpResource->skinFileName = NULL;
284              tmpResource->pointer = new MD2Data(fullName, tmpResource->skinFileName);
285            }
286              break;
287        case TTF:
288            if (param1)
289              tmpResource->ttfSize = *(int*)param1;
290            else
291              tmpResource->ttfSize = FONT_DEFAULT_SIZE;
292            if (param2)
293              {
294                Vector* tmpVec = (Vector*)param2;
295                tmpResource->ttfColorR = (int)tmpVec->x;
296                tmpResource->ttfColorG = (int)tmpVec->y;
297                tmpResource->ttfColorB = (int)tmpVec->z;
298              }
299            else
300              {
301                tmpResource->ttfColorR = FONT_DEFAULT_COLOR_R;
302                tmpResource->ttfColorG = FONT_DEFAULT_COLOR_G;
303                tmpResource->ttfColorB = FONT_DEFAULT_COLOR_B;
304              }
305           
306          if(isFile(fullName))
307            tmpResource->pointer = new Font(fullName,
308                                            tmpResource->ttfSize,
309                                            tmpResource->ttfColorR,
310                                            tmpResource->ttfColorG,
311                                            tmpResource->ttfColorB);
312          else
313            PRINTF(2)("Sorry, %s does not exist. Not loading Font\n", fullName);
314          break;
315        case IMAGE:
316          if(isFile(fullName))
317            {
318              PRINTF(4)("Image %s resides to %s\n", fileName, fullName);
319              tmpResource->pointer = new Texture(fullName);
320            }
321          else
322            {
323              tIterator<char>* iterator = imageDirs->getIterator();
324              tmpDir = iterator->nextElement();
325              //tmpDir = imageDirs->enumerate();
326              while(tmpDir)
327                {
328                  char* imgName = new char[strlen(tmpDir)+strlen(fileName)+1];
329                  sprintf(imgName, "%s%s", tmpDir, fileName);
330                  if(isFile(imgName))
331                    {
332                      PRINTF(4)("Image %s resides to %s\n", fileName, imgName);
333                      tmpResource->pointer = new Texture(imgName);
334                      delete []imgName;
335                      break;
336                    }
337                  delete []imgName;
338                  tmpDir = iterator->nextElement();
339                }
340              delete iterator;
341            }
342          if(!tmpResource)
343             PRINTF(2)("!!Image %s not Found!!\n", fileName);
344          break;
345        default:
346          tmpResource->pointer = NULL;
347          PRINTF(1)("No type found for %s.\n   !!This should not happen unless the Type is not supported yet.!!\n", tmpResource->name);
348          break;
349        }
350      if (tmpResource->pointer)
351        this->resourceList->add(tmpResource);
352      delete []fullName;
353    }
354  if (tmpResource->pointer)
355    return tmpResource->pointer;
356  else 
357    {
358      PRINTF(2)("Resource %s could not be loaded\n", fileName);
359      delete tmpResource;
360      return NULL;
361    }
362}
363
364/**
365   \brief unloads a Resource
366   \param pointer: The pointer to free
367   \param prio: the PriorityLevel to unload this resource
368   \returns true if successful (pointer found, and deleted), false otherwise
369*/
370bool ResourceManager::unload(void* pointer, ResourcePriority prio)
371{
372  // if pointer is existent. and only one resource of this type exists.
373  Resource* tmpResource = this->locateResourceByPointer(pointer);
374  if (!tmpResource)
375    {
376      PRINTF(2)("Resource not Found %p\n", pointer);
377      return false;
378    }
379  else
380    unload(tmpResource, prio);
381}
382
383/**
384   \brief unloads a Resource
385   \param resource: The resource to unloade
386   \param prio the PriorityLevel to unload this resource
387*/
388bool ResourceManager::unload(Resource* resource, ResourcePriority prio)
389{
390  if (resource->count > 0)
391    resource->count--;
392  if (resource->prio <= prio)
393    {
394      if (resource->count <= 0)
395        {
396          // deleting the Resource
397          switch(resource->type)
398            {
399            case OBJ:
400            case PRIM:
401              delete (Model*)resource->pointer;
402              break;
403            case MD2:
404              delete (MD2Data*)resource->pointer;
405              break;
406            case IMAGE:
407              delete (Texture*)resource->pointer;
408              break;
409            case TTF:
410              delete (Font*)resource->pointer;
411              break;
412            default:
413              PRINTF(1)("NOT YET IMPLEMENTED !!FIX FIX!!\n");
414              return false;
415              break;
416            }
417          // deleting the List Entry:
418          PRINTF(4)("Resource %s safely removed.\n", resource->name);
419          delete []resource->name;
420          this->resourceList->remove(resource);
421        }
422      else
423        PRINTF(4)("Resource %s not removed, because there are still %d References to it.\n", resource->name, resource->count);
424    }
425  else
426    PRINTF(4)("not deleting resource %s because DeleteLevel to high\n", resource->name);
427  return true;
428}
429
430
431/**
432   \brief unloads all alocated Memory of Resources with a pririty lower than prio
433   \param prio The priority to delete
434*/
435bool ResourceManager::unloadAllByPriority(ResourcePriority prio)
436{
437  tIterator<Resource>* iterator = resourceList->getIterator();
438  Resource* enumRes = iterator->nextElement();
439  while (enumRes)
440    {
441      if (enumRes->prio <= prio)
442        if (enumRes->count == 0)
443          unload(enumRes, prio);
444        else
445          PRINTF(2)("unable to unload %s because there are still %d references to it\n",
446                   enumRes->name, enumRes->count);
447      //enumRes = resourceList->nextElement();
448      enumRes = iterator->nextElement();
449    }
450  delete iterator;
451}
452
453/**
454   \brief Searches for a Resource by some information
455   \param fileName: The name to look for
456   \param type the Type of resource to locate.
457   \param param1: an additional option to parse (see the constuctors for more help)
458   \param param2: an additional option to parse (see the constuctors for more help)
459   \param param3: an additional option to parse (see the constuctors for more help)
460   \returns a Pointer to the Resource if found, NULL otherwise.
461*/
462Resource* ResourceManager::locateResourceByInfo(const char* fileName, ResourceType type,
463                                                void* param1, void* param2, void* param3)
464{
465  //  Resource* enumRes = resourceList->enumerate();
466  tIterator<Resource>* iterator = resourceList->getIterator();
467  Resource* enumRes = iterator->nextElement();
468  while (enumRes)
469    {
470      if (enumRes->type == type && !strcmp(fileName, enumRes->name))
471        {
472          bool match = false;
473          bool subMatch = false;
474
475          switch (type)
476            {
477            case PRIM:
478            case OBJ:
479              if (!param1)
480                {
481                  if (enumRes->modelSize == 1.0)
482                    match = true;
483                }
484              else if (enumRes->modelSize == *(float*)param1)
485                match = true;
486              break;
487            case MD2:
488              if (!param1)
489                {
490                  if (enumRes->skinFileName == NULL)
491                    match = true;
492                }
493              else if (!strcmp(enumRes->skinFileName, (const char*) param1))
494                match = true;
495              break;
496            case TTF:
497              if (!param1)
498                {
499                  if (enumRes->ttfSize == FONT_DEFAULT_SIZE)
500                    subMatch = true;
501                }
502              else if (enumRes->modelSize =- *(int*)param1)
503                subMatch = true;
504              if(subMatch)
505                {
506                  Vector* tmpVec = (Vector*)param2;
507                  if (!param2)
508                    {
509                      if(enumRes->ttfColorR == FONT_DEFAULT_COLOR_R &&
510                         enumRes->ttfColorG == FONT_DEFAULT_COLOR_G &&
511                         enumRes->ttfColorB == FONT_DEFAULT_COLOR_B )
512                        match = true;
513                    }
514                  else if (enumRes->ttfColorR == (int)tmpVec->x &&
515                           enumRes->ttfColorG == (int)tmpVec->y &&
516                           enumRes->ttfColorB == (int)tmpVec->z )
517                    match = true;
518                }
519
520              break;
521            default:
522              match = true;
523              break;
524            }
525          if (match)
526            {
527              delete iterator;
528              return enumRes;
529            }
530        }
531      enumRes = iterator->nextElement();
532    }
533  delete iterator;
534  return NULL;
535}
536
537/**
538   \brief Searches for a Resource by Pointer
539   \param pointer the Pointer to search for
540   \returns a Pointer to the Resource if found, NULL otherwise.
541*/
542Resource* ResourceManager::locateResourceByPointer(const void* pointer)
543{
544  //  Resource* enumRes = resourceList->enumerate();
545  tIterator<Resource>* iterator = resourceList->getIterator();
546  Resource* enumRes = iterator->nextElement();
547  while (enumRes)
548    {
549      if (pointer == enumRes->pointer)
550        {
551          delete iterator;
552          return enumRes;
553        }
554      enumRes = iterator->nextElement();
555    }
556  delete iterator;
557  return NULL;
558}
559
560/**
561   \brief Checks if it is a Directory
562   \param directoryName the Directory to check for
563   \returns true if it is a directory/symlink false otherwise
564*/
565bool ResourceManager::isDir(const char* directoryName)
566{
567  if (directoryName == NULL)
568    return false;
569
570  char* tmpDirName = NULL;
571  struct stat status;
572
573  // checking for the termination of the string given. If there is a "/" at the end cut it away
574  if (directoryName[strlen(directoryName)-1] == '/')
575    {
576      tmpDirName = new char[strlen(directoryName)+1];
577      strncpy(tmpDirName, directoryName, strlen(directoryName)-1);
578      tmpDirName[strlen(directoryName)-1] = '\0';
579    }
580  else
581    {
582      tmpDirName = new char[strlen(directoryName)+1];
583      strcpy(tmpDirName, directoryName);
584    }
585
586  if(!stat(tmpDirName, &status))
587    {
588      if (status.st_mode & (S_IFDIR
589#ifndef __WIN32__
590                            | S_IFLNK
591#endif
592                            ))
593        {
594          delete tmpDirName;
595          return true;
596        }
597      else
598        {
599          delete tmpDirName;
600          return false;
601        }
602    }
603  else
604    return false;
605}
606
607/**
608   \brief Checks if the file is either a Regular file or a Symlink
609   \param fileName the File to check for
610   \returns true if it is a regular file/symlink, false otherwise
611*/
612bool ResourceManager::isFile(const char* fileName)
613{
614  if (fileName == NULL)
615    return false;
616  char* tmpFileName = ResourceManager::homeDirCheck(fileName);
617  // actually checks the File
618  struct stat status;
619  if (!stat(tmpFileName, &status))
620    {
621      if (status.st_mode & (S_IFREG
622#ifndef __WIN32__
623                            | S_IFLNK
624#endif
625                            ))
626        {
627          delete tmpFileName;
628          return true;
629        }
630      else
631        {
632          delete tmpFileName;
633          return false;
634        }
635    }
636  else 
637    {
638      delete tmpFileName;
639      return false;
640    }
641}
642
643/**
644   \brief touches a File on the disk (thereby creating it)
645   \param fileName The file to touch
646*/
647bool ResourceManager::touchFile(const char* fileName)
648{
649  char* tmpName = ResourceManager::homeDirCheck(fileName);
650  if (tmpName == NULL)
651    return false;
652  FILE* stream;
653  if( (stream = fopen (tmpName, "w")) == NULL)
654    {
655      PRINTF(1)("could not open %s fro writing\n", fileName);
656      return false;
657    }
658  fclose(stream);
659   
660  delete tmpName; 
661}
662
663/**
664   \brief deletes a File from disk
665   \param fileName the File to delete
666*/
667bool ResourceManager::deleteFile(const char* fileName)
668{
669  if (fileName == NULL)
670    return false;
671  char* tmpName = ResourceManager::homeDirCheck(fileName);
672  unlink(tmpName);
673  delete tmpName;
674}
675
676/**
677    \param name the Name of the file to check
678    \returns The name of the file, including the HomeDir
679    IMPORTANT: this has to be deleted from the outside
680*/
681char* ResourceManager::homeDirCheck(const char* name)
682{
683  if (name == NULL)
684    return NULL;
685  char* retName;
686  if (!strncmp(name, "~/", 2))
687    {
688      char tmpFileName[500];
689#ifdef __WIN32__
690      strcpy(tmpFileName, getenv("USERPROFILE"));
691#else
692      strcpy(tmpFileName, getenv("HOME"));
693#endif
694      retName = new char[strlen(tmpFileName)+strlen(name)];
695      sprintf(retName, "%s%s", tmpFileName, name+1);
696    }
697  else
698    {
699      retName = new char[strlen(name)+1];
700      strcpy(retName, name);
701    }
702  return retName;
703}
704
705/**
706    \param fileName the Name of the File to check
707    \returns The full name of the file, including the DataDir, and NULL if the file does not exist
708    IMPORTANT: this has to be deleted from the outside
709*/
710char* ResourceManager::getFullName(const char* fileName)
711{
712  if (fileName == NULL)
713    return NULL;
714
715  char* retName = new char[strlen(ResourceManager::getInstance()->getDataDir())
716                           + strlen(fileName) + 1];
717  sprintf(retName, "%s%s", ResourceManager::getInstance()->getDataDir(), fileName);
718  if (ResourceManager::isFile(retName) || ResourceManager::isDir(retName))
719    return retName;
720  else
721    {
722      delete retName;
723      return NULL;
724    }
725}
726
727
728/**
729   \brief outputs debug information about the ResourceManager
730*/
731void ResourceManager::debug(void)
732{
733  PRINT(0)("=RM===================================\n");
734  PRINT(0)("= RESOURCE-MANAGER DEBUG INFORMATION =\n");
735  PRINT(0)("======================================\n");
736  // if it is not initialized
737  PRINT(0)(" Reference is: %p\n", ResourceManager::singletonRef);
738  PRINT(0)(" Data-Directory is: %s\n", this->dataDir);
739  PRINT(0)(" List of Image-Directories: ");
740  tIterator<char>* tmpIt = imageDirs->getIterator();
741  char* tmpDir = tmpIt->nextElement();
742  while(tmpDir)
743    {
744      PRINT(0)("%s ",tmpDir);
745      tmpDir = tmpIt->nextElement();
746    }
747  delete tmpIt;
748  PRINT(0)("\n");
749
750  PRINT(0)("List of all stored Resources:\n");
751  tIterator<Resource>* iterator = resourceList->getIterator();
752  Resource* enumRes = iterator->nextElement();
753  while (enumRes)
754    {
755      PRINT(0)("-----------------------------------------\n");
756      PRINT(0)("Name: %s; References: %d; Type:", enumRes->name, enumRes->count);
757      switch (enumRes->type)
758        {
759        case OBJ:
760          PRINT(0)("ObjectModel\n");
761          break;
762        case PRIM:
763          PRINT(0)("PrimitiveModel\n");
764          break;
765        case IMAGE:
766          PRINT(0)("ImageFile (Texture)\n");
767          break;
768        default:
769          PRINT(0)("SoundFile\n");
770          break;
771        }
772      PRINT(0)("gets deleted at ");
773      switch(enumRes->prio)
774        {
775        default:
776        case RP_NO:
777          PRINT(0)("first posibility (0)\n");
778          break;
779        case RP_LEVEL:
780          PRINT(0)("the end of the Level (1)\n");
781          break;
782        case RP_CAMPAIGN:
783          PRINT(0)("the end of the campaign (2)\n");
784          break;
785        case RP_GAME:
786          PRINT(0)("when leaving the game (3)\n");
787          break;
788        }
789      enumRes = iterator->nextElement();
790    }
791  delete iterator;
792
793
794
795  PRINT(0)("==================================RM==\n");
796}
Note: See TracBrowser for help on using the repository browser.