Hi Chuck,

Thanks for the useful information. Hope it could be added to the wiki
page, as a good supplement of my origin serializer tutorial which is
written unpolished and in a hurry. :)

I'm still waiting for decision of the submitted osgAnimation
serializers. After that I'll continue completing other core library
wrappers and have a taste to support the introspection mechanism,
which would be a lightweight replacement of osgIntrospection.

Cheers,

Wang Rui


2010/4/16 Chuck Seberino <[email protected]>:
> I have been playing around with the new serialization support with 2.9.7 and
> wanted to share some of my findings.  I think some of these might be useful
> for others looking to do the same.
>
> 1.  Serialization support  *requires* that you override the virtual methods
> for className() and libraryName().  If you don't, then things won't
> serialize properly and you might spend *LOTS* of time trying to figure out
> why...
> 2.  You can provide serialization for a class that doesn't live in a
> namespace.  Just specify global namespace.
>
> REGISTER_OBJECT_WRAPPER(NoNamespaceClass,
>                         new NoNamespaceClass,
>                         ::NoNamespaceClass,
>                         "osg::Object osg::Node ::NoNamespaceClass") { ... }
>
> 3.  As long as you have item 1. you can still serialize a class without
> adding in additional accessors and mutators.  This is useful if you have a
> class that you can't or don't want to change to add in the necessary set/get
> methods to satisfy serialization.  A wrapper class can be created to do this
> for you.
>
> // Class that we don't want to expose get/set
>
> class NoGetSetClass : public osg::Node
> {
> public:
>
>    ...
>    virtual const char* className() const { return "NoGetSetClass"; } // name
> to match
>    virtual const char* libraryName() const { return ""; }            // no
> namespace
> protected:
>    std::string _internalVariable;
> };
>
> // Helper class that is used just for serialization purposes
> class SerializerForNoGetSetClass : public NoGetSetClass
> {
> public:
>
>    ...
>    const std::string& getVariable() const { return _internalVariable; }
>    void setVariable(const std::string& str) { _internalVariable = str; }
> };
>
> REGISTER_OBJECT_WRAPPER(NoGetSetClass,                  // Old name because
> this is what we match against
>
>                         new SerializerForNoGetSetClass, // Use helper class
> for get/set
>
>                         ::NoGetSetClass,
>
>                         "osg::Object osg::Node ::NoGetSetClass")
>
> {
>
>    // Manually recreate macro to specify our serializer subclass
>
>    wrapper->addSerializer(new
> osgDB::StringSerializer<SerializerForNoGetSetClass>("Variable", "default",
>                              &SerializerForNoGetSetClass::getVariable,
>                              &SerializerForNoGetSetClass::setVariable));
> }
>
> The macros for ADD_*_SERIALIZER can't be used because we want to use our
> subclass instead of the original class we want serialized.  When the
> serialization code is invoked, it matches the class type and classname
> properly with the old class, but constructs an instance of
> SerializerForNoGetSetClass to push and pull values.
> 4.  You can specify more than one REGISTER_OBJECT_WRAPPER statement in a
> single compilation unit.  The macro creates a typedef (typedef CLASS
> MyClass) that is used for the subsequent serialization commands.  Calling
> the macro more than once will cause it to complain about the redefinition of
> MyClass.  Since the purpose of the macro is to statically register a
> wrapper, it can be guarded by a namespace and still function just fine.
>
> // This macro creates a typedef
>
> REGISTER_OBJECT_WRAPPER(Class1,
>
>                         new Class1,
>
>                         ::Class1,
>
>                         "osg::Object ::Class1")
> {
>
>    // We only require the typedef to be valid in here
>    ...
> }
>
> // The typedef is still available here
>
> namespace { // Now this macro doesn't conflict with previous macro typedef
> REGISTER_OBJECT_WRAPPER(Class2,
>
>                         new Class2,
>
>                         ::Class2,
>
>                         "osg::Object ::Class2")
> {
>    ...
>
>    // The new typedef takes precedence because of namespace scope
> }
> } // namespace
>
>
>
> Hopefully these nuggets of information will help anyone else trying to get
> their own custom classes to serialize properly without pulling out too much
> hair.  For those that don't know it, this wiki link is a good starting point
> http://www.openscenegraph.org/projects/osg/wiki/Support/KnowledgeBase/SerializationSupport
>
> Regards,
> Chuck Seberino
>
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to