Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core2/src/orxonox/core/Loader.cc @ 878

Last change on this file since 878 was 878, checked in by landauf, 16 years ago

added boolean bApplyLoaderMask to the XMLPortObject macro to determine whether the ClassTreeMask from the Loader should be applied or not (the idea is: objects included in excluded objects are excluded too, no matter what the mask sais. but objects included in a namespace or directly in a level-file are filtered by the mask.)

File size: 5.4 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      Fabian 'x3n' Landau
23 *   Co-authors:
24 *      ...
25 *
26 */
27
28#include "Loader.h"
29#include "Level.h"
30#include "BaseObject.h"
31#include "Identifier.h"
32#include "Iterator.h"
33#include "Debug.h"
34#include "CoreIncludes.h"
35#include "Namespace.h"
36
37#include "util/tinyxml/ticpp.h"
38
39namespace orxonox
40{
41    std::vector<std::pair<const Level*, ClassTreeMask> > Loader::levels_s;
42    ClassTreeMask Loader::currentMask_s;
43
44    bool Loader::open(const Level* level, const ClassTreeMask& mask)
45    {
46        Loader::add(level, mask);
47        return Loader::load(level, mask);
48    }
49
50    void Loader::close()
51    {
52        Loader::unload();
53        Loader::levels_s.clear();
54    }
55
56    void Loader::close(const Level* level)
57    {
58        Loader::unload(level);
59        Loader::remove(level);
60    }
61
62    void Loader::add(const Level* level, const ClassTreeMask& mask)
63    {
64        Loader::levels_s.insert(Loader::levels_s.end(), std::pair<const Level*, ClassTreeMask>(level, mask));
65    }
66
67    void Loader::remove(const Level* level)
68    {
69        for (std::vector<std::pair<const Level*, ClassTreeMask> >::iterator it = Loader::levels_s.begin(); it != Loader::levels_s.end(); ++it)
70        {
71            if ((*it).first == level)
72            {
73                Loader::levels_s.erase(it);
74                break;
75            }
76        }
77    }
78
79    bool Loader::load(const ClassTreeMask& mask)
80    {
81        bool success = true;
82        for (std::vector<std::pair<const Level*, ClassTreeMask> >::iterator it = Loader::levels_s.begin(); it != Loader::levels_s.end(); ++it)
83            if (!Loader::load((*it).first, (*it).second * mask))
84                success = false;
85
86        return success;
87    }
88
89    void Loader::unload(const ClassTreeMask& mask)
90    {
91        for (Iterator<BaseObject> it = ObjectList<BaseObject>::begin(); it; )
92        {
93            if (mask.isIncluded(it->getIdentifier()))
94                delete (*(it++));
95            else
96                ++it;
97        }
98    }
99
100    bool Loader::reload(const ClassTreeMask& mask)
101    {
102        Loader::unload(mask);
103        return Loader::load(mask);
104    }
105
106    bool Loader::load(const Level* level, const ClassTreeMask& mask)
107    {
108        Loader::currentMask_s = level->getMask() * mask;
109
110        try
111        {
112            COUT(0) << "Start loading " << level->getFile() << "..." << std::endl;
113            COUT(3) << "Mask: " << Loader::currentMask_s << std::endl;
114
115            ticpp::Document xmlfile(level->getFile());
116            xmlfile.LoadFile();
117
118            for (ticpp::Iterator<ticpp::Element> child = xmlfile.FirstChildElement(false); child != child.end(); child++)
119            {
120                Identifier* identifier = ID(child->Value());
121                if (identifier)
122                {
123                    if (identifier->isA(Class(Namespace)) || Loader::currentMask_s.isIncluded(identifier))
124                    {
125                        COUT(4) << "  fabricating " << child->Value() << "..." << std::endl;
126                        BaseObject* newObject = identifier->fabricate();
127                        newObject->setLoaderIndentation("    ");
128                        newObject->setLevel(level);
129                        newObject->XMLPort(*child, true);
130                        COUT(5) << "  ...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl;
131                    }
132                }
133                else
134                {
135                    COUT(2) << "  Warning: '" << child->Value() << "' is not a valid classname." << std::endl;
136                }
137            }
138
139            COUT(0) << "Finished loading " << level->getFile() << "." << std::endl;
140
141            return true;
142        }
143        catch(ticpp::Exception& ex)
144        {
145            COUT(1) << std::endl;
146            COUT(1) << "An error occurred in Loader.cc while loading " << level->getFile() << ":" << std::endl;
147            COUT(1) << ex.what() << std::endl;
148            COUT(1) << "Loading aborted." << std::endl;
149            return false;
150        }
151    }
152
153    void Loader::unload(const Level* level, const ClassTreeMask& mask)
154    {
155        for (Iterator<BaseObject> it = ObjectList<BaseObject>::begin(); it; )
156        {
157            if ((it->getLevel() == level) && mask.isIncluded(it->getIdentifier()))
158                delete (*(it++));
159            else
160                ++it;
161        }
162    }
163
164    bool Loader::reload(const Level* level, const ClassTreeMask& mask)
165    {
166        Loader::unload(level, mask);
167        return Loader::load(level, mask);
168    }
169}
Note: See TracBrowser for help on using the repository browser.