#include <iostream>
#include <cassert>
struct ResourceHandle
{
typedef unsigned Id;
static const Id NULL_ID = 0;
ResourceHandle() : id(NULL_ID) {}
bool isNull() const
{ return id == NULL_ID; }
Id id;
};
template <typename THandle, typename THandleInterface>
struct Resource
{
typedef THandle Handle;
typedef THandleInterface HandleInterface;
HandleInterface* getInterface() const { return _interface; }
void setInterface(HandleInterface* interface) { assert(!getHandle().isNull()); // should not work if handle is NOT null
_interface = interface; }
const Handle& getHandle() const
{ return _handle; }
protected:
typedef Resource<THandle, THandleInterface> Base;
Resource(HandleInterface* interface) : _interface(interface) {}
Handle _handle;
private:
HandleInterface* _interface;
};
// example:
struct Image
{ /* ... */ };
struct TextureHandle : ResourceHandle
{
unsigned int width, height, depth;
};
struct TextureHandleInterface
{
virtual bool load(TextureHandle&, const Image&) = 0;
virtual void destroy(TextureHandle&) = 0;
virtual Image getImageData(const TextureHandle&) const = 0;
};
struct Texture : Resource<TextureHandle, TextureHandleInterface>
{
Texture(HandleInterface* interface) : Base(interface) {}
bool load(const Image& image) { return getInterface()->load(_handle, image); }
void destroy() { return getInterface()->destroy(_handle); }
Image getImageData() const { return getInterface()->getImageData(_handle); }
};
class OglTextureInterface : public TextureHandleInterface
{
public:
OglTextureInterface()
{
_nextId = 0;
}
virtual bool load(TextureHandle& texture, const Image&)
{
std::cout << "Loading texture: " << &texture;
texture.id = _nextId++;
return true;
}
virtual void destroy(TextureHandle& texture)
{
std::cout << "Destroying texture: " << &texture;
}
virtual Image getImageData(const TextureHandle&) const
{
return Image();
}
private:
ResourceHandle::Id _nextId;
};
int main(int argc, char* argv[])
{
OglTextureInterface interface;
Texture texture(&interface);
texture.load(Image());
std::cout << "\nTexture ID: " << texture.getHandle().id << '\n';
return 0;
}