Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core/src/orxonox/core/ClassTreeMask.cc @ 802

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

added new class "ClassTreeMask"

File size: 6.2 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 "ClassTreeMask.h"
29#include "Identifier.h"
30#include "BaseObject.h"
31
32namespace orxonox
33{
34    // ###############################
35    // ###    ClassTreeMaskNode    ###
36    // ###############################
37    ClassTreeMaskNode::ClassTreeMaskNode(const Identifier* subclass, bool bIncluded)
38    {
39        this->subclass_ = subclass;
40        this->bIncluded_ = bIncluded;
41    }
42
43    ClassTreeMaskNode::~ClassTreeMaskNode()
44    {
45        for (std::list<ClassTreeMaskNode*>::iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); )
46            delete (*(it++));
47    }
48
49    void ClassTreeMaskNode::include()
50    {
51        this->bIncluded_ = true;
52    }
53
54    void ClassTreeMaskNode::exclude()
55    {
56        this->bIncluded_ = false;
57    }
58
59    void ClassTreeMaskNode::setIncluded(bool bIncluded)
60    {
61        this->bIncluded_ = bIncluded;
62    }
63
64    void ClassTreeMaskNode::addSubnode(ClassTreeMaskNode* subnode)
65    {
66        this->subnodes_.insert(this->subnodes_.end(), subnode);
67    }
68
69    bool ClassTreeMaskNode::isIncluded() const
70    {
71        return this->bIncluded_;
72    }
73
74    bool ClassTreeMaskNode::isExcluded() const
75    {
76        return (!this->bIncluded_);
77    }
78
79    const Identifier* ClassTreeMaskNode::getClass() const
80    {
81        return this->subclass_;
82    }
83
84
85    // ###############################
86    // ###      ClassTreeMask      ###
87    // ###############################
88    ClassTreeMask::ClassTreeMask()
89    {
90        this->root_ = new ClassTreeMaskNode(ClassIdentifier<BaseObject>::getIdentifier(), true);
91    }
92
93    ClassTreeMask::~ClassTreeMask()
94    {
95        delete this->root_;
96    }
97
98    void ClassTreeMask::include(const Identifier* subclass)
99    {
100        this->add(subclass, true);
101    }
102
103    void ClassTreeMask::exclude(const Identifier* subclass)
104    {
105        this->add(subclass, false);
106    }
107
108    void ClassTreeMask::add(const Identifier* subclass, bool bInclude)
109    {
110        this->add(this->root_, subclass, bInclude);
111    }
112
113    void ClassTreeMask::add(ClassTreeMaskNode* node, const Identifier* subclass, bool bInclude)
114    {
115        // Check if the current node contains exactly the subclass we want to add
116        if (subclass == node->getClass())
117        {
118            // We're at the right place, just change the mask and return
119            node->setIncluded(bInclude);
120            return;
121        }
122        else
123        {
124            // Search for an already existing node, containing the subclass we want to add
125            for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); ++it)
126            {
127                if (subclass->isA((*it)->getClass()))
128                {
129                    // We've found an existing node -> delegate the work and return
130                    this->add(*it, subclass, bInclude);
131                    return;
132                }
133            }
134
135            // There is no existing node satisfying our needs -> we create a new node
136            ClassTreeMaskNode* newnode = new ClassTreeMaskNode(subclass, bInclude);
137
138            // Search for nodes that should actually be subnodes of our new node
139            for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); )
140            {
141                if ((*it)->getClass()->isChildOf(subclass))
142                {
143                    // We've found a subnode: add it to the new node an erase it from the current node
144                    newnode->addSubnode(*it);
145                    node->subnodes_.erase(it++);
146                }
147                else
148                {
149                    ++it;
150                }
151            }
152
153            // Finally add the new node as a subnode to the current node
154            node->addSubnode(newnode);
155        }
156    }
157
158    void ClassTreeMask::reset()
159    {
160        delete this->root_;
161        this->root_ = new ClassTreeMaskNode(ClassIdentifier<BaseObject>::getIdentifier(), true);
162    }
163
164    bool ClassTreeMask::isIncluded(const Identifier* subclass)
165    {
166        return this->isIncluded(this->root_, subclass);
167    }
168
169    bool ClassTreeMask::isIncluded(ClassTreeMaskNode* node, const Identifier* subclass)
170    {
171        // Check if the searched subclass is of the same type as the class in the current node or a derivative
172        if (subclass->isA(node->getClass()))
173        {
174            // Check for the special case
175            if (subclass == node->getClass())
176                return node->isIncluded();
177
178            // Go through the list of subnodes and look for a node containing the searched subclass
179            for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); ++it)
180                if (subclass->isA((*it)->getClass()))
181                    return isIncluded(*it, subclass);
182
183            // There is no subnode containing our class -> the rule of the current node takes in effect
184            return node->isIncluded();
185        }
186        else
187        {
188            // The class is not included in the mask: return false
189            return false;
190        }
191    }
192
193    bool ClassTreeMask::isExcluded(const Identifier* subclass)
194    {
195        return (!this->isIncluded(subclass));
196    }
197}
Note: See TracBrowser for help on using the repository browser.