From: timoore Date: Fri, 21 Nov 2008 14:48:15 +0000 (+0000) Subject: Templates for interacting with OSG objects X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=98cecfe940dd9245672b32a01e027aca3d04c02f;p=simgear.git Templates for interacting with OSG objects --- diff --git a/simgear/structure/Makefile.am b/simgear/structure/Makefile.am index f976fe80..17e2ff9b 100644 --- a/simgear/structure/Makefile.am +++ b/simgear/structure/Makefile.am @@ -8,6 +8,7 @@ include_HEADERS = \ exception.hxx \ event_mgr.hxx \ subsystem_mgr.hxx \ + OSGUtils.hxx \ OSGVersion.hxx \ SGAtomic.hxx \ SGBinding.hxx \ diff --git a/simgear/structure/OSGUtils.hxx b/simgear/structure/OSGUtils.hxx new file mode 100644 index 00000000..21c5d698 --- /dev/null +++ b/simgear/structure/OSGUtils.hxx @@ -0,0 +1,157 @@ +// OSGUtils.hxx - Useful templates for interfacing to Open Scene Graph +// +// Copyright (C) 2008 Tim Moore timoore@redhat.com +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#ifndef SIMGEAR_OSGUTILS_HXX +#define SIMGEAR_OSGUTILS_HXX 1 + +#include +#include + +namespace simgear +{ +// RefPtrAdapter also appears in OpenSceneGraph's +// osgDB/DatabasePager.cpp. I wrote that code too. -- Tim Moore + +// Convert function objects that take pointer args into functions that a +// reference to an osg::ref_ptr. This is quite useful for doing STL +// operations on lists of ref_ptr. This code assumes that a function +// with an argument const Foo* should be composed into a function of +// argument type ref_ptr&, not ref_ptr&. Some support +// for that should be added to make this more general. +template +struct PointerTraits +{ + typedef class NullType {} PointeeType; +}; + +template +struct PointerTraits +{ + typedef U PointeeType; +}; + +template +struct PointerTraits +{ + typedef U PointeeType; +}; + +template +class RefPtrAdapter + : public std::unary_function::PointeeType>, + typename FuncObj::result_type> +{ +public: + typedef typename PointerTraits::PointeeType PointeeType; + typedef osg::ref_ptr RefPtrType; + explicit RefPtrAdapter(const FuncObj& funcObj) : _func(funcObj) {} + typename FuncObj::result_type operator()(const RefPtrType& refPtr) const + { + return _func(refPtr.get()); + } +protected: + FuncObj _func; +}; + +template +RefPtrAdapter refPtrAdapt(const FuncObj& func) +{ + return RefPtrAdapter(func); +} +} +/** Typesafe wrapper around OSG's object clone function. Something + * very similar is in current OSG sources. + */ +namespace osg +{ +template class ref_ptr; +class CopyOp; +} + +namespace simgear +{ +template +T* clone(const T* object, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) +{ + return static_cast(object->clone(copyop)); +} + +template +T* clone_ref(const osg::ref_ptr& object, + const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) +{ + return static_cast(object->clone(copyop)); +} + +template +class BackRefInsertIterator + : public boost::iterator_facade, + BackRefInsertIterator, + boost::incrementable_traversal_tag + > +{ +public: + typedef typename Container::value_type::element_type* PtrType; + BackRefInsertIterator() : _container(0) {} + explicit BackRefInsertIterator(Container& container) + : _container(&container) + { + } + + BackRefInsertIterator& + operator=(const PtrType ptr) + { + _container->push_back(ptr); + return *this; + } + +private: + friend class boost::iterator_core_access; + + void increment() + { + } + + BackRefInsertIterator& dereference() + { + return *this; + } + + BackRefInsertIterator& dereference() const + { + return const_cast(*this); + } + + bool equal(const BackRefInsertIterator& rhs) + { + return _container == rhs._container; + } + + Container* _container; +}; + + +template +inline BackRefInsertIterator +backRefInsertIterator(Container& container) +{ + return BackRefInsertIterator(container); +} +} +#endif