]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - include/iscenegraph.h
added msvc dlls to install.py; added svn revision lookup to makeversion.py; updated...
[xonotic/netradiant.git] / include / iscenegraph.h
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant 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 GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined (INCLUDED_ISCENEGRAPH_H)
23 #define INCLUDED_ISCENEGRAPH_H
24
25 #include <cstddef>
26 #include "generic/constant.h"
27
28 template<typename value_type>
29 class Stack;
30 template<typename Contained>
31 class Reference;
32
33 class Callback;
34
35 namespace scene
36 {
37   class Instance;
38   const Instance* const nullInstancePointer = 0;
39   inline const Instance& nullInstance()
40   {
41     return *nullInstancePointer;
42   }
43
44   class Node;
45   const Node* const nullNodePointer = 0;
46   inline const Node& nullNode()
47   {
48     return *nullNodePointer;
49   }
50 }
51
52 typedef Reference<scene::Node> NodeReference;
53
54 typedef std::size_t TypeId;
55
56 const TypeId NODETYPEID_MAX = 64;
57 const TypeId NODETYPEID_NONE = NODETYPEID_MAX;
58
59 const TypeId INSTANCETYPEID_MAX = 64;
60 const TypeId INSTANCETYPEID_NONE = INSTANCETYPEID_MAX;
61
62 namespace scene
63 {
64   /// \brief A unique key to an instance of a node in the scene-graph.
65   typedef Stack<NodeReference> Path;
66
67   /// \brief A scene-graph - a Directed Acyclic Graph (DAG).
68   ///
69   /// - Each node may refer to zero or more 'child' nodes (directed).
70   /// - A node may never have itself as one of its ancestors (acyclic).
71   /// - Each node may have more than one 'parent', thus having more than one 'instance' in the graph.
72   /// - Each instance is uniquely identified by the list of its ancestors plus itself, known as a 'path'.
73   class Graph
74   {
75   public:
76     INTEGER_CONSTANT(Version, 1);
77     STRING_CONSTANT(Name, "scenegraph");
78
79     class Walker
80     {
81     public:
82       /// \brief Called before traversing the first child-instance of 'instance'. If the return value is false, the children of the current instance are not traversed.
83       virtual bool pre(const Path& path, Instance& instance) const = 0;
84       /// \brief Called after traversing the last child-instance of 'instance'.
85       virtual void post(const Path& path, Instance& instance) const
86       {
87       }
88     };
89
90     /// \brief Returns the root-node of the graph.
91     virtual Node& root() = 0;
92     /// \brief Sets the root-node of the graph to be 'node'.
93     virtual void insert_root(Node& root) = 0;
94     /// \brief Clears the root-node of the graph.
95     virtual void erase_root() = 0;
96     /// \brief Traverses all nodes in the graph depth-first, starting from the root node.
97     virtual void traverse(const Walker& walker) = 0;
98     /// \brief Traverses all nodes in the graph depth-first, starting from 'start'.
99     virtual void traverse_subgraph(const Walker& walker, const Path& start) = 0;
100     /// \brief Returns the instance at the location identified by 'path', or 0 if it does not exist.
101     virtual scene::Instance* find(const Path& path) = 0;
102
103     /// \brief Invokes all scene-changed callbacks. Called when any part of the scene changes the way it will appear when the scene is rendered.
104     /// \todo Move to a separate class.
105     virtual void sceneChanged() = 0;
106     /// \brief Add a \p callback to be invoked when the scene changes.
107     /// \todo Move to a separate class.
108     virtual void addSceneChangedCallback(const Callback& callback) = 0;
109
110     /// \brief Invokes all bounds-changed callbacks. Called when the bounds of any instance in the scene change.
111     /// \todo Move to a separate class.
112     virtual void boundsChanged() = 0;
113     /// \brief Add a \p callback to be invoked when the bounds of any instance in the scene change.
114     virtual void addBoundsChangedCallback(const Callback& callback) = 0;
115     /// \brief Remove a \p callback to be invoked when the bounds of any instance in the scene change.
116     virtual void removeBoundsChangedCallback(const Callback& callback) = 0;
117
118     virtual TypeId getNodeTypeId(const char* name) = 0;
119     virtual TypeId getInstanceTypeId(const char* name) = 0;
120   };
121
122   class Traversable
123   {
124   public:
125     STRING_CONSTANT(Name, "scene::Traversable");
126
127     class Observer
128     {
129     public:
130       /// \brief Called when a node is added to the container.
131       virtual void insert(Node& node) = 0;
132       /// \brief Called when a node is removed from the container.
133       virtual void erase(Node& node) = 0;
134     };
135
136     class Walker
137     {
138     public:
139       /// \brief Called before traversing the first child-node of 'node'. If the return value is false, the children of the current node are not traversed.
140       virtual bool pre(Node& node) const = 0;
141       /// \brief Called after traversing the last child-node of 'node'. 
142       virtual void post(Node& node) const
143       {
144       }
145     };
146     /// \brief Adds a node to the container.
147     virtual void insert(Node& node) = 0;
148     /// \brief Removes a node from the container.
149     virtual void erase(Node& node) = 0;
150     /// \brief Traverses the subgraphs rooted at each node in the container, depth-first.
151     virtual void traverse(const Walker& walker) = 0;
152     /// \brief Returns true if the container contains no nodes.
153     virtual bool empty() const = 0;
154   };
155
156   class Instantiable
157   {
158   public:
159     STRING_CONSTANT(Name, "scene::Instantiable");
160
161     class Observer
162     {
163     public:
164       /// \brief Called when an instance is added to the container.
165       virtual void insert(scene::Instance* instance) = 0;
166       /// \brief Called when an instance is removed from the container.
167       virtual void erase(scene::Instance* instance) = 0;
168     };
169
170     class Visitor
171     {
172     public:
173       virtual void visit(Instance& instance) const = 0;
174     };
175
176     /// \brief Returns a new instance uniquely identified by 'path'.
177     virtual scene::Instance* create(const scene::Path& path, scene::Instance* parent) = 0;
178     /// \brief Calls Visitor::visit(instance) for each instance in the container.
179     virtual void forEachInstance(const Visitor& visitor) = 0;
180     /// \brief Adds an instance to the container.
181     virtual void insert(Observer* observer, const Path& path, scene::Instance* instance) = 0;
182     /// \brief Returns an instance removed from the container.
183     virtual scene::Instance* erase(Observer* observer, const Path& path) = 0;
184   };
185
186   class Cloneable
187   {
188   public:
189     STRING_CONSTANT(Name, "scene::Cloneable");
190
191     /// \brief Returns a copy of itself.
192     virtual scene::Node& clone() const = 0;
193   };
194 }
195
196 #include "modulesystem.h"
197
198 template<typename Type>
199 class GlobalModule;
200 typedef GlobalModule<scene::Graph> GlobalSceneGraphModule;
201
202 template<typename Type>
203 class GlobalModuleRef;
204 typedef GlobalModuleRef<scene::Graph> GlobalSceneGraphModuleRef;
205
206 inline scene::Graph& GlobalSceneGraph()
207 {
208   return GlobalSceneGraphModule::getTable();
209 }
210
211 inline void AddSceneChangeCallback(const Callback& callback)
212 {
213   GlobalSceneGraph().addSceneChangedCallback(callback);
214 }
215 inline void SceneChangeNotify()
216 {
217   GlobalSceneGraph().sceneChanged();
218 }
219
220
221
222 #endif