mirror of
https://github.com/UberGames/GtkRadiant.git
synced 2024-11-23 12:22:19 +00:00
6ee91d153e
git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@44 8a3a26a2-13c4-0310-b231-cf6edde360e5
221 lines
7.3 KiB
C++
221 lines
7.3 KiB
C++
/*
|
|
Copyright (C) 2001-2006, William Joseph.
|
|
All Rights Reserved.
|
|
|
|
This file is part of GtkRadiant.
|
|
|
|
GtkRadiant is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
GtkRadiant is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GtkRadiant; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#if !defined (INCLUDED_ISCENEGRAPH_H)
|
|
#define INCLUDED_ISCENEGRAPH_H
|
|
|
|
#include <cstddef>
|
|
#include "generic/constant.h"
|
|
#include "signal/signalfwd.h"
|
|
|
|
template<typename value_type>
|
|
class Stack;
|
|
template<typename Contained>
|
|
class Reference;
|
|
|
|
namespace scene
|
|
{
|
|
class Instance;
|
|
const Instance* const nullInstancePointer = 0;
|
|
inline const Instance& nullInstance()
|
|
{
|
|
return *nullInstancePointer;
|
|
}
|
|
|
|
class Node;
|
|
const Node* const nullNodePointer = 0;
|
|
inline const Node& nullNode()
|
|
{
|
|
return *nullNodePointer;
|
|
}
|
|
}
|
|
|
|
typedef Reference<scene::Node> NodeReference;
|
|
|
|
typedef std::size_t TypeId;
|
|
|
|
const TypeId NODETYPEID_MAX = 64;
|
|
const TypeId NODETYPEID_NONE = NODETYPEID_MAX;
|
|
|
|
const TypeId INSTANCETYPEID_MAX = 64;
|
|
const TypeId INSTANCETYPEID_NONE = INSTANCETYPEID_MAX;
|
|
|
|
namespace scene
|
|
{
|
|
/// \brief A unique key to an instance of a node in the scene-graph.
|
|
typedef Stack<NodeReference> Path;
|
|
|
|
/// \brief A scene-graph - a Directed Acyclic Graph (DAG).
|
|
///
|
|
/// - Each node may refer to zero or more 'child' nodes (directed).
|
|
/// - A node may never have itself as one of its ancestors (acyclic).
|
|
/// - Each node may have more than one 'parent', thus having more than one 'instance' in the graph.
|
|
/// - Each instance is uniquely identified by the list of its ancestors plus itself, known as a 'path'.
|
|
class Graph
|
|
{
|
|
public:
|
|
INTEGER_CONSTANT(Version, 1);
|
|
STRING_CONSTANT(Name, "scenegraph");
|
|
|
|
class Walker
|
|
{
|
|
public:
|
|
/// \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.
|
|
virtual bool pre(const Path& path, Instance& instance) const = 0;
|
|
/// \brief Called after traversing the last child-instance of 'instance'.
|
|
virtual void post(const Path& path, Instance& instance) const
|
|
{
|
|
}
|
|
};
|
|
|
|
/// \brief Returns the root-node of the graph.
|
|
virtual Node& root() = 0;
|
|
/// \brief Sets the root-node of the graph to be 'node'.
|
|
virtual void insert_root(Node& root) = 0;
|
|
/// \brief Clears the root-node of the graph.
|
|
virtual void erase_root() = 0;
|
|
/// \brief Traverses all nodes in the graph depth-first, starting from the root node.
|
|
virtual void traverse(const Walker& walker) = 0;
|
|
/// \brief Traverses all nodes in the graph depth-first, starting from 'start'.
|
|
virtual void traverse_subgraph(const Walker& walker, const Path& start) = 0;
|
|
/// \brief Returns the instance at the location identified by 'path', or 0 if it does not exist.
|
|
virtual scene::Instance* find(const Path& path) = 0;
|
|
|
|
/// \brief Invokes all scene-changed callbacks. Called when any part of the scene changes the way it will appear when the scene is rendered.
|
|
/// \todo Move to a separate class.
|
|
virtual void sceneChanged() = 0;
|
|
/// \brief Add a \p callback to be invoked when the scene changes.
|
|
/// \todo Move to a separate class.
|
|
virtual void addSceneChangedCallback(const SignalHandler& handler) = 0;
|
|
|
|
/// \brief Invokes all bounds-changed callbacks. Called when the bounds of any instance in the scene change.
|
|
/// \todo Move to a separate class.
|
|
virtual void boundsChanged() = 0;
|
|
/// \brief Add a \p callback to be invoked when the bounds of any instance in the scene change.
|
|
virtual SignalHandlerId addBoundsChangedCallback(const SignalHandler& boundsChanged) = 0;
|
|
/// \brief Remove a \p callback to be invoked when the bounds of any instance in the scene change.
|
|
virtual void removeBoundsChangedCallback(SignalHandlerId id) = 0;
|
|
|
|
virtual TypeId getNodeTypeId(const char* name) = 0;
|
|
virtual TypeId getInstanceTypeId(const char* name) = 0;
|
|
};
|
|
|
|
class Traversable
|
|
{
|
|
public:
|
|
STRING_CONSTANT(Name, "scene::Traversable");
|
|
|
|
class Observer
|
|
{
|
|
public:
|
|
/// \brief Called when a node is added to the container.
|
|
virtual void insert(Node& node) = 0;
|
|
/// \brief Called when a node is removed from the container.
|
|
virtual void erase(Node& node) = 0;
|
|
};
|
|
|
|
class Walker
|
|
{
|
|
public:
|
|
/// \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.
|
|
virtual bool pre(Node& node) const = 0;
|
|
/// \brief Called after traversing the last child-node of 'node'.
|
|
virtual void post(Node& node) const
|
|
{
|
|
}
|
|
};
|
|
/// \brief Adds a node to the container.
|
|
virtual void insert(Node& node) = 0;
|
|
/// \brief Removes a node from the container.
|
|
virtual void erase(Node& node) = 0;
|
|
/// \brief Traverses the subgraphs rooted at each node in the container, depth-first.
|
|
virtual void traverse(const Walker& walker) = 0;
|
|
/// \brief Returns true if the container contains no nodes.
|
|
virtual bool empty() const = 0;
|
|
};
|
|
|
|
class Instantiable
|
|
{
|
|
public:
|
|
STRING_CONSTANT(Name, "scene::Instantiable");
|
|
|
|
class Observer
|
|
{
|
|
public:
|
|
/// \brief Called when an instance is added to the container.
|
|
virtual void insert(scene::Instance* instance) = 0;
|
|
/// \brief Called when an instance is removed from the container.
|
|
virtual void erase(scene::Instance* instance) = 0;
|
|
};
|
|
|
|
class Visitor
|
|
{
|
|
public:
|
|
virtual void visit(Instance& instance) const = 0;
|
|
};
|
|
|
|
/// \brief Returns a new instance uniquely identified by 'path'.
|
|
virtual scene::Instance* create(const scene::Path& path, scene::Instance* parent) = 0;
|
|
/// \brief Calls Visitor::visit(instance) for each instance in the container.
|
|
virtual void forEachInstance(const Visitor& visitor) = 0;
|
|
/// \brief Adds an instance to the container.
|
|
virtual void insert(Observer* observer, const Path& path, scene::Instance* instance) = 0;
|
|
/// \brief Returns an instance removed from the container.
|
|
virtual scene::Instance* erase(Observer* observer, const Path& path) = 0;
|
|
};
|
|
|
|
class Cloneable
|
|
{
|
|
public:
|
|
STRING_CONSTANT(Name, "scene::Cloneable");
|
|
|
|
/// \brief Returns a copy of itself.
|
|
virtual scene::Node& clone() const = 0;
|
|
};
|
|
}
|
|
|
|
#include "modulesystem.h"
|
|
|
|
template<typename Type>
|
|
class GlobalModule;
|
|
typedef GlobalModule<scene::Graph> GlobalSceneGraphModule;
|
|
|
|
template<typename Type>
|
|
class GlobalModuleRef;
|
|
typedef GlobalModuleRef<scene::Graph> GlobalSceneGraphModuleRef;
|
|
|
|
inline scene::Graph& GlobalSceneGraph()
|
|
{
|
|
return GlobalSceneGraphModule::getTable();
|
|
}
|
|
|
|
inline void AddSceneChangeCallback(const SignalHandler& handler)
|
|
{
|
|
GlobalSceneGraph().addSceneChangedCallback(handler);
|
|
}
|
|
inline void SceneChangeNotify()
|
|
{
|
|
GlobalSceneGraph().sceneChanged();
|
|
}
|
|
|
|
|
|
|
|
#endif
|