Refactored osgDB::Input::readObjectOfType to use a template, and updated associated wrappers to avoid using local static's

This commit is contained in:
Robert Osfield 2012-11-21 13:38:11 +00:00
parent ea9e13a0c6
commit 3a67eefd9f
12 changed files with 129 additions and 122 deletions

View File

@ -29,7 +29,25 @@
namespace osgDB {
struct basic_type_wrapper;
/** basic structure for custom runtime inheritance checking */
struct basic_type_wrapper {
virtual ~basic_type_wrapper() {}
virtual bool matches(const osg::Object *proto) const = 0;
};
/** a class template that checks inheritance between a given
Object's class and a class defined at compile time through
the template parameter T.
This is used in conjunction with readObjectOfType() to
specify an abstract class as reference type.
**/
template<class T>
struct type_wrapper: basic_type_wrapper {
bool matches(const osg::Object *proto) const
{
return dynamic_cast<const T*>(proto) != 0;
}
};
/** deprecated. */
class OSGDB_EXPORT Field
@ -255,6 +273,13 @@ class OSGDB_EXPORT Input : public FieldReaderIterator
virtual osg::Object* readObjectOfType(const osg::Object& compObj);
virtual osg::Object* readObjectOfType(const basic_type_wrapper &btw);
template<typename T>
inline T* readObjectOfType()
{
return dynamic_cast<T*>(readObjectOfType(osgDB::type_wrapper<T>()));
}
virtual osg::Object* readObject();
virtual osg::Image* readImage();
virtual osg::Drawable* readDrawable();

View File

@ -40,25 +40,6 @@ extern "C"
namespace osgDB {
/** basic structure for custom runtime inheritance checking */
struct basic_type_wrapper {
virtual ~basic_type_wrapper() {}
virtual bool matches(const osg::Object *proto) const = 0;
};
/** a class template that checks inheritance between a given
Object's class and a class defined at compile time through
the template parameter T.
This is used in conjunction with readObjectOfType() to
specify an abstract class as reference type.
**/
template<class T>
struct type_wrapper: basic_type_wrapper {
bool matches(const osg::Object *proto) const
{
return dynamic_cast<const T*>(proto) != 0;
}
};
/**
Registry is a singleton factory which stores

View File

@ -198,12 +198,10 @@ bool AnimationPathCallback_readLocalData(osg::Object &obj, osgDB::Input &fr)
iteratorAdvanced = true;
}
static osg::ref_ptr<osg::AnimationPath> s_path = new osg::AnimationPath;
ref_ptr<osg::Object> object = fr.readObjectOfType(*s_path);
if (object.valid())
osg::ref_ptr<osg::AnimationPath> animpath = fr.readObjectOfType<osg::AnimationPath>();
if (animpath.valid())
{
osg::AnimationPath* animpath = dynamic_cast<osg::AnimationPath*>(object.get());
if (animpath) apc->setAnimationPath(animpath);
apc->setAnimationPath(animpath.get());
iteratorAdvanced = true;
}

View File

@ -45,9 +45,7 @@ bool CoordinateSystemNode_readLocalData(Object& obj, Input& fr)
fr+=2;
}
static ref_ptr<EllipsoidModel> s_ellipsoidModel = new EllipsoidModel;
EllipsoidModel* em = static_cast<EllipsoidModel*>(fr.readObjectOfType(*s_ellipsoidModel));
EllipsoidModel* em = fr.readObjectOfType<osg::EllipsoidModel>();
if (em) csn.setEllipsoidModel(em);
return iteratorAdvanced;

View File

@ -27,35 +27,35 @@ bool Drawable_readLocalData(Object& obj, Input& fr)
Drawable& drawable = static_cast<Drawable&>(obj);
static ref_ptr<StateSet> s_drawstate = new osg::StateSet;
if (StateSet* readState = static_cast<StateSet*>(fr.readObjectOfType(*s_drawstate)))
osg::StateSet* readState = fr.readObjectOfType<osg::StateSet>();
if (readState)
{
drawable.setStateSet(readState);
iteratorAdvanced = true;
}
Shape* shape = static_cast<Shape *>(fr.readObjectOfType(type_wrapper<Shape>()));
Shape* shape = fr.readObjectOfType<Shape>();
if (shape)
{
drawable.setShape(shape);
iteratorAdvanced = true;
}
Drawable::UpdateCallback* uc = dynamic_cast<Drawable::UpdateCallback *>(fr.readObjectOfType(type_wrapper<Drawable::UpdateCallback>()));
Drawable::UpdateCallback* uc = fr.readObjectOfType<Drawable::UpdateCallback>();
if (uc)
{
drawable.setUpdateCallback(uc);
iteratorAdvanced = true;
}
Drawable::CullCallback* cc = dynamic_cast<Drawable::CullCallback *>(fr.readObjectOfType(type_wrapper<Drawable::CullCallback>()));
Drawable::CullCallback* cc = fr.readObjectOfType<Drawable::CullCallback>();
if (cc)
{
drawable.setCullCallback(cc);
iteratorAdvanced = true;
}
Drawable::DrawCallback* dc = dynamic_cast<Drawable::DrawCallback *>(fr.readObjectOfType(type_wrapper<Drawable::DrawCallback>()));
Drawable::DrawCallback* dc = fr.readObjectOfType<Drawable::DrawCallback>();
if (dc)
{
drawable.setDrawCallback(dc);
@ -76,7 +76,7 @@ bool Drawable_readLocalData(Object& obj, Input& fr)
iteratorAdvanced = true;
}
Drawable::ComputeBoundingBoxCallback* cbc = dynamic_cast<Drawable::ComputeBoundingBoxCallback *>(fr.readObjectOfType(type_wrapper<Drawable::ComputeBoundingBoxCallback>()));
Drawable::ComputeBoundingBoxCallback* cbc = fr.readObjectOfType<Drawable::ComputeBoundingBoxCallback>();
if (cbc)
{
drawable.setComputeBoundingBoxCallback(cbc);

View File

@ -74,15 +74,14 @@ bool Node_readLocalData(Object& obj, Input& fr)
iteratorAdvanced = true;
}
static ref_ptr<StateSet> s_drawstate = new osg::StateSet;
if (StateSet* readState = static_cast<StateSet*>(fr.readObjectOfType(*s_drawstate)))
StateSet* readState = fr.readObjectOfType<StateSet>();
if (readState)
{
node.setStateSet(readState);
iteratorAdvanced = true;
}
static ref_ptr<NodeCallback> s_nodecallback = new osg::NodeCallback;
while (fr.matchSequence("UpdateCallback {"))
{
int entry = fr[0].getNoNestedBrackets();
@ -90,7 +89,7 @@ bool Node_readLocalData(Object& obj, Input& fr)
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
{
NodeCallback* nodecallback = dynamic_cast<NodeCallback*>(fr.readObjectOfType(*s_nodecallback));
NodeCallback* nodecallback = fr.readObjectOfType<NodeCallback>();
if (nodecallback) {
if (node.getUpdateCallback() == NULL) {
node.setUpdateCallback(nodecallback);
@ -111,7 +110,7 @@ bool Node_readLocalData(Object& obj, Input& fr)
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
{
NodeCallback* nodecallback = dynamic_cast<NodeCallback*>(fr.readObjectOfType(*s_nodecallback));
NodeCallback* nodecallback = fr.readObjectOfType<NodeCallback>();
if (nodecallback) {
if (node.getEventCallback() == NULL) {
node.setEventCallback(nodecallback);
@ -132,7 +131,7 @@ bool Node_readLocalData(Object& obj, Input& fr)
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
{
NodeCallback* nodecallback = dynamic_cast<NodeCallback*>(fr.readObjectOfType(*s_nodecallback));
NodeCallback* nodecallback = fr.readObjectOfType<NodeCallback>();
if (nodecallback) {
if (node.getCullCallback() == NULL) {
node.setCullCallback(nodecallback);
@ -165,7 +164,7 @@ bool Node_readLocalData(Object& obj, Input& fr)
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
{
Node::ComputeBoundingSphereCallback* callback = dynamic_cast<Node::ComputeBoundingSphereCallback*>(fr.readObjectOfType(type_wrapper<Node::ComputeBoundingSphereCallback>()));
Node::ComputeBoundingSphereCallback* callback = fr.readObjectOfType<Node::ComputeBoundingSphereCallback>();
if (callback) {
node.setComputeBoundingSphereCallback(callback);
}

View File

@ -28,12 +28,10 @@ bool NodeCallback_readLocalData(osg::Object &obj, osgDB::Input &fr)
bool itrAdvanced = false;
static osg::ref_ptr<NodeCallback> s_nc = new NodeCallback;
osg::ref_ptr<osg::Object> object = fr.readObjectOfType(*s_nc);
if (object.valid())
NodeCallback* ncc = fr.readObjectOfType<NodeCallback>();
if (ncc)
{
NodeCallback* ncc = dynamic_cast<NodeCallback*>(object.get());
if (ncc) nc.setNestedCallback(ncc);
nc.setNestedCallback(ncc);
itrAdvanced = true;
}

View File

@ -27,10 +27,7 @@ bool OccluderNode_readLocalData(Object& obj, Input& fr)
OccluderNode& occludernode = static_cast<OccluderNode&>(obj);
static ref_ptr<ConvexPlanarOccluder> s_occluder = new ConvexPlanarOccluder;
ConvexPlanarOccluder* tmpOccluder = static_cast<ConvexPlanarOccluder*>(fr.readObjectOfType(*s_occluder));
ConvexPlanarOccluder* tmpOccluder = fr.readObjectOfType<ConvexPlanarOccluder>();
if (tmpOccluder)
{
occludernode.setOccluder(tmpOccluder);

View File

@ -29,12 +29,11 @@ bool StateAttribute_readLocalData(Object& obj, Input& fr)
bool iteratorAdvanced = false;
StateAttribute& stateAttribute = static_cast<StateAttribute&>(obj);
static ref_ptr<StateAttributeCallback> s_callback = new osg::StateAttributeCallback;
while (fr.matchSequence("UpdateCallback {"))
{
//int entry = fr[0].getNoNestedBrackets();
fr += 2;
StateAttributeCallback* callback = dynamic_cast<StateAttributeCallback*>(fr.readObjectOfType(*s_callback));
StateAttributeCallback* callback = fr.readObjectOfType<StateAttributeCallback>();
if (callback) {
stateAttribute.setUpdateCallback(callback);
}
@ -45,7 +44,7 @@ bool StateAttribute_readLocalData(Object& obj, Input& fr)
{
//int entry = fr[0].getNoNestedBrackets();
fr += 2;
StateAttributeCallback* callback = dynamic_cast<StateAttributeCallback*>(fr.readObjectOfType(*s_callback));
StateAttributeCallback* callback = fr.readObjectOfType<StateAttributeCallback>();
if (callback) {
stateAttribute.setEventCallback(callback);
}

View File

@ -65,26 +65,61 @@ REGISTER_DOTOSGWRAPPER(GeoState)
//
// Set up the maps from name to GLMode and visa versa.
//
typedef std::map<std::string,StateAttribute::GLMode> GLNameToGLModeMap;
typedef std::map<StateAttribute::GLMode,std::string> GLModeToGLNameMap;
typedef std::set<StateAttribute::GLMode> TextureGLModeSet;
GLNameToGLModeMap s_GLNameToGLModeMap;
GLModeToGLNameMap s_GLModeToGLNameMap;
TextureGLModeSet s_TextureGLModeSet;
#define ADD_NAME(name,mode) _GLNameToGLModeMap[name]=mode; _GLModeToGLNameMap[mode]=name;
#define ADD_NAME(name,mode) s_GLNameToGLModeMap[name]=mode; s_GLModeToGLNameMap[mode]=name;
void initGLNames()
struct ModesAndNames
{
static bool first_time = true;
if (!first_time) return;
ModesAndNames();
static OpenThreads::Mutex s_initGLNames;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_initGLNames);
typedef std::map<std::string,StateAttribute::GLMode> GLNameToGLModeMap;
typedef std::map<StateAttribute::GLMode,std::string> GLModeToGLNameMap;
typedef std::set<StateAttribute::GLMode> TextureGLModeSet;
if (!first_time) return;
inline bool isTextureMode(int mode) const
{
return _TextureGLModeSet.find(mode)!=_TextureGLModeSet.end();
}
inline bool getGLModeForName(const std::string& str, osg::StateAttribute::GLMode& mode) const
{
GLNameToGLModeMap::const_iterator nitr = _GLNameToGLModeMap.find(str);
if (nitr!=_GLNameToGLModeMap.end())
{
mode = nitr->second;
return true;
}
else
{
return false;
}
}
inline bool getNameForGLMode(const osg::StateAttribute::GLMode& mode, std::string& str) const
{
GLModeToGLNameMap::const_iterator nitr = _GLModeToGLNameMap.find(mode);
if (nitr!=_GLModeToGLNameMap.end())
{
str = nitr->second;
return true;
}
else
{
return false;
}
}
GLNameToGLModeMap _GLNameToGLModeMap;
GLModeToGLNameMap _GLModeToGLNameMap;
TextureGLModeSet _TextureGLModeSet;
};
static ModesAndNames s_ModesAndNames;
ModesAndNames::ModesAndNames()
{
ADD_NAME("GL_ALPHA_TEST",GL_ALPHA_TEST)
ADD_NAME("GL_BLEND",GL_BLEND)
ADD_NAME("GL_COLOR_MATERIAL",GL_COLOR_MATERIAL)
@ -138,17 +173,17 @@ void initGLNames()
ADD_NAME("GL_VERTEX_PROGRAM_POINT_SIZE", GL_VERTEX_PROGRAM_POINT_SIZE)
ADD_NAME("GL_VERTEX_PROGRAM_TWO_SIDE", GL_VERTEX_PROGRAM_TWO_SIDE)
s_TextureGLModeSet.insert(GL_TEXTURE_1D);
s_TextureGLModeSet.insert(GL_TEXTURE_2D);
s_TextureGLModeSet.insert(GL_TEXTURE_3D);
_TextureGLModeSet.insert(GL_TEXTURE_1D);
_TextureGLModeSet.insert(GL_TEXTURE_2D);
_TextureGLModeSet.insert(GL_TEXTURE_3D);
s_TextureGLModeSet.insert(GL_TEXTURE_CUBE_MAP);
s_TextureGLModeSet.insert(GL_TEXTURE_RECTANGLE);
_TextureGLModeSet.insert(GL_TEXTURE_CUBE_MAP);
_TextureGLModeSet.insert(GL_TEXTURE_RECTANGLE);
s_TextureGLModeSet.insert(GL_TEXTURE_GEN_Q);
s_TextureGLModeSet.insert(GL_TEXTURE_GEN_R);
s_TextureGLModeSet.insert(GL_TEXTURE_GEN_S);
s_TextureGLModeSet.insert(GL_TEXTURE_GEN_T);
_TextureGLModeSet.insert(GL_TEXTURE_GEN_Q);
_TextureGLModeSet.insert(GL_TEXTURE_GEN_R);
_TextureGLModeSet.insert(GL_TEXTURE_GEN_S);
_TextureGLModeSet.insert(GL_TEXTURE_GEN_T);
// for(GLNameToGLModeMap::iterator itr=s_GLNameToGLModeMap.begin();
@ -157,8 +192,6 @@ void initGLNames()
// {
// cout << "Name ["<<itr->first<<","<<itr->second<<"]"<< std::endl;
// }
first_time = false;
}
@ -294,8 +327,6 @@ bool StateSet_readLocalData(Object& obj, Input& fr)
// note, StateSet replaced GeoState April 2001.
StateSet& stateset = static_cast<StateSet&>(obj);
initGLNames();
// read the rendering hint value.
if (fr[0].matchWord("rendering_hint"))
{
@ -359,12 +390,11 @@ bool StateSet_readLocalData(Object& obj, Input& fr)
stateset.setRenderBinDetails(binNumber,binName,rbmode);
}
static ref_ptr<StateSet::Callback> s_callback = new osg::StateSet::Callback;
while (fr.matchSequence("UpdateCallback {"))
{
// int entry = fr[0].getNoNestedBrackets();
fr += 2;
StateSet::Callback* callback = dynamic_cast<StateSet::Callback*>(fr.readObjectOfType(*s_callback));
StateSet::Callback* callback = fr.readObjectOfType<StateSet::Callback>();
if (callback) {
stateset.setUpdateCallback(callback);
}
@ -375,7 +405,7 @@ bool StateSet_readLocalData(Object& obj, Input& fr)
{
//int entry = fr[0].getNoNestedBrackets();
fr += 2;
StateSet::Callback* callback = dynamic_cast<StateSet::Callback*>(fr.readObjectOfType(*s_callback));
StateSet::Callback* callback = fr.readObjectOfType<StateSet::Callback>();
if (callback) {
stateset.setEventCallback(callback);
}
@ -395,7 +425,7 @@ bool StateSet_readLocalData(Object& obj, Input& fr)
int mode;
fr[0].getInt(mode);
if (s_TextureGLModeSet.find(mode)!=s_TextureGLModeSet.end())
if (s_ModesAndNames.isTextureMode(mode))
{
// remap to a texture unit.
stateset.setTextureMode(0,(StateAttribute::GLMode)mode,value);
@ -414,11 +444,10 @@ bool StateSet_readLocalData(Object& obj, Input& fr)
{
if (StateSet_matchModeStr(fr[1].getStr(),value))
{
GLNameToGLModeMap::iterator nitr = s_GLNameToGLModeMap.find(fr[0].getStr());
if (nitr!=s_GLNameToGLModeMap.end())
StateAttribute::GLMode mode;
if (s_ModesAndNames.getGLModeForName(fr[0].getStr(), mode))
{
StateAttribute::GLMode mode = nitr->second;
if (s_TextureGLModeSet.find(mode)!=s_TextureGLModeSet.end())
if (s_ModesAndNames.isTextureMode(mode))
{
// remap to a texture unit.
stateset.setTextureMode(0,mode,value);
@ -494,10 +523,9 @@ bool StateSet_readLocalData(Object& obj, Input& fr)
{
if (StateSet_matchModeStr(fr[1].getStr(),value))
{
GLNameToGLModeMap::iterator nitr = s_GLNameToGLModeMap.find(fr[0].getStr());
if (nitr!=s_GLNameToGLModeMap.end())
StateAttribute::GLMode mode;
if (s_ModesAndNames.getGLModeForName(fr[0].getStr(), mode))
{
StateAttribute::GLMode mode = nitr->second;
stateset.setTextureMode(unit,mode,value);
fr+=2;
localIteratorAdvanced = true;
@ -543,8 +571,6 @@ bool StateSet_writeLocalData(const Object& obj, Output& fw)
const StateSet& stateset = static_cast<const StateSet&>(obj);
initGLNames();
// write the rendering hint value.
fw.indent()<<"rendering_hint ";
switch(stateset.getRenderingHint())
@ -575,11 +601,11 @@ bool StateSet_writeLocalData(const Object& obj, Output& fw)
for(StateSet::ModeList::const_iterator mitr=ml.begin();
mitr!=ml.end();
++mitr)
{
GLModeToGLNameMap::iterator nitr = s_GLModeToGLNameMap.find(mitr->first);
if (nitr!=s_GLModeToGLNameMap.end())
{
std::string str;
if (s_ModesAndNames.getNameForGLMode(mitr->first, str))
{
fw.indent() << nitr->second << " " << StateSet_getModeStr(mitr->second) << std::endl;
fw.indent() << str << " " << StateSet_getModeStr(mitr->second) << std::endl;
}
else
{
@ -620,16 +646,16 @@ bool StateSet_writeLocalData(const Object& obj, Output& fw)
mitr!=ml.end();
++mitr)
{
GLModeToGLNameMap::iterator nitr = s_GLModeToGLNameMap.find(mitr->first);
if (nitr!=s_GLModeToGLNameMap.end())
{
fw.indent() << nitr->second << " " << StateSet_getModeStr(mitr->second) << std::endl;
}
else
{
std::string str;
if (s_ModesAndNames.getNameForGLMode(mitr->first, str))
{
fw.indent() << str << " " << StateSet_getModeStr(mitr->second) << std::endl;
}
else
{
// no name defined for GLMode so just pass its value to fw.
fw.indent() << "0x" << hex << (unsigned int)mitr->first << dec <<" " << StateSet_getModeStr(mitr->second) << std::endl;
}
}
}
}

View File

@ -210,12 +210,11 @@ bool Uniform_readLocalData(Object& obj, Input& fr)
}
#endif //]
static ref_ptr<Uniform::Callback> s_callback = new osg::Uniform::Callback;
while (fr.matchSequence("UpdateCallback {"))
{
//int entry = fr[0].getNoNestedBrackets();
fr += 2;
Uniform::Callback* callback = dynamic_cast<Uniform::Callback*>(fr.readObjectOfType(*s_callback));
Uniform::Callback* callback = fr.readObjectOfType<Uniform::Callback>();
if (callback) {
uniform.setUpdateCallback(callback);
}
@ -226,7 +225,7 @@ bool Uniform_readLocalData(Object& obj, Input& fr)
{
//int entry = fr[0].getNoNestedBrackets();
fr += 2;
Uniform::Callback* callback = dynamic_cast<Uniform::Callback*>(fr.readObjectOfType(*s_callback));
Uniform::Callback* callback = fr.readObjectOfType<Uniform::Callback>();
if (callback) {
uniform.setEventCallback(callback);
}

View File

@ -24,19 +24,6 @@ REGISTER_DOTOSGWRAPPER(ObjectRecordData_Proxy)
osgDB::DotOsgWrapper::READ_AND_WRITE
);
#if 0
// if deffing out as values are not used anywhere.
static const int numBits( 6 );
typedef std::pair< std::string, osgSim::ObjectRecordData::Flags> FlagBits;
static FlagBits flagBits[numBits] = {
FlagBits( std::string("DONT_DISPLAY_IN_DAYLIGHT"), osgSim::ObjectRecordData::DONT_DISPLAY_IN_DAYLIGHT ),
FlagBits( "DONT_DISPLAY_AT_DUSK", osgSim::ObjectRecordData::DONT_DISPLAY_AT_DUSK ),
FlagBits( "DONT_DISPLAY_AT_NIGHT", osgSim::ObjectRecordData::DONT_DISPLAY_AT_NIGHT ),
FlagBits( "DONT_ILLUMINATE", osgSim::ObjectRecordData::DONT_ILLUMINATE ),
FlagBits( "FLAT_SHADED", osgSim::ObjectRecordData::FLAT_SHADED ),
FlagBits( "GROUPS_SHADOW_OBJECT", osgSim::ObjectRecordData::GROUPS_SHADOW_OBJECT )
};
#endif
bool ObjectRecordData_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
bool iteratorAdvanced = false;