c++openglopenvg

How to create global instance of objects that require a context?


I am attempting to write a C++ wrapper of OpenVG, which is very Open-GL like in its design. here is a simple wrapper for a path handle:

class Path {
        VGPath handle;

    public:
        Path() :
        handle(vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
            1,0,0,0, VG_PATH_CAPABILITY_ALL)) 
        { 
        std::cout << "Path Handle created : " << (void*)handle << '\n';
        }

        ~Path() {
            std::cout << "Path destroyed  : " << (void*)handle << '\n';
            vgDestroyPath(handle);
        }

    };

unfortunately, openVG requires a context to function and will abort if vgCreatePath is called with no openVG context. This prevents me from creating (for testing purpose) a global Path object object in my code, since it is build before I can create a openVG context (I do so in the main). Is there any workaround to prevent this?

I think that leaving the handle unitialized at the object construction is a very bad idea... should I force the creation of a global context when I'm creating a Path object if no context is present?


Solution

  • Is there any workaround to prevent this?

    Yes, use smart pointers, create it on demand using some kind of "factory" function, store it as long as it is needed in any variable.

    In C++03:

    typedef boost::weak_ptr<Path> PathWeakPtr;
    typedef boost::shared_ptr<Path> PathPtr;
    
    PathPtr createPath(){
        static PathWeakPtr lastPath;
        PathPtr result = lastPath.lock();
        if (!result){
            result.reset(new Path());
            lastPath = result;
        }
        return result;
    }
    

    ...

    void doSomething(){
        PathPtr path = createPath();//points to same path as in main*()
        ...
    }
    
    int main(int argc, char** argv){
        PathPtr path = createPath();//initialization
        doSomething();
        return 0;
    }
    

    In C++11 use:

    typedef std::weak_ptr<Path> PathWeakPtr;
    typedef std::shared_ptr<Path> PathPtr;
    

    instead of

    typedef boost::weak_ptr<Path> PathWeakPtr;
    typedef boost::shared_ptr<Path> PathPtr;