Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/levelloader/src/levelfactory.cc @ 3496

Last change on this file since 3496 was 3496, checked in by chris, 19 years ago

orxonox/branches/levelloader: Finished implementation of LevelFactory and associated, only thing left to do is testing

File size: 5.4 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Christian Meyer
15   co-programmer: ...
16*/
17
18
19#include "levelfactory.h"
20
21using namespace std;
22
23/*  --------------------------------------------------
24*               LevelFactory
25*   --------------------------------------------------
26*/
27
28LevelFactory* LevelFactory::singletonRef = NULL;
29
30LevelFactory* LevelFactory::getInstance ()
31{
32  if (singletonRef == NULL)
33    singletonRef = new LevelFactory();
34  return singletonRef;
35}
36
37/**
38   \brief loads a level from an XMLFile and feeds it into the world
39   \param filename the XML file to be parsed
40 
41*/
42int LevelFactory::loadXMLFile( char* filename)
43{
44        TiXMLDocument* XMLDoc = new TiXMLDocument( filename);
45        // load the level document
46        if( !XMLDoc.LoadFile())
47        {
48                // report an error
49                PRINTF(ERR)("Error loading XML File: %s @ %d:%d\n", XMLDoc.ErrorDesc(), XMLDoc.ErrorRow(), XMLDoc.ErrorCol());
50                delete XMLDoc;
51                return -1;
52        }
53       
54        // get orxonox simpleton
55        Orxonox* orx = Orxonox::getInstance();
56
57        // find the world
58        World world = orx->getWorld;
59       
60        // check basic validity
61        TiXMLElement* element = XMLDoc.RootElement();
62        TiXMLNode* comment = element->FirstChild( COMMENT);
63       
64        if( comment == NULL || ( !strcmp( comment->Value(), "OrxoLev")))
65        {
66                // report an error
67                PRINTF(ERR)("Specified XML File is not an orxonox data file (OrxoLev comment missing)\n");
68                delete XMLDoc;
69                return -1;
70        }
71       
72        // start loading objects into world
73        loadFromXMLElement( element), world, NULL);
74       
75        // free the XML data
76        delete XMLDoc;
77}
78
79/**
80   \brief recursive XML document parsing and loading function
81   \param root the XML Element to be parsed
82   \param world the world where the loaded objects shall be spawned
83   \param parent the object that is parent to all objects in current element
84*/
85
86void loadFromXMLElement( TiXMLElement* root, World* world, BaseObject* parent)
87{
88        TiXMLElement *child, *sibling;
89        BaseObject* object;
90        LoadParameters* data;
91        void* data;
92
93        if( root == NULL)
94        {
95                PRINTF(ERR)("LevelFactory tried to load from a NULL element\n");
96                return;
97        }
98
99        // load root first
100               
101                // check for LevelFactory integrity
102        if( first == NULL)
103        {
104                PRINTF(ERR)("LevelFactory does not know any ObjectFactories, loading not possible\n");
105                return;
106        }
107       
108                // gather & compile attributes
109        data = new LoadParameters( root);
110       
111                // load the object
112        object = first->load( root->Value(), data);
113       
114                // get rid of parameters
115        delete data;
116       
117        if( object != NULL)
118        {
119                // set parent
120       
121                // spawn object
122                world->spawn( object);
123                PRINTF(INFO)("Successfully loaded a '%s'\n", root->value());
124        }
125        else
126        {
127                PRINTF(ERR)("No ObjectFactory found to load '%s'\n", root->value())
128        }
129       
130        // walk children
131        child = root->FirstChildElement();
132        if( child != NULL) loadFromXMLElement( child, world, object);
133       
134        // siblings third
135        sibling = root->NextSiblingElement();
136        if( sibling != NULL) loadFromXMLElement( sibling, world, parent);
137}
138
139/**
140   \brief constructor
141   
142   set everything to zero
143*/
144LevelFactory::LevelFactory () 
145{
146        // clear the Factory Q
147   first = NULL;
148}
149
150/**
151   \brief deconstructor
152   
153   kills the Q and the singletonRef
154*/
155LevelFactory::LevelFactory ()
156{
157        singletonRef = NULL;
158        delete first;
159}
160
161/**
162   \brief register an ObjectFactory to the LevelFactory
163   \param factory an ObjectFactory to be registered
164*/
165void LevelFactory::registerFactory( ObjectFactory* factory)
166{
167                // just to see whether it works
168        PRINTF(INFO)("'%s' registered to LevelFactory\n", factory->getClassname());
169        if( first == NULL) first = factory;
170        else first->registerFactory( factory);
171}
172
173/*  --------------------------------------------------
174*               ObjectFactory
175*   --------------------------------------------------
176*/
177
178/**
179   \brief constructor
180   
181   set everything to zero and define classname
182*/
183ObjectFactory::ObjectFactory ()
184{
185        classname = "NULL"
186        next = NULL;
187}
188
189/**
190   \brief constructor
191   
192   clear the Q
193*/
194ObjectFactory::~ObjectFactory ()
195{
196        delete next;
197}
198
199/**
200   \brief used to run through the Q to find a factory that can load the specified object
201*/
202BaseObject* ObjectFactory::loadObject( char* name, void* data)
203{
204        if( !strcmp( name, classname)) return fabricateObject( data);
205        else if( next != NULL) return next->loadObject( name, data);
206        else return NULL;
207}
208
209/**
210   \brief generates the associated object from data
211*/
212BaseObject* ObjectFactory::fabricateObject( void* data)
213{
214        return NULL;
215}
216       
217/**
218   \brief add an ObjectFactory to the ObjectFactory Q
219   \param factory an ObjectFactory to be registered
220*/
221void ObjectFactory::registerFactory( ObjectFactory* factory)
222{
223        if( next == NULL) next = factory;
224        else next->registerFactory( factory);
225}
226
227/**
228   \brief make this particular factory known to the LevelFactory
229*/
230void ObjectFactory::initialize()
231{
232        LevelFactory* fct = LevelFactory::getInstance();
233        fct.registerFactory( this);
234}
235
236/*  --------------------------------------------------
237*                       LoadParameters
238*   --------------------------------------------------
239*/
240       
241const char* LoadParameters::grabParameter( const char* name)
242{
243        return root->Attribute( name);
244}
245
246const char* LoadParameters::grabParameter( const char* name, int* i)
247{
248        return root->Attribute( name, i);
249}
250
251const char* LoadParameters::grabParameter( const char* name, double* d)
252{
253        return root->Attribute( name, d);
254}
Note: See TracBrowser for help on using the repository browser.