Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core/src/orxonox/core/ClassTreeMask.h @ 809

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

commented and documented ClassManager, IdentifierDistributor and ClassTreeMask

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