diff --git a/include/osg/Identifier b/include/osg/Identifier new file mode 100644 index 000000000..c9ec853c7 --- /dev/null +++ b/include/osg/Identifier @@ -0,0 +1,68 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2014 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_IDENTIFER_H +#define OSG_IDENTIFER_H + +#include +#include + +#include +#include + +#define OSG_HAS_IDENTIFIER + +namespace osg +{ + +/** helper function for doing a case insenstive compare of two strings.*/ +inline bool iequals(const std::string& lhs, const std::string& rhs) +{ + if (lhs.size()!=rhs.size()) return false; + + for(std::string::size_type i=0; i +#include +#include + +namespace osg { + +#define OSG_HAS_VALUEMAP + +class OSG_EXPORT ValueMap : public osg::Object +{ + public: + + ValueMap(); + + ValueMap(const ValueMap& vm, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Object(osg, ValueMap) + + typedef std::map< osg::ref_ptr, osg::ref_ptr > KeyValueMap; + + void setKeyValueMap(KeyValueMap& properties) { _keyValueMap = properties; } + + KeyValueMap& getKeyValueMap() { return _keyValueMap; } + + const KeyValueMap& getKeyValueMap() const { return _keyValueMap; } + + osg::Object* setValue(const osg::Referenced* key, osg::Object* object) + { + return (_keyValueMap[key] = object).get(); + } + + template + osg::Object* setValue(const osg::Referenced* key, const T& value) + { + typedef TemplateValueObject UserValueObject; + KeyValueMap::iterator itr = _keyValueMap.find(key); + if (itr!=_keyValueMap.end() && typeid(*(itr->second))==typeid(UserValueObject)) + { + UserValueObject* uvo = static_cast(itr->second.get()); + uvo->setValue(value); + return uvo; + } + else + { + return (_keyValueMap[key] = new UserValueObject(value)).get(); + } + } + + + inline osg::Object* getValue(const osg::Referenced* key) + { + KeyValueMap::iterator itr = _keyValueMap.find(key); + return (itr!=_keyValueMap.end()) ? itr->second.get() : 0; + } + + inline const osg::Object* getValue(const osg::Referenced* key) const + { + KeyValueMap::const_iterator itr = _keyValueMap.find(key); + return (itr!=_keyValueMap.end()) ? itr->second.get() : 0; + } + + + template + T* getValueOfType(const osg::Referenced* key) + { + Object* object = getValue(key); + return (object && typeid(*object)==typeid(T)) ? static_cast(object) : 0; + } + + + template + const T* getValueOfType(const osg::Referenced* key) const + { + const Object* object = getValue(key); + return (object && typeid(*object)==typeid(T)) ? static_cast(object) : 0; + } + + + template + bool getValue(const osg::Referenced* key, T& value) + { + typedef TemplateValueObject UserValueObject; + UserValueObject* uvo = getValueOfType(key); + if (uvo) + { + value = uvo->getValue(); + return true; + } + else + { + return false; + } + } + + template + bool getValue(const osg::Referenced* key, T& value) const + { + typedef TemplateValueObject UserValueObject; + const UserValueObject* uvo = getValueOfType(key); + if (uvo) + { + value = uvo->getValue(); + return true; + } + else + { + return false; + } + } + + + protected: + + virtual ~ValueMap(); + + KeyValueMap _keyValueMap; + +}; + +} + +#endif diff --git a/include/osg/ValueStack b/include/osg/ValueStack new file mode 100644 index 000000000..b180f3b03 --- /dev/null +++ b/include/osg/ValueStack @@ -0,0 +1,167 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2016 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_VALUESTACK +#define OSG_VALUESTACK 1 + +#include + +namespace osg { + +#define OSG_HAS_VALUESTACK + +class OSG_EXPORT ValueStack : public osg::Object +{ + public: + + ValueStack(); + + ValueStack(const ValueStack& ps, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Object(osg, ValueStack) + + typedef std::vector< osg::ref_ptr > Values; + typedef std::map< osg::ref_ptr, Values> ValueStackMap; + + void setValueStackMap(ValueStackMap& pm) { _valuesMap = pm; } + + ValueStackMap& getValueStackMap() { return _valuesMap; } + + const ValueStackMap& getValueStackMap() const { return _valuesMap; } + + inline void push(const Referenced* key, Object* value) + { + _valuesMap[key].push_back(value); + } + + template + void push(const osg::Referenced* key, const T& value) + { + typedef TemplateValueObject UserValueObject; + _valuesMap[key].push_back(new UserValueObject(value)); + } + + inline void pop(const Referenced* key) + { + _valuesMap[key].pop_back(); + } + + inline void push(ValueMap* valueMap) + { + if (valueMap) + { + ValueMap::KeyValueMap& keyValueMap = valueMap->getKeyValueMap(); + for(ValueMap::KeyValueMap::iterator itr = keyValueMap.begin(); + itr != keyValueMap.end(); + ++itr) + { + push(itr->first.get(), itr->second.get()); + } + } + } + + inline void pop(ValueMap* valueMap) + { + if (valueMap) + { + ValueMap::KeyValueMap& keyValueMap = valueMap->getKeyValueMap(); + for(ValueMap::KeyValueMap::iterator itr = keyValueMap.begin(); + itr != keyValueMap.end(); + ++itr) + { + pop(itr->first.get()); + } + } + } + + inline osg::Object* getValue(const osg::Referenced* key) + { + ValueStackMap::iterator itr = _valuesMap.find(key); + if (itr==_valuesMap.end()) return 0; + + Values& values = itr->second; + if (values.empty()) return 0; + + return values.back().get(); + } + + inline const osg::Object* getValue(const osg::Referenced* key) const + { + ValueStackMap::const_iterator itr = _valuesMap.find(key); + if (itr==_valuesMap.end()) return 0; + + const Values& values = itr->second; + if (values.empty()) return 0; + + return values.back().get(); + } + + template + T* getValueOfType(const osg::Referenced* key) + { + Object* object = getValue(key); + return (object && typeid(*object)==typeid(T)) ? static_cast(object) : 0; + } + + + template + const T* getValueOfType(const osg::Referenced* key) const + { + const Object* object = getValue(key); + return (object && typeid(*object)==typeid(T)) ? static_cast(object) : 0; + } + + template + bool getValue(const osg::Referenced* key, T& value) + { + typedef TemplateValueObject UserValueObject; + UserValueObject* uvo = getValueOfType(key); + if (uvo) + { + value = uvo->getValue(); + return true; + } + else + { + return false; + } + } + + template + bool getValue(const osg::Referenced* key, T& value) const + { + typedef TemplateValueObject UserValueObject; + const UserValueObject* uvo = getValueOfType(key); + if (uvo) + { + value = uvo->getValue(); + return true; + } + else + { + return false; + } + } + + protected: + + virtual ~ValueStack(); + + ValueStackMap _valuesMap; + +}; + + +} + +#endif diff --git a/src/osg/Identifier.cpp b/src/osg/Identifier.cpp new file mode 100644 index 000000000..a6f8a8e83 --- /dev/null +++ b/src/osg/Identifier.cpp @@ -0,0 +1,123 @@ +#include + +#include +#include + +#include + +#include + +using namespace osg; + +struct IdentifierKey +{ + IdentifierKey(const std::string& str, int num, osg::Referenced* f, osg::Referenced* s): + name(str), + number(num), + first(f), + second(s) + { + } + + const std::string name; + const int number; + const osg::Referenced* first; + const osg::Referenced* second; + + bool operator < (const IdentifierKey& rhs) const + { + if (namerhs.name) return false; + + if (numberrhs.number) return false; + + if (firstrhs.first) return false; + + return (second > IdentifierMap; + +IdentifierMap s_IdentifierMap; +OpenThreads::Mutex s_IdentifierMapMutex; + +Identifier::Identifier(const std::string& name, int number, osg::Referenced* f, osg::Referenced* s): + _name(name), + _number(number), + _first(f), + _second(s) +{ + if (_first) _first->addObserver(this); + if (_second) _second->addObserver(this); +} + +Identifier::~Identifier() +{ + if (_first) _first->removeObserver(this); + if (_second) _second->removeObserver(this); +} + +void Identifier::objectDeleted(void* ptr) +{ + if (_first==ptr || _second==ptr) + { + IdentifierKey key(_name, _number, _first, _second); + + { + OpenThreads::ScopedLock lock(s_IdentifierMapMutex); + IdentifierMap::iterator itr = s_IdentifierMap.find(key); + if (itr!=s_IdentifierMap.end()) + { + OSG_NOTICE<<"Warning : this = "<removeObserver(this); + } + + if (_second==ptr && _first) + { + _first->removeObserver(this); + } + + _first = 0; + _second = 0; + } + +} + + +Identifier* osg::Identifier::get(const std::string& name, int number, osg::Referenced* first, osg::Referenced* second) +{ + IdentifierKey key(name, number, first, second); + + OpenThreads::ScopedLock lock(s_IdentifierMapMutex); + + IdentifierMap::iterator itr = s_IdentifierMap.find(key); + if (itr!=s_IdentifierMap.end()) return itr->second.get(); + + osg::ref_ptr identifier = new Identifier(name, number, first, second); + s_IdentifierMap[key] = identifier; + return identifier.get(); +} + +Identifier* osg::Identifier::get(int number, osg::Referenced* first, osg::Referenced* second) +{ + return get("", number, first, second); +} + +Identifier* osg::Identifier::get(osg::Referenced* first, osg::Referenced* second) +{ + return get("", 0, first, second); +} diff --git a/src/osg/ValueMap.cpp b/src/osg/ValueMap.cpp new file mode 100644 index 000000000..37b68f6dd --- /dev/null +++ b/src/osg/ValueMap.cpp @@ -0,0 +1,36 @@ +/* -*-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. +*/ +#include + +#include + +using namespace osg; + +ValueMap::ValueMap() +{ +} + +ValueMap::ValueMap(const ValueMap& vm, const osg::CopyOp& copyop): + osg::Object(vm, copyop) +{ + for(KeyValueMap::const_iterator itr = vm._keyValueMap.begin(); + itr != vm._keyValueMap.end(); + ++itr) + { + _keyValueMap[itr->first] = osg::clone(itr->second.get(), copyop); + } +} + +ValueMap::~ValueMap() +{ +} diff --git a/src/osg/ValueStack.cpp b/src/osg/ValueStack.cpp new file mode 100644 index 000000000..9346bbe4e --- /dev/null +++ b/src/osg/ValueStack.cpp @@ -0,0 +1,30 @@ +/* -*-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. +*/ +#include + +#include + +using namespace osg; + +ValueStack::ValueStack() +{ +} + +ValueStack::ValueStack(const ValueStack& ps, const osg::CopyOp& copyop): + osg::Object(ps, copyop) +{ +} + +ValueStack::~ValueStack() +{ +}