diff --git a/include/osg/CopyOp b/include/osg/CopyOp index e24dce44c..eff881fee 100644 --- a/include/osg/CopyOp +++ b/include/osg/CopyOp @@ -24,12 +24,15 @@ class Image; class Texture; class StateSet; class StateAttribute; +class StateAttributeCallback; class Uniform; class Node; class Drawable; class Array; class PrimitiveSet; class Shape; +class NodeCallback; + /** Copy Op(erator) used to control whether shallow or deep copy is used * during copy construction and clone operation.*/ @@ -52,6 +55,7 @@ class OSG_EXPORT CopyOp DEEP_COPY_PRIMITIVES = 1<<8, DEEP_COPY_SHAPES = 1<<9, DEEP_COPY_UNIFORMS = 1<<10, + DEEP_COPY_CALLBACKS = 1<<11, DEEP_COPY_ALL = 0x7FFFFFFF }; @@ -72,6 +76,8 @@ class OSG_EXPORT CopyOp virtual PrimitiveSet* operator() (const PrimitiveSet* primitives) const; virtual Shape* operator() (const Shape* shape) const; virtual Uniform* operator() (const Uniform* shape) const; + virtual NodeCallback* operator() (const NodeCallback* nodecallback) const; + virtual StateAttributeCallback* operator() (const StateAttributeCallback* stateattributecallback) const; protected: diff --git a/include/osg/ImageSequence b/include/osg/ImageSequence index a8f15dcb3..822bd2156 100644 --- a/include/osg/ImageSequence +++ b/include/osg/ImageSequence @@ -105,7 +105,7 @@ class OSG_EXPORT ImageSequence : public ImageStream virtual void update(NodeVisitor* nv); - struct OSG_EXPORT UpdateCallback : public osg::StateAttribute::Callback + struct OSG_EXPORT UpdateCallback : public osg::StateAttributeCallback { virtual void operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv); }; diff --git a/include/osg/StateAttribute b/include/osg/StateAttribute index d4c75b241..42f617616 100644 --- a/include/osg/StateAttribute +++ b/include/osg/StateAttribute @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -190,7 +191,9 @@ class OSG_EXPORT StateAttribute : public Object StateAttribute(); StateAttribute(const StateAttribute& sa,const CopyOp& copyop=CopyOp::SHALLOW_COPY): - Object(sa,copyop) {} + Object(sa,copyop), + _updateCallback(copyop(sa._updateCallback.get())) + {} /** Clone the type of an attribute, with Object* return type. @@ -281,37 +284,28 @@ class OSG_EXPORT StateAttribute : public Object // default to no black listed GLMode's associated with use of the StateAttribute. return true; } - - struct Callback : public virtual osg::Object - { - Callback() {} - Callback(const Callback&,const CopyOp&) {} - - META_Object(osg,Callback); - - /** do customized update code.*/ - virtual void operator () (StateAttribute*, NodeVisitor*) {} - }; + // provide callback for backwards compatibility. + typedef osg::StateAttributeCallback Callback; /** Set the UpdateCallback which allows users to attach customize the updating of an object during the update traversal.*/ - void setUpdateCallback(Callback* uc); + void setUpdateCallback(StateAttributeCallback* uc); /** Get the non const UpdateCallback.*/ - Callback* getUpdateCallback() { return _updateCallback.get(); } + StateAttributeCallback* getUpdateCallback() { return _updateCallback.get(); } /** Get the const UpdateCallback.*/ - const Callback* getUpdateCallback() const { return _updateCallback.get(); } + const StateAttributeCallback* getUpdateCallback() const { return _updateCallback.get(); } /** Set the EventCallback which allows users to attach customize the updating of an object during the Event traversal.*/ - void setEventCallback(Callback* ec); + void setEventCallback(StateAttributeCallback* ec); /** Get the non const EventCallback.*/ - Callback* getEventCallback() { return _eventCallback.get(); } + StateAttributeCallback* getEventCallback() { return _eventCallback.get(); } /** Get the const EventCallback.*/ - const Callback* getEventCallback() const { return _eventCallback.get(); } + const StateAttributeCallback* getEventCallback() const { return _eventCallback.get(); } /** apply the OpenGL state attributes. @@ -343,8 +337,8 @@ class OSG_EXPORT StateAttribute : public Object ParentList _parents; friend class osg::StateSet; - ref_ptr _updateCallback; - ref_ptr _eventCallback; + ref_ptr _updateCallback; + ref_ptr _eventCallback; }; } diff --git a/include/osg/StateAttributeCallback b/include/osg/StateAttributeCallback new file mode 100644 index 000000000..947259b54 --- /dev/null +++ b/include/osg/StateAttributeCallback @@ -0,0 +1,39 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * 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 + * OpenSceneGraph Public License for more details. +*/ +#ifndef OSG_STATEATTRIBUTECALLBACK +#define OSG_STATEATTRIBUTECALLBACK 1 + +#include +#include + +namespace osg { + +class StateAttribute; +class NodeVisitor; + +class OSG_EXPORT StateAttributeCallback : public virtual osg::Object +{ + public: + StateAttributeCallback() {} + + StateAttributeCallback(const StateAttributeCallback&,const CopyOp&) {} + + META_Object(osg,StateAttributeCallback); + + /** do customized update code.*/ + virtual void operator () (StateAttribute*, NodeVisitor*) {} +}; + +} + +#endif diff --git a/src/osg/CMakeLists.txt b/src/osg/CMakeLists.txt index 31a95e301..46daa7a42 100644 --- a/src/osg/CMakeLists.txt +++ b/src/osg/CMakeLists.txt @@ -137,6 +137,7 @@ SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/ShapeDrawable ${HEADER_PATH}/State ${HEADER_PATH}/StateAttribute + ${HEADER_PATH}/StateAttributeCallback ${HEADER_PATH}/StateSet ${HEADER_PATH}/Stats ${HEADER_PATH}/Stencil diff --git a/src/osg/CopyOp.cpp b/src/osg/CopyOp.cpp index c3d876414..36469a331 100644 --- a/src/osg/CopyOp.cpp +++ b/src/osg/CopyOp.cpp @@ -18,6 +18,7 @@ #include #include #include +#include using namespace osg; @@ -65,3 +66,37 @@ StateAttribute* CopyOp::operator() (const StateAttribute* attr) const } +NodeCallback* CopyOp::operator() (const NodeCallback* nc) const +{ + if (nc && _flags&DEEP_COPY_CALLBACKS) + { + // deep copy the full chain of callback + osg::NodeCallback* first = dynamic_cast(nc->clone(*this)); + first->setNestedCallback(0); + nc = nc->getNestedCallback(); + while (nc) + { + osg::NodeCallback* ucb = dynamic_cast(nc->clone(*this)); + ucb->setNestedCallback(0); + first->addNestedCallback(ucb); + nc = nc->getNestedCallback(); + } + return first; + } + else + return const_cast(nc); +} + + +StateAttributeCallback* CopyOp::operator() (const StateAttributeCallback* sc) const +{ + if (sc && _flags&DEEP_COPY_CALLBACKS) + { + // deep copy the full chain of callback + StateAttributeCallback* cb = dynamic_cast(sc->clone(*this)); + return cb; + } + else + return const_cast(sc); +} + diff --git a/src/osg/StateAttribute.cpp b/src/osg/StateAttribute.cpp index 0501c17c3..06746975e 100644 --- a/src/osg/StateAttribute.cpp +++ b/src/osg/StateAttribute.cpp @@ -42,7 +42,7 @@ void StateAttribute::removeParent(osg::StateSet* object) } -void StateAttribute::setUpdateCallback(Callback* uc) +void StateAttribute::setUpdateCallback(StateAttributeCallback* uc) { osg::notify(osg::INFO)<<"StateAttribute::Setting Update callbacks"<second.first->getUpdateCallback(); + StateAttributeCallback* callback = itr->second.first->getUpdateCallback(); if (callback) (*callback)(itr->second.first.get(),nv); } @@ -1684,7 +1684,7 @@ void StateSet::runUpdateCallbacks(osg::NodeVisitor* nv) itr!=attributeList.end(); ++itr) { - StateAttribute::Callback* callback = itr->second.first->getUpdateCallback(); + StateAttributeCallback* callback = itr->second.first->getUpdateCallback(); if (callback) (*callback)(itr->second.first.get(),nv); } } @@ -1745,7 +1745,7 @@ void StateSet::runEventCallbacks(osg::NodeVisitor* nv) itr!=_attributeList.end(); ++itr) { - StateAttribute::Callback* callback = itr->second.first->getEventCallback(); + StateAttributeCallback* callback = itr->second.first->getEventCallback(); if (callback) (*callback)(itr->second.first.get(),nv); } @@ -1758,7 +1758,7 @@ void StateSet::runEventCallbacks(osg::NodeVisitor* nv) itr!=attributeList.end(); ++itr) { - StateAttribute::Callback* callback = itr->second.first->getEventCallback(); + StateAttributeCallback* callback = itr->second.first->getEventCallback(); if (callback) (*callback)(itr->second.first.get(),nv); } } diff --git a/src/osgPlugins/osg/StateAttribute.cpp b/src/osgPlugins/osg/StateAttribute.cpp index 69293a834..57d7845a4 100644 --- a/src/osgPlugins/osg/StateAttribute.cpp +++ b/src/osgPlugins/osg/StateAttribute.cpp @@ -29,12 +29,12 @@ bool StateAttribute_readLocalData(Object& obj, Input& fr) bool iteratorAdvanced = false; StateAttribute& stateAttribute = static_cast(obj); - static ref_ptr s_callback = new osg::StateAttribute::Callback; + static ref_ptr s_callback = new osg::StateAttributeCallback; while (fr.matchSequence("UpdateCallback {")) { //int entry = fr[0].getNoNestedBrackets(); fr += 2; - StateAttribute::Callback* callback = dynamic_cast(fr.readObjectOfType(*s_callback)); + StateAttributeCallback* callback = dynamic_cast(fr.readObjectOfType(*s_callback)); if (callback) { stateAttribute.setUpdateCallback(callback); } @@ -45,7 +45,7 @@ bool StateAttribute_readLocalData(Object& obj, Input& fr) { //int entry = fr[0].getNoNestedBrackets(); fr += 2; - StateAttribute::Callback* callback = dynamic_cast(fr.readObjectOfType(*s_callback)); + StateAttributeCallback* callback = dynamic_cast(fr.readObjectOfType(*s_callback)); if (callback) { stateAttribute.setEventCallback(callback); }