Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: changed all getInstances into inline functions to save some (minor) time

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