Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/core/ClassTreeMask.h @ 1049

Last change on this file since 1049 was 871, checked in by landauf, 17 years ago

merged core branch to trunk

File size: 9.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/**
29    @file ClassTreeMask.h
30    @brief Definition of the ClassTreeMask, ClassTreeMaskNode and ClassTreeMaskIterator classes.
31
32    ClassTreeMask is a class to define a mask of the class-tree beginning with BaseObject.
33    You can include or exclude classes by calling the corresponding functions with the
34    Identifier of the class.
35
36    You can work with a ClassTreeMask in the sense of the set-theory, meaning that you can create
37    unions, intersections, complements and differences by using overloaded operators.
38
39
40
41    The ClassTreeMask is internally represented by a tree. The nodes in the tree are
42    ClassTreeMaskNodes, containing the rule (included or excluded) for this class and all
43    subclasses and a list of all subnodes. To minimize the size, the tree contains only
44    nodes changing the mask. By adding new rules, the tree gets reordered dynamically.
45
46    Adding a new rule overwrites all rules assigned to inherited classes. Use overwrite = false
47    if you don't like this feature. Useless rules that don't change the information of the mask
48    aren't saved in the internal tree. Use clean = false if you wan't to save them.
49
50    With overwrite = false and clean = false it doesn't matter in which way you create the mask.
51    You can manually drop useless rules from the tree by calling clean().
52
53
54
55    Because of the complicated shape of the internal tree, there is an iterator to iterate
56    through all ClassTreeMaskNodes of a mask. It starts with the BaseObject and moves on to
57    the first subclass until it reaches a leaf of the tree. Then the iterator moves one step
58    back and iterates to the second subclass. If there are no more subclasses, it steps another
59    step back, and so on.
60
61    Example: A and B are childs of BaseObject, A1 and A2 are childs of A, B1 and B2 are childs of B.
62    The ClassTreeMaskIterator would move trough the tree in the following order:
63    BaseObject, A, A1, A2, B, B1, B2.
64
65    Note that the iterator doesn't move trough the whole class-tree, but only through the
66    internal tree of the mask, containing the minimal needed set of nodes to describe the mask.
67*/
68
69#ifndef _ClassTreeMask_H__
70#define _ClassTreeMask_H__
71
72#include <list>
73#include <stack>
74
75#include "CorePrereqs.h"
76
77namespace orxonox
78{
79    // ###############################
80    // ###    ClassTreeMaskNode    ###
81    // ###############################
82    //! The ClassTreeMaskNode is a node in the internal tree of the ClassTreeMask, containing the rules of the mask.
83    /**
84        The ClassTreeMaskNode is used to store the rule (included or excluded) for a given
85        class (described by the corresponding Identifier). The nodes are used in the internal
86        tree of ClassTreeMask. To build a tree, they store a list of all subnodes.
87    */
88    class _CoreExport ClassTreeMaskNode
89    {
90        friend class ClassTreeMask;
91        friend class ClassTreeMaskIterator;
92
93        public:
94            ClassTreeMaskNode(const Identifier* subclass, bool bIncluded = true);
95            ~ClassTreeMaskNode();
96
97            void include(bool overwrite = true);
98            void exclude(bool overwrite = true);
99            void setIncluded(bool bIncluded, bool overwrite = true);
100
101            void addSubnode(ClassTreeMaskNode* subnode);
102
103            bool isIncluded() const;
104            bool isExcluded() const;
105
106            const Identifier* getClass() const;
107
108        private:
109            void deleteAllSubnodes();
110
111            const Identifier* subclass_;                //!< The Identifier of the subclass the rule refers to
112            bool bIncluded_;                            //!< The rule: included or excluded
113            std::list<ClassTreeMaskNode*> subnodes_;    //!< A list containing all subnodes in the tree
114    };
115
116
117    // ###############################
118    // ###  ClassTreeMaskIterator  ###
119    // ###############################
120    //! The ClassTreeMaskIterator moves through all ClassTreeMaskNodes of the internal tree of a ClassTreeMask, containing the rules.
121    /**
122        Because of the complicated shape of the internal rule-tree of ClassTreeMask, an
123        iterator is used to move through all nodes of the tree. It starts with the BaseObject
124        and moves on to the first subclass until it reaches a leaf of the tree. Then the
125        iterator moves one step back and iterates to the second subclass. If there are no more
126        subclasses, it steps another step back, and so on.
127    */
128    class _CoreExport ClassTreeMaskIterator
129    {
130        public:
131            ClassTreeMaskIterator(ClassTreeMaskNode* node);
132            ~ClassTreeMaskIterator();
133
134            ClassTreeMaskIterator& operator++();
135            ClassTreeMaskNode* operator*() const;
136            ClassTreeMaskNode* operator->() const;
137            operator bool();
138            bool operator==(ClassTreeMaskNode* compare);
139            bool operator!=(ClassTreeMaskNode* compare);
140
141        private:
142            std::stack<std::pair<std::list<ClassTreeMaskNode*>::iterator, std::list<ClassTreeMaskNode*>::iterator> > nodes_;    //!< A stack to store list-iterators
143            std::list<ClassTreeMaskNode*> rootlist_;                                                                            //!< A list for internal use (it only stores the root-node)
144    };
145
146
147    // ###############################
148    // ###      ClassTreeMask      ###
149    // ###############################
150    //! The ClassTreeMask is a set of rules, containing the information for each class whether it's included or not.
151    /**
152        With a ClassTreeMask, you can include or exclude subtrees of the class-tree, starting
153        with a given subclass, described by the corresponding Identifier. To minimize the size
154        of the mask, the mask saves only relevant rules. But you can manually add rules that
155        don't change the information of the mask by using clean = false. If you want to drop
156        useless rules, call the clean() function.
157    */
158    class _CoreExport ClassTreeMask
159    {
160        public:
161            ClassTreeMask();
162            ClassTreeMask(const ClassTreeMask& other);
163            ~ClassTreeMask();
164
165            void include(const Identifier* subclass, bool overwrite = true, bool clean = true);
166            void exclude(const Identifier* subclass, bool overwrite = true, bool clean = true);
167            void add(const Identifier* subclass, bool bInclude, bool overwrite = true, bool clean = true);
168
169            void includeSingle(const Identifier* subclass, bool clean = true);
170            void excludeSingle(const Identifier* subclass, bool clean = true);
171            void addSingle(const Identifier* subclass, bool bInclude, bool clean = true);
172
173            void reset();
174            void clean();
175
176            bool isIncluded(const Identifier* subclass) const;
177            bool isExcluded(const Identifier* subclass) const;
178
179            ClassTreeMask& operator=(const ClassTreeMask& other);
180
181            ClassTreeMask& operator+();
182            ClassTreeMask operator-() const;
183
184            ClassTreeMask operator+(const ClassTreeMask& other) const;
185            ClassTreeMask operator*(const ClassTreeMask& other) const;
186            ClassTreeMask operator-(const ClassTreeMask& other) const;
187            ClassTreeMask operator!() const;
188
189            ClassTreeMask& operator+=(const ClassTreeMask& other);
190            ClassTreeMask& operator*=(const ClassTreeMask& other);
191            ClassTreeMask& operator-=(const ClassTreeMask& other);
192
193            ClassTreeMask operator&(const ClassTreeMask& other) const;
194            ClassTreeMask operator|(const ClassTreeMask& other) const;
195            ClassTreeMask operator^(const ClassTreeMask& other) const;
196            ClassTreeMask operator~() const;
197
198            ClassTreeMask& operator&=(const ClassTreeMask& other);
199            ClassTreeMask& operator|=(const ClassTreeMask& other);
200            ClassTreeMask& operator^=(const ClassTreeMask& other);
201
202            friend std::ostream& operator<<(std::ostream& out, const ClassTreeMask& mask);
203
204        private:
205            void add(ClassTreeMaskNode* node, const Identifier* subclass, bool bInclude, bool overwrite = true);
206            bool isIncluded(ClassTreeMaskNode* node, const Identifier* subclass) const;
207            void clean(ClassTreeMaskNode* node);
208            bool nodeExists(const Identifier* subclass);
209
210            ClassTreeMaskNode* root_;   //!< The root-node of the internal rule-tree, usually BaseObject
211    };
212}
213
214#endif /* _ClassTreeMask_H__ */
Note: See TracBrowser for help on using the repository browser.