]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - include/iscenegraph.h
Remove -Wno-delete-non-virtual-dtor
[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 #include "signal/signalfwd.h"
28
29 template<typename value_type>
30 class Stack;
31 template<typename Contained>
32 class Reference;
33
34 namespace scene
35 {
36 class Instance;
37 const Instance* const nullInstancePointer = 0;
38 inline const Instance& nullInstance(){
39         return *nullInstancePointer;
40 }
41
42 class Node;
43 const Node* const nullNodePointer = 0;
44 inline const Node& nullNode(){
45         return *nullNodePointer;
46 }
47 }
48
49 typedef Reference<scene::Node> NodeReference;
50
51 typedef std::size_t TypeId;
52
53 const TypeId NODETYPEID_MAX = 64;
54 const TypeId NODETYPEID_NONE = NODETYPEID_MAX;
55
56 const TypeId INSTANCETYPEID_MAX = 64;
57 const TypeId INSTANCETYPEID_NONE = INSTANCETYPEID_MAX;
58
59 namespace scene
60 {
61 /// \brief A unique key to an instance of a node in the scene-graph.
62 typedef Stack<NodeReference> Path;
63
64 /// \brief A scene-graph - a Directed Acyclic Graph (DAG).
65 ///
66 /// - Each node may refer to zero or more 'child' nodes (directed).
67 /// - A node may never have itself as one of its ancestors (acyclic).
68 /// - Each node may have more than one 'parent', thus having more than one 'instance' in the graph.
69 /// - Each instance is uniquely identified by the list of its ancestors plus itself, known as a 'path'.
70 class Graph
71 {
72 public:
73 virtual ~Graph() = default;
74 INTEGER_CONSTANT( Version, 1 );
75 STRING_CONSTANT( Name, "scenegraph" );
76
77 class Walker
78 {
79 public:
80 /// \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.
81 virtual bool pre( const Path& path, Instance& instance ) const = 0;
82 /// \brief Called after traversing the last child-instance of 'instance'.
83 virtual void post( const Path& path, Instance& instance ) const {
84 }
85 };
86
87 /// \brief Returns the root-node of the graph.
88 virtual Node& root() = 0;
89 /// \brief Sets the root-node of the graph to be 'node'.
90 virtual void insert_root( Node& root ) = 0;
91 /// \brief Clears the root-node of the graph.
92 virtual void erase_root() = 0;
93 /// \brief Traverses all nodes in the graph depth-first, starting from the root node.
94 virtual void traverse( const Walker& walker ) = 0;
95 /// \brief Traverses all nodes in the graph depth-first, starting from 'start'.
96 virtual void traverse_subgraph( const Walker& walker, const Path& start ) = 0;
97 /// \brief Returns the instance at the location identified by 'path', or 0 if it does not exist.
98 virtual scene::Instance* find( const Path& path ) = 0;
99
100 /// \brief Invokes all scene-changed callbacks. Called when any part of the scene changes the way it will appear when the scene is rendered.
101 /// \todo Move to a separate class.
102 virtual void sceneChanged() = 0;
103 /// \brief Add a \p callback to be invoked when the scene changes.
104 /// \todo Move to a separate class.
105 virtual void addSceneChangedCallback( const SignalHandler& handler ) = 0;
106
107 /// \brief Invokes all bounds-changed callbacks. Called when the bounds of any instance in the scene change.
108 /// \todo Move to a separate class.
109 virtual void boundsChanged() = 0;
110 /// \brief Add a \p callback to be invoked when the bounds of any instance in the scene change.
111 virtual SignalHandlerId addBoundsChangedCallback( const SignalHandler& boundsChanged ) = 0;
112 /// \brief Remove a \p callback to be invoked when the bounds of any instance in the scene change.
113 virtual void removeBoundsChangedCallback( SignalHandlerId id ) = 0;
114
115 virtual TypeId getNodeTypeId( const char* name ) = 0;
116 virtual TypeId getInstanceTypeId( const char* name ) = 0;
117 };
118
119 class Traversable
120 {
121 public:
122 STRING_CONSTANT( Name, "scene::Traversable" );
123
124 class Observer
125 {
126 public:
127 /// \brief Called when a node is added to the container.
128 virtual void insert( Node& node ) = 0;
129 /// \brief Called when a node is removed from the container.
130 virtual void erase( Node& node ) = 0;
131 };
132
133 class Walker
134 {
135 public:
136 /// \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.
137 virtual bool pre( Node& node ) const = 0;
138 /// \brief Called after traversing the last child-node of 'node'.
139 virtual void post( Node& node ) const {
140 }
141 };
142 /// \brief Adds a node to the container.
143 virtual void insert( Node& node ) = 0;
144 /// \brief Removes a node from the container.
145 virtual void erase( Node& node ) = 0;
146 /// \brief Traverses the subgraphs rooted at each node in the container, depth-first.
147 virtual void traverse( const Walker& walker ) = 0;
148 /// \brief Returns true if the container contains no nodes.
149 virtual bool empty() const = 0;
150 };
151
152 class Instantiable
153 {
154 public:
155 STRING_CONSTANT( Name, "scene::Instantiable" );
156
157 class Observer
158 {
159 public:
160 /// \brief Called when an instance is added to the container.
161 virtual void insert( scene::Instance* instance ) = 0;
162 /// \brief Called when an instance is removed from the container.
163 virtual void erase( scene::Instance* instance ) = 0;
164 };
165
166 class Visitor
167 {
168 public:
169 virtual void visit( Instance& instance ) const = 0;
170 };
171
172 /// \brief Returns a new instance uniquely identified by 'path'.
173 virtual scene::Instance* create( const scene::Path& path, scene::Instance* parent ) = 0;
174 /// \brief Calls Visitor::visit(instance) for each instance in the container.
175 virtual void forEachInstance( const Visitor& visitor ) = 0;
176 /// \brief Adds an instance to the container.
177 virtual void insert( Observer* observer, const Path& path, scene::Instance* instance ) = 0;
178 /// \brief Returns an instance removed from the container.
179 virtual scene::Instance* erase( Observer* observer, const Path& path ) = 0;
180 };
181
182 class Cloneable
183 {
184 public:
185 STRING_CONSTANT( Name, "scene::Cloneable" );
186
187 /// \brief Returns a copy of itself.
188 virtual scene::Node& clone() const = 0;
189 };
190 }
191
192 #include "modulesystem.h"
193
194 template<typename Type>
195 class GlobalModule;
196 typedef GlobalModule<scene::Graph> GlobalSceneGraphModule;
197
198 template<typename Type>
199 class GlobalModuleRef;
200 typedef GlobalModuleRef<scene::Graph> GlobalSceneGraphModuleRef;
201
202 inline scene::Graph& GlobalSceneGraph(){
203         return GlobalSceneGraphModule::getTable();
204 }
205
206 inline void AddSceneChangeCallback( const SignalHandler& handler ){
207         GlobalSceneGraph().addSceneChangedCallback( handler );
208 }
209 inline void SceneChangeNotify(){
210         GlobalSceneGraph().sceneChanged();
211 }
212
213
214
215 #endif