Quote:Original post by Domarius
To answer your question, the hge variable (m_hge in my class) is a singleton.
Oh.
The best "wrapping" might then not use any objects at all, then. Instead, you would create a namespace with free functions for all the functionality you want to "reflect", and just call hgeCreate (and use the result) from within the free functions (presumably this function will return early when the singleton already exists :) ). This is actually likely to save you significant amounts of memory (in the form of redundant pointers to the singleton that are no longer stored all over the place).
Quote:and it returns a pointer to the same object, and (AFAIK) increments a counter. When you're done with it, you call
m_hge->Release();
and it decrements the counter, and finally destroys the object when there are no more pointers to it.
Oh. That complicates things, then. But there's hope. Something like this should do it:
HGEWrapper.h:
#ifndef HGE_WRAPPER_H#define HGE_WRAPPER_Hnamespace my_hge { void foo();}#endif
HGEWrapper.cpp:
namespace my_hge { namespace detail { // We define an object that uses RAII to control a pointer to the singleton: class HGEWrapper { HGEInterface* ptr; // Stubbing these out prevents the object from being copied, which is // what we want, here. HGEWrapper(const HGEWrapper&); // don't try to implement this. HGEWrapper& operator=(const HGEWrapper&); // don't try to implement this. public: HGEWrapper(int version) : ptr(HGECreate(version)) {} ~HGEWrapper() { ptr->Release(); } HGEInterface& operator*() { return *ptr; } HGEInterface* operator->() { return ptr; } } implementation; // This ^^^ instance of the wrapper object ensures that the counter is at // least 1 during the entire program, so that the thing won't be re-created // continually. Note that you might have to worry about the "static order // of initialization fiasco" here, if you're unlucky enough that there are // other singletons in the program and they have dependencies on each other. } void foo() { // Because we had to make that static instance, we just use it in the // function implementations - although we could also create our own local // instances and everything would be just fine. // Anyway, we just forward things to the singleton like this: detail::implementation->foo(); }}
On the other hand, it sort of depends on the scope of HGE. If it tries to do too much, there may be cause to split the functionality up into several headers; and there might yet be some use for actual objects (of the sort that can be freely instantiated) - e.g. to store parameters for a later call to a complicated function.