Added type maps to help with querrying supported type names

This commit is contained in:
Robert Osfield
2013-09-20 10:04:50 +00:00
parent 250d9f2ed7
commit 6e3f893a0e
3 changed files with 192 additions and 136 deletions

View File

@@ -161,66 +161,9 @@ int main(int argc, char** argv)
osgDB::writeNodeFile(*presentation, "pres.osgt");
osgDB::PropertyInterface pi;
typedef std::map<int, std::string> 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<int> types;
osgDB::ObjectWrapper::TypeList types;
ow->writeSchema(properties, types);
OSG_NOTICE<<" properties.size() = "<<properties.size()<<", types.size() = "<<types.size()<<std::endl;
unsigned int numProperties = std::min(properties.size(), types.size());
for(unsigned int i=0; i<numProperties; ++i)
{
OSG_NOTICE<<" property = "<<properties[i]<<", type = "<<types[i]<<", typeName = "<<typeNameMap[types[i]]<<std::endl;
OSG_NOTICE<<" property = "<<properties[i]<<", type = "<<types[i]<<", typeName = "<<pi.getTypeName(types[i])<<std::endl;
}
}
#if 0
#if 1
osgDB::ObjectWrapperManager::IntLookupMap& intLookupMap = owm->getLookupMap();
for(osgDB::ObjectWrapperManager::IntLookupMap::iterator itr = intLookupMap.begin();
itr != intLookupMap.end();
@@ -275,7 +218,6 @@ int main(int argc, char** argv)
#endif
presentation->setName("[this is a test]");
osgDB::PropertyInterface pi;
if (pi.setProperty(presentation.get(), "Name", std::string("[this is new improved test]")))
{
OSG_NOTICE<<"setProperty(presentation.get(), Name) succeeded."<<std::endl;
@@ -359,11 +301,11 @@ int main(int argc, char** argv)
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
osg::ref_ptr<osg::Node> 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."<<std::endl;
for(osgDB::PropertyInterface::PropertyList::iterator itr = properties.begin();
for(osgDB::PropertyInterface::PropertyMap::iterator itr = properties.begin();
itr != properties.end();
++itr)
{
@@ -438,7 +380,7 @@ int main(int argc, char** argv)
osgDB::BaseSerializer::Type type; \
if (pi.getPropertyType(O, #PN, type)) \
{ \
OSG_NOTICE<<#PN<<" : type "<<type<<", "<<typeNameMap[type]<<std::endl; \
OSG_NOTICE<<#PN<<" : type "<<type<<", "<<pi.getTypeName(type)<<std::endl; \
} \
else \
{ \

View File

@@ -109,73 +109,99 @@ DECLARE_TYPE(osg::Vec4ui, VEC4UI)
class PropertyOutputIterator;
class PropertyInputIterator;
/** PropertyInterface provides a general means of checking for supported properties of classes, and getting/setting thoses properties.
Uses the osgDB serializers to do the actual object querry/get/set.
*/
class OSGDB_EXPORT PropertyInterface
{
public:
PropertyInterface();
typedef std::pair<std::string, osgDB::BaseSerializer::Type> PropertyNameTypePair;
typedef std::list<PropertyNameTypePair> 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<typename T>
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<typename T>
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<std::string, osgDB::BaseSerializer::Type> 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<std::string, PropertyMap> 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<std::string, osgDB::BaseSerializer::Type> TypeNameToTypeMap;
typedef std::map<osgDB::BaseSerializer::Type, std::string> TypeToTypeNameMap;
TypeNameToTypeMap _typeNameToTypeMap;
TypeToTypeNameMap _typeToTypeNameMap;
ObjectPropertyMap _whiteList;
ObjectPropertyMap _blackList;
};
template<typename T>
bool PropertyInterface::getProperty(const osg::Object* object, const std::string& propertyName, T& value)
{
if (copyPropertyDataFromObject(object, propertyName, &value, sizeof(T), getTypeEnum<T>()))
{
return true;
}
else
{
// fallback to check user data for property
return object->getUserValue(propertyName, value);
}
if (copyPropertyDataFromObject(object, propertyName, &value, sizeof(T), getTypeEnum<T>())) return true;
else return object->getUserValue(propertyName, value); // fallback to check user data for property
}
template<typename T>
bool PropertyInterface::setProperty(osg::Object* object, const std::string& propertyName, const T& value)
{
if (copyPropertyDataToObject(object, propertyName, &value, sizeof(T), getTypeEnum<T>()))
{
return true;
}
if (copyPropertyDataToObject(object, propertyName, &value, sizeof(T), getTypeEnum<T>())) return true;
else
{
// fallback to using user data to store property data

View File

@@ -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