From 6e3f893a0e19c2dfd887f1cf9c7628464f7484bb Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 20 Sep 2013 10:04:50 +0000 Subject: [PATCH] Added type maps to help with querrying supported type names --- examples/osgpresentation/osgpresentation.cpp | 74 +------- include/osgDB/PropertyInterface | 82 ++++++--- src/osgDB/PropertyInterface.cpp | 172 ++++++++++++++----- 3 files changed, 192 insertions(+), 136 deletions(-) diff --git a/examples/osgpresentation/osgpresentation.cpp b/examples/osgpresentation/osgpresentation.cpp index 244c04127..cba25a9cc 100644 --- a/examples/osgpresentation/osgpresentation.cpp +++ b/examples/osgpresentation/osgpresentation.cpp @@ -161,66 +161,9 @@ int main(int argc, char** argv) osgDB::writeNodeFile(*presentation, "pres.osgt"); + osgDB::PropertyInterface pi; - typedef std::map TypeNameMap; - TypeNameMap typeNameMap; - -#define TYPENAME(A) typeNameMap[osgDB::BaseSerializer::A] = #A; - - - TYPENAME(RW_UNDEFINED) - TYPENAME(RW_USER) - TYPENAME(RW_OBJECT) - TYPENAME(RW_IMAGE) - TYPENAME(RW_LIST) - - TYPENAME(RW_BOOL) - TYPENAME(RW_CHAR) - TYPENAME(RW_UCHAR) - TYPENAME(RW_SHORT) - TYPENAME(RW_USHORT) - TYPENAME(RW_INT) - TYPENAME(RW_UINT) - TYPENAME(RW_FLOAT) - TYPENAME(RW_DOUBLE) - - TYPENAME(RW_VEC2F) - TYPENAME(RW_VEC2D) - TYPENAME(RW_VEC3F) - TYPENAME(RW_VEC3D) - TYPENAME(RW_VEC4F) - TYPENAME(RW_VEC4D) - TYPENAME(RW_QUAT) - TYPENAME(RW_PLANE) - - TYPENAME(RW_MATRIXF) - TYPENAME(RW_MATRIXD) - TYPENAME(RW_MATRIX) - TYPENAME(RW_GLENUM) - TYPENAME(RW_STRING) - TYPENAME(RW_ENUM) - - TYPENAME(RW_VEC2B) - TYPENAME(RW_VEC2UB) - TYPENAME(RW_VEC2S) - TYPENAME(RW_VEC2US) - TYPENAME(RW_VEC2I) - TYPENAME(RW_VEC2UI) - - TYPENAME(RW_VEC3B) - TYPENAME(RW_VEC3UB) - TYPENAME(RW_VEC3S) - TYPENAME(RW_VEC3US) - TYPENAME(RW_VEC3I) - TYPENAME(RW_VEC3UI) - - TYPENAME(RW_VEC4B) - TYPENAME(RW_VEC4UB) - TYPENAME(RW_VEC4S) - TYPENAME(RW_VEC4US) - TYPENAME(RW_VEC4I) - TYPENAME(RW_VEC4UI) -#if 0 +#if 1 osgDB::ObjectWrapperManager* owm = osgDB::Registry::instance()->getObjectWrapperManager(); if (owm) { @@ -243,19 +186,19 @@ int main(int argc, char** argv) osgDB::StringList properties; - std::vector types; + osgDB::ObjectWrapper::TypeList types; ow->writeSchema(properties, types); OSG_NOTICE<<" properties.size() = "< geometry = new osg::Geometry; osg::ref_ptr node = new osg::Node; - osgDB::PropertyInterface::PropertyList properties; + osgDB::PropertyInterface::PropertyMap properties; if (pi.getSupportedProperties(presentation.get(), properties, true)) { OSG_NOTICE<<"Have supported properites found."< PropertyNameTypePair; - typedef std::list PropertyList; - bool getSupportedProperties(const osg::Object* object, PropertyList& properties, bool searchAssociates=true); - - bool getPropertyType(const osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type& type); + /// get the Type of the specified property, return true if property is supported, otherwise false. + bool getPropertyType(const osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type& type) const; + /// return type of two types are compatible bool areTypesCompatible(osgDB::BaseSerializer::Type lhs, osgDB::BaseSerializer::Type rhs) const; + + /// template method for getting property data, return true if property available and the type is compatible, otherwise returns false. template bool getProperty(const osg::Object* object, const std::string& propertyName, T& value); + /// template method for setting property data, return true if property available and the type is compatible, otherwise returns false. template bool setProperty(osg::Object* object, const std::string& propertyName, const T& value); + + /// get the human readable name of type. + std::string getTypeName(osgDB::BaseSerializer::Type type) const; + + /// get the enum value of type given the human readable name. + osgDB::BaseSerializer::Type getType(const std::string& typeName) const; + + + /// Properties supported for a single class + typedef std::map PropertyMap; + + /// Get the list of of properties supported by object + bool getSupportedProperties(const osg::Object* object, PropertyMap& properties, bool searchAssociates=true) const; + + + /// Properties supported for a range of classes, used for white and black lists + typedef std::map ObjectPropertyMap; + + /// Get the list of properties that are explictly defined as supported + ObjectPropertyMap& getWhiteList() { return _whiteList; } + + /// Get the const list of properties that are explictly defined as supported + const ObjectPropertyMap& getWhiteList() const { return _whiteList; } + + /// Get the list of properties that are explictly defined as not supported + ObjectPropertyMap& getBlackList() { return _blackList; } + + /// Get the const list of properties that are explictly defined as not supported + const ObjectPropertyMap& getBlackList() const { return _blackList; } + protected: bool copyPropertyDataFromObject(const osg::Object* object, const std::string& propertyName, void* valuePtr, unsigned int valueSize, osgDB::BaseSerializer::Type valueType); bool copyPropertyDataToObject(osg::Object* object, const std::string& propertyName, const void* valuePtr, unsigned int valueSize, osgDB::BaseSerializer::Type valueType); - osgDB::ObjectWrapper* getObjectWrapper(const osg::Object* object) const - { - std::string compoundClassName = std::string(object->libraryName()) + std::string("::") + std::string(object->className()); - return osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper(compoundClassName); - } + osgDB::ObjectWrapper* getObjectWrapper(const osg::Object* object) const; - osgDB::BaseSerializer* getSerializer(const osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type& type) const - { - osgDB::ObjectWrapper* ow = getObjectWrapper(object); - return ow ? ow->getSerializer(propertyName, type) : 0; - } + osgDB::BaseSerializer* getSerializer(const osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type& type) const; osgDB::OutputStream _outputStream; PropertyOutputIterator* _poi; osgDB::InputStream _inputStream; PropertyInputIterator* _pii; + + typedef std::map TypeNameToTypeMap; + typedef std::map TypeToTypeNameMap; + + TypeNameToTypeMap _typeNameToTypeMap; + TypeToTypeNameMap _typeToTypeNameMap; + + ObjectPropertyMap _whiteList; + ObjectPropertyMap _blackList; }; template bool PropertyInterface::getProperty(const osg::Object* object, const std::string& propertyName, T& value) { - if (copyPropertyDataFromObject(object, propertyName, &value, sizeof(T), getTypeEnum())) - { - return true; - } - else - { - // fallback to check user data for property - return object->getUserValue(propertyName, value); - } + if (copyPropertyDataFromObject(object, propertyName, &value, sizeof(T), getTypeEnum())) return true; + else return object->getUserValue(propertyName, value); // fallback to check user data for property } template bool PropertyInterface::setProperty(osg::Object* object, const std::string& propertyName, const T& value) { - if (copyPropertyDataToObject(object, propertyName, &value, sizeof(T), getTypeEnum())) - { - return true; - } + if (copyPropertyDataToObject(object, propertyName, &value, sizeof(T), getTypeEnum())) return true; else { // fallback to using user data to store property data diff --git a/src/osgDB/PropertyInterface.cpp b/src/osgDB/PropertyInterface.cpp index 205306a6c..ddab58051 100644 --- a/src/osgDB/PropertyInterface.cpp +++ b/src/osgDB/PropertyInterface.cpp @@ -173,6 +173,65 @@ PropertyInterface::PropertyInterface(): _pii = new PropertyInputIterator; _inputStream.setInputIterator(_pii); + + + // initialize the type maps + #define TYPENAME(A) \ + _typeToTypeNameMap[osgDB::BaseSerializer::RW_##A] = #A; \ + _typeNameToTypeMap[#A] = osgDB::BaseSerializer::RW_##A; + + TYPENAME(UNDEFINED) + TYPENAME(USER) + TYPENAME(OBJECT) + TYPENAME(IMAGE) + TYPENAME(LIST) + + TYPENAME(BOOL) + TYPENAME(CHAR) + TYPENAME(UCHAR) + TYPENAME(SHORT) + TYPENAME(USHORT) + TYPENAME(INT) + TYPENAME(UINT) + TYPENAME(FLOAT) + TYPENAME(DOUBLE) + + TYPENAME(VEC2F) + TYPENAME(VEC2D) + TYPENAME(VEC3F) + TYPENAME(VEC3D) + TYPENAME(VEC4F) + TYPENAME(VEC4D) + TYPENAME(QUAT) + TYPENAME(PLANE) + + TYPENAME(MATRIXF) + TYPENAME(MATRIXD) + TYPENAME(MATRIX) + TYPENAME(GLENUM) + TYPENAME(STRING) + TYPENAME(ENUM) + + TYPENAME(VEC2B) + TYPENAME(VEC2UB) + TYPENAME(VEC2S) + TYPENAME(VEC2US) + TYPENAME(VEC2I) + TYPENAME(VEC2UI) + + TYPENAME(VEC3B) + TYPENAME(VEC3UB) + TYPENAME(VEC3S) + TYPENAME(VEC3US) + TYPENAME(VEC3I) + TYPENAME(VEC3UI) + + TYPENAME(VEC4B) + TYPENAME(VEC4UB) + TYPENAME(VEC4S) + TYPENAME(VEC4US) + TYPENAME(VEC4I) + TYPENAME(VEC4UI) } @@ -197,49 +256,31 @@ bool PropertyInterface::areTypesCompatible(osgDB::BaseSerializer::Type lhs, osgD return lhs==rhs; } -bool PropertyInterface::getSupportedProperties(const osg::Object* object, PropertyList& properties, bool searchAssociates) +std::string PropertyInterface::getTypeName(osgDB::BaseSerializer::Type type) const +{ + TypeToTypeNameMap::const_iterator itr = _typeToTypeNameMap.find(type); + if (itr != _typeToTypeNameMap.end()) return itr->second; + else return std::string(); +} + +osgDB::BaseSerializer::Type PropertyInterface::getType(const std::string& typeName) const +{ + TypeNameToTypeMap::const_iterator itr = _typeNameToTypeMap.find(typeName); + if (itr != _typeNameToTypeMap.end()) return itr->second; + else return osgDB::BaseSerializer::RW_UNDEFINED; +} + + +osgDB::ObjectWrapper* PropertyInterface::getObjectWrapper(const osg::Object* object) const +{ + std::string compoundClassName = std::string(object->libraryName()) + std::string("::") + std::string(object->className()); + return osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper(compoundClassName); +} + +osgDB::BaseSerializer* PropertyInterface::getSerializer(const osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type& type) const { osgDB::ObjectWrapper* ow = getObjectWrapper(object); - if (!ow) - { - return false; - } - - if (searchAssociates) - { - const osgDB::StringList& associates = ow->getAssociates(); - for(osgDB::StringList::const_iterator aitr = associates.begin(); - aitr != associates.end(); - ++aitr) - { - osgDB::ObjectWrapper* associate_wrapper = osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper(*aitr); - if (associate_wrapper) - { - const osgDB::ObjectWrapper::SerializerList& associate_serializers = associate_wrapper->getSerializerList(); - unsigned int i=0; - for(osgDB::ObjectWrapper::SerializerList::const_iterator sitr = associate_serializers.begin(); - sitr != associate_serializers.end(); - ++sitr, ++i) - { - properties.push_back(PropertyNameTypePair((*sitr)->getName(), associate_wrapper->getTypeList()[i])); - } - } - } - } - else - { - const osgDB::ObjectWrapper::SerializerList& serializers = ow->getSerializerList(); - unsigned int i=0; - for(osgDB::ObjectWrapper::SerializerList::const_iterator itr = serializers.begin(); - itr != serializers.end(); - ++itr) - { - properties.push_back(PropertyNameTypePair((*itr)->getName(), ow->getTypeList()[i])); - } - } - - - return true; + return ow ? ow->getSerializer(propertyName, type) : 0; } bool PropertyInterface::copyPropertyDataFromObject(const osg::Object* object, const std::string& propertyName, void* valuePtr, unsigned int valueSize, osgDB::BaseSerializer::Type valueType) @@ -324,7 +365,7 @@ public: virtual void apply(const osg::Matrixd& /*value*/) { type = osgDB::BaseSerializer::RW_MATRIXD; } }; -bool PropertyInterface::getPropertyType(const osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type& type) +bool PropertyInterface::getPropertyType(const osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type& type) const { if (getSerializer(object, propertyName, type)!=0) return true; @@ -344,6 +385,53 @@ bool PropertyInterface::getPropertyType(const osg::Object* object, const std::st return false; } + +bool PropertyInterface::getSupportedProperties(const osg::Object* object, PropertyMap& properties, bool searchAssociates) const +{ + osgDB::ObjectWrapper* ow = getObjectWrapper(object); + if (!ow) + { + return false; + } + + if (searchAssociates) + { + const osgDB::StringList& associates = ow->getAssociates(); + for(osgDB::StringList::const_iterator aitr = associates.begin(); + aitr != associates.end(); + ++aitr) + { + osgDB::ObjectWrapper* associate_wrapper = osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper(*aitr); + if (associate_wrapper) + { + const osgDB::ObjectWrapper::SerializerList& associate_serializers = associate_wrapper->getSerializerList(); + unsigned int i=0; + for(osgDB::ObjectWrapper::SerializerList::const_iterator sitr = associate_serializers.begin(); + sitr != associate_serializers.end(); + ++sitr, ++i) + { + properties[(*sitr)->getName()] = associate_wrapper->getTypeList()[i]; + } + } + } + } + else + { + const osgDB::ObjectWrapper::SerializerList& serializers = ow->getSerializerList(); + unsigned int i=0; + for(osgDB::ObjectWrapper::SerializerList::const_iterator itr = serializers.begin(); + itr != serializers.end(); + ++itr) + { + properties[(*itr)->getName()] = ow->getTypeList()[i]; + } + } + + + return true; +} + + } // end of osgDB namespace