X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=libs%2Finstancelib.h;h=af9dd2bba31a181f3eb6b4e7c24f7e4c93cf8ed1;hb=1483f2b87be32a60ef7e0038f3a893624a3c6639;hp=9ff32e6d46a837a705bdf10355c78a9bd588a68f;hpb=107765f0e4b543dfc346851ee5b4605cc17eb1c6;p=xonotic%2Fnetradiant.git diff --git a/libs/instancelib.h b/libs/instancelib.h index 9ff32e6d..af9dd2bb 100644 --- a/libs/instancelib.h +++ b/libs/instancelib.h @@ -1,25 +1,25 @@ /* -Copyright (C) 2001-2006, William Joseph. -All Rights Reserved. + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. -This file is part of GtkRadiant. + 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 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. + 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 -*/ + 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_INSTANCELIB_H) +#if !defined ( INCLUDED_INSTANCELIB_H ) #define INCLUDED_INSTANCELIB_H #include "debugging/debugging.h" @@ -33,161 +33,136 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA class InstanceSubgraphWalker : public scene::Traversable::Walker { - scene::Instantiable::Observer* m_observer; - mutable scene::Path m_path; - mutable Stack m_parent; +scene::Instantiable::Observer* m_observer; +mutable scene::Path m_path; +mutable Stack m_parent; public: - InstanceSubgraphWalker(scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* parent) - : m_observer(observer), m_path(path), m_parent(parent) - { - } - bool pre(scene::Node& node) const - { - m_path.push(makeReference(node)); - scene::Instance* instance = Node_getInstantiable(node)->create(m_path, m_parent.top()); - m_observer->insert(instance); - Node_getInstantiable(node)->insert(m_observer, m_path, instance); - m_parent.push(instance); - return true; - } - void post(scene::Node& node) const - { - m_path.pop(); - m_parent.pop(); - } +InstanceSubgraphWalker( scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* parent ) + : m_observer( observer ), m_path( path ), m_parent( parent ){ +} +bool pre( scene::Node& node ) const { + m_path.push( makeReference( node ) ); + scene::Instance* instance = Node_getInstantiable( node )->create( m_path, m_parent.top() ); + m_observer->insert( instance ); + Node_getInstantiable( node )->insert( m_observer, m_path, instance ); + m_parent.push( instance ); + return true; +} +void post( scene::Node& node ) const { + m_path.pop(); + m_parent.pop(); +} }; class UninstanceSubgraphWalker : public scene::Traversable::Walker { - scene::Instantiable::Observer* m_observer; - mutable scene::Path m_path; +scene::Instantiable::Observer* m_observer; +mutable scene::Path m_path; public: - UninstanceSubgraphWalker(scene::Instantiable::Observer* observer, const scene::Path& parent) - : m_observer(observer), m_path(parent) - { - } - bool pre(scene::Node& node) const - { - m_path.push(makeReference(node)); - return true; - } - void post(scene::Node& node) const - { - scene::Instance* instance = Node_getInstantiable(node)->erase(m_observer, m_path); - m_observer->erase(instance); - delete instance; - m_path.pop(); - } +UninstanceSubgraphWalker( scene::Instantiable::Observer* observer, const scene::Path& parent ) + : m_observer( observer ), m_path( parent ){ +} +bool pre( scene::Node& node ) const { + m_path.push( makeReference( node ) ); + return true; +} +void post( scene::Node& node ) const { + scene::Instance* instance = Node_getInstantiable( node )->erase( m_observer, m_path ); + m_observer->erase( instance ); + delete instance; + m_path.pop(); +} }; class InstanceSet : public scene::Traversable::Observer { - typedef std::pair CachePath; +typedef std::pair CachePath; - typedef CachePath key_type; +typedef CachePath key_type; - typedef std::map InstanceMap; - InstanceMap m_instances; +typedef std::map InstanceMap; +InstanceMap m_instances; public: - typedef InstanceMap::iterator iterator; - - iterator begin() - { - return m_instances.begin(); - } - iterator end() - { - return m_instances.end(); - } - - // traverse observer - void insert(scene::Node& child) - { - for(iterator i = begin(); i != end(); ++i) - { - Node_traverseSubgraph(child, InstanceSubgraphWalker((*i).first.first, (*i).first.second, (*i).second)); - (*i).second->boundsChanged(); - } - } - void erase(scene::Node& child) - { - for(iterator i = begin(); i != end(); ++i) - { - Node_traverseSubgraph(child, UninstanceSubgraphWalker((*i).first.first, (*i).first.second)); - (*i).second->boundsChanged(); - } - } - - // instance - void forEachInstance(const scene::Instantiable::Visitor& visitor) - { - for(iterator i = begin(); i != end(); ++i) - { - visitor.visit(*(*i).second); - } - } - - void insert(scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance) - { - ASSERT_MESSAGE(m_instances.find(key_type(observer, PathConstReference(instance->path()))) == m_instances.end(), "InstanceSet::insert - element already exists"); - m_instances.insert(InstanceMap::value_type(key_type(observer, PathConstReference(instance->path())), instance)); - } - scene::Instance* erase(scene::Instantiable::Observer* observer, const scene::Path& path) - { - ASSERT_MESSAGE(m_instances.find(key_type(observer, PathConstReference(path))) != m_instances.end(), "InstanceSet::erase - failed to find element"); - InstanceMap::iterator i = m_instances.find(key_type(observer, PathConstReference(path))); - scene::Instance* instance = i->second; - m_instances.erase(i); - return instance; - } - - void transformChanged() - { - for(InstanceMap::iterator i = m_instances.begin(); i != m_instances.end(); ++i) - { - (*i).second->transformChanged(); - } - } - typedef MemberCaller TransformChangedCaller; - void boundsChanged() - { - for(InstanceMap::iterator i = m_instances.begin(); i != m_instances.end(); ++i) - { - (*i).second->boundsChanged(); - } - } - typedef MemberCaller BoundsChangedCaller; -}; +typedef InstanceMap::iterator iterator; -template -inline void InstanceSet_forEach(InstanceSet& instances, const Functor& functor) -{ - for(InstanceSet::iterator i = instances.begin(), end = instances.end(); i != end; ++i) - { - functor(*(*i).second); - } +iterator begin(){ + return m_instances.begin(); +} +iterator end(){ + return m_instances.end(); } -template -class InstanceEvaluateTransform -{ -public: - inline void operator()(scene::Instance& instance) const - { - InstanceTypeCast::cast(instance)->evaluateTransform(); - } +// traverse observer +void insert( scene::Node& child ){ + for ( iterator i = begin(); i != end(); ++i ) + { + Node_traverseSubgraph( child, InstanceSubgraphWalker( ( *i ).first.first, ( *i ).first.second, ( *i ).second ) ); + ( *i ).second->boundsChanged(); + } +} +void erase( scene::Node& child ){ + for ( iterator i = begin(); i != end(); ++i ) + { + Node_traverseSubgraph( child, UninstanceSubgraphWalker( ( *i ).first.first, ( *i ).first.second ) ); + ( *i ).second->boundsChanged(); + } +} + +// instance +void forEachInstance( const scene::Instantiable::Visitor& visitor ){ + for ( iterator i = begin(); i != end(); ++i ) + { + visitor.visit( *( *i ).second ); + } +} + +void insert( scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance ){ + ASSERT_MESSAGE( m_instances.find( key_type( observer, PathConstReference( instance->path() ) ) ) == m_instances.end(), "InstanceSet::insert - element already exists" ); + m_instances.insert( InstanceMap::value_type( key_type( observer, PathConstReference( instance->path() ) ), instance ) ); +} +scene::Instance* erase( scene::Instantiable::Observer* observer, const scene::Path& path ){ + ASSERT_MESSAGE( m_instances.find( key_type( observer, PathConstReference( path ) ) ) != m_instances.end(), "InstanceSet::erase - failed to find element" ); + InstanceMap::iterator i = m_instances.find( key_type( observer, PathConstReference( path ) ) ); + scene::Instance* instance = i->second; + m_instances.erase( i ); + return instance; +} + +void transformChanged(){ + for ( InstanceMap::iterator i = m_instances.begin(); i != m_instances.end(); ++i ) + { + ( *i ).second->transformChanged(); + } +} +typedef MemberCaller TransformChangedCaller; +void boundsChanged(){ + for ( InstanceMap::iterator i = m_instances.begin(); i != m_instances.end(); ++i ) + { + ( *i ).second->boundsChanged(); + } +} +typedef MemberCaller BoundsChangedCaller; }; +template +inline void InstanceSet_forEach( InstanceSet& instances, const Functor& functor ){ + for ( InstanceSet::iterator i = instances.begin(), end = instances.end(); i != end; ++i ) + { + functor( *( *i ).second ); + } +} + template class InstanceSetEvaluateTransform { public: - static void apply(InstanceSet& instances) - { - InstanceSet_forEach(instances, InstanceEvaluateTransform()); - } - typedef ReferenceCaller::apply> Caller; +static void apply( InstanceSet& instances ){ + InstanceSet_forEach(instances, [&](scene::Instance &instance) { + InstanceTypeCast::cast(instance)->evaluateTransform(); + }); +} +typedef ReferenceCaller::apply> Caller; }; #endif