[osg-users] Any progress in configuration abstraction...

Robert Osfield robert.osfield at gmail.com
Wed Aug 8 01:01:10 PDT 2007


Hi Adrian,

I have just checked in a trial of using localised prototype()/create()
methods added to CullVisitor and DatabasePager.  The added methods
look like:

        /** Create a shallow copy of the CullVisitor, used by
CullVisitor::create() to clone the prototype..*/
        virtual CullVisitor* clone() const { return new CullVisitor(*this); }

        /** get the prototype singleton used by CullVisitor::create().*/
        static osg::ref_ptr<CullVisitor>& prototype();

        /** create a CullVisitor by cloning CullVisitor::prototype().*/
        static CullVisitor* create();

The DatabasePager is exactly the save for class name.  The
implementation looks like:

osg::ref_ptr<CullVisitor>& CullVisitor::prototype()
{
    static osg::ref_ptr<CullVisitor> s_CullVisitor = new CullVisitor;
    return s_CullVisitor;
}

CullVisitor* CullVisitor::create()
{
    return CullVisitor::prototype().valid() ?
           CullVisitor::prototype()->clone() :
           new CullVisitor;
}

Things to note are the fact that the prototype method passed back a
reference to the static ref_ptr<CullVisitor>, this allows you to
directly modify it without the need for a set/get pairing.

To pass on your own implementations you'll need to something like the
following (note, the copy constructor and clone() method being
overriden):

class MyCullVisitor : public osgUtil::CullVisitor
{
public:

    MyCullVisitor()
    {
        osg::notify(osg::NOTICE)<<"Constructig my CullVisitor
"<<this<<std::endl;
    }

    MyCullVisitor(const MyCullVisitor& rhs):
        CullVisitor(rhs)
    {
        osg::notify(osg::NOTICE)<<"Constructig my
CullVisitor(CullVisitor)"<<this<<std::endl;
    }

    ~MyCullVisitor()
    {
        osg::notify(osg::NOTICE)<<"Destructig my
MyCullVisitor"<<this<<std::endl;
    }


    virtual CullVisitor* clone() const { return new MyCullVisitor(*this); }

    void apply(osg::Geode& geode)
    {
        // osg::notify(osg::NOTICE)<<"In
MyCullVisitor::apply(Geode)"<<std::endl;
        CullVisitor::apply(geode);
    }
};

class MyDatabasePager : public osgDB::DatabasePager
{
public:

    MyDatabasePager()
    {
        osg::notify(osg::NOTICE)<<"Constructig my MyDatabasePager"<<std::endl;
    }

    MyDatabasePager(const MyDatabasePager& rhs):
        DatabasePager(rhs)
    {
        osg::notify(osg::NOTICE)<<"Constructig my MyDatabasePager"<<std::endl;
    }

    ~MyDatabasePager()
    {
        osg::notify(osg::NOTICE)<<"Destructig my MyDatabasePager"<<std::endl;
    }

    virtual DatabasePager* clone() const { return new MyDatabasePager(*this); }

};


int main(int argc, char** argv)
{
    osgUtil::CullVisitor::prototype() = new MyCullVisitor;
    osgDB::DatabasePager::prototype() = new MyDatabasePager;

.. usual set up of your application, osgViewer will now use these prototypes..

}

Attached is osgviewer.cpp modified with these changes.

The reason for me going for this solution is simply to keep the
factory method localised to each class, and it also offers the
possibility of configuring the original prototype without needing to
create a new instance.

A further evolution might be to make the default and copy constructors
of CullVisitor/DatabasePager pager protected to force developers to go
via the create() method, but this would prevent some types of usage so
I'll hang back on this.

Robert.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: osgviewer.cpp
Type: text/x-c++src
Size: 8975 bytes
Desc: not available
Url : http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20070808/8a32cc08/attachment.cpp 


More information about the osg-users mailing list