/* -*-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_OBJECT #define OSG_OBJECT 1 #include #include #include #include #include #include namespace osg { // forward declare class State; #define _ADDQUOTES(def) #def #define ADDQUOTES(def) _ADDQUOTES(def) /** META_Object macro define the standard clone, isSameKindAs and className methods. * Use when subclassing from Object to make it more convenient to define * the standard pure virtual clone, isSameKindAs and className methods * which are required for all Object subclasses.*/ #define META_Object(library,name) \ virtual osg::Object* cloneType() const { return new name (); } \ virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new name (*this,copyop); } \ virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } \ virtual const char* libraryName() const { return #library; }\ virtual const char* className() const { return #name; } template T* clone(const T* t, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) { if (t) { osg::ref_ptr obj = t->clone(copyop); T* ptr = dynamic_cast(obj.get()); if (ptr) { obj.release(); return ptr; } else { OSG_WARN<<"Warning: osg::clone(const T*, osg::CopyOp&) cloned object not of type T, returning NULL."< T* clone(const T* t, const std::string& name, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) { T* newObject = osg::clone(t, copyop); if (newObject) { newObject->setName(name); return newObject; } else { OSG_WARN<<"Warning: osg::clone(const T*, const std::string&, const osg::CopyOp) passed null object to clone, returning NULL."< T* cloneType(const T* t) { if (t) { osg::ref_ptr obj = t->cloneType(); T* ptr = dynamic_cast(obj.get()); if (ptr) { obj.release(); return ptr; } else { OSG_WARN<<"Warning: osg::cloneType(const T*) cloned object not of type T, returning NULL."< and gets the value. * To use this template method you need to include the osg/ValueObject header.*/ template bool getUserValue(const std::string& name, T& value) const; /** Convinience method that creates the osg::TemplateValueObject to store the * specified value and adds it as a named UserObject. * To use this template method you need to include the osg/ValueObject header. */ template void setUserValue(const std::string& name, const T& value); /** A vector of std::string's which are used to describe the object.*/ typedef std::vector DescriptionList; /** Set the list of string descriptions.*/ void setDescriptions(const DescriptionList& descriptions); /** Get the description list of the node.*/ DescriptionList& getDescriptions(); /** Get the const description list of the const node.*/ const DescriptionList& getDescriptions() const; /** Get a single const description of the const node.*/ const std::string& getDescription(unsigned int i) const; /** Get a single description of the node.*/ std::string& getDescription(unsigned int i); /** Get the number of descriptions of the node.*/ unsigned int getNumDescriptions() const; /** Add a description string to the node.*/ void addDescription(const std::string& desc); /** Resize any per context GLObject buffers to specified size. */ virtual void resizeGLObjectBuffers(unsigned int /*maxSize*/) {} /** If State is non-zero, this function releases any associated OpenGL objects for * the specified graphics context. Otherwise, releases OpenGL objects * for all graphics contexts. */ virtual void releaseGLObjects(osg::State* = 0) const {} protected: /** Object destructor. Note, is protected so that Objects cannot be deleted other than by being dereferenced and the reference count being zero (see osg::Referenced), preventing the deletion of nodes which are still in use. This also means that Nodes cannot be created on stack i.e Node node will not compile, forcing all nodes to be created on the heap i.e Node* node = new Node().*/ virtual ~Object() {} std::string _name; DataVariance _dataVariance; /** Internal structure for storing all user data.*/ class OSG_EXPORT UserDataContainer : public osg::Referenced { public: UserDataContainer(); UserDataContainer(const UserDataContainer& udc, const osg::CopyOp& copyop=CopyOp::SHALLOW_COPY); virtual void setThreadSafeRefUnref(bool threadSafe); typedef std::vector< osg::ref_ptr > ObjectList; ref_ptr _userData; DescriptionList _descriptionList; ObjectList _objectList; protected: virtual ~UserDataContainer() {} }; ref_ptr _userDataContainer; /** Convinience method that returns the UserDataContainer, and if one doesn't already exist creates and assigns * one to the Object and then return this new UserDataContainer.*/ UserDataContainer* getOrCreateUserDataContainer() { if (!_userDataContainer.valid()) _userDataContainer = new UserDataContainer; return _userDataContainer.get(); } private: /** disallow any copy operator.*/ Object& operator = (const Object&) { return *this; } }; } #endif