We really need to stop and consider what we've already written yet. And provides an abstract. Because it becomes to be big.
I'd like to discuss about the design of the low level resource classes. This has really nothing to do with our main subject but it is still interesting since it shows how to choose a solution which maximize the benefits of OO, minimize the drawbacks, and produce very clean code.
And I'm happy to know that somebody loves me :) Thanks for your support [grin].
Some bits of informations about low level resources
Only the DisplayDriver creates or destroy low level resources. Therefore, there is no need for the resource to provide a public constructor or a public destructor. Having a protected one allow a child class to access it and disallow you to create a resource outside of the DisplayDriver. Of course, the DisplayDriver needs to be a friend class of all the DisplayResource child classes.
You'd ask me: why is this good? This is related to the DirectX philosophy. When you are using DirectX in fullscreen and alt-tabing to another application you have to reset the DirectX device. This cannot be done if the device contains resources which has been allocated outside of the managed pool. Therefore you have to release the resource, reset the device and then reset the resources. Now, there is two solutions to do this:
- the DIY way: loop through the resources and do the stuff by yourself. You'll have to note that this is a common source of problem when programming DirectX. One may forget to release a single resource and the device will not be able to reset.
- the "I don't want to tackkle with it" way: let the DisplayDriver do all the work for you. It is easy for the driver to know whether the resources have to released or not before the driver reset. It is therefore less error prone to go this way.
To design our solution, we chosed the second option. But since the display driver now handle the release and reset of the resources, it needs to reference all the resources which are used at the device reset time. We hit another alternative here (and therefore, two possibilities):
- the resource knows how to add itself to the driver resource list and it knows how to remove itself from this list. The DisplayDriver needs to expose an interface to these function. If we don't want to expose this interface to the public we'll have to set all the possible resource classes as friend classes of DisplayDriver. This makes little sense to me.
- the driver adds the resource it creates to a resource list. it requires that the whole resource creation is done by the driver - and only by it. Therefore, to avoid the creation of resources outside of the driver, we have to forbid this at the code level - by protecting the constructor and the destructor. This solution also requires to have at least one creation function by resource type in the DisplayDriver.
We again chosed the second option. The "one function by resource type" is not really a problem. More, it is actually a benefits because of the code it produces:
surface = mDisplayDriver.createSurface(...);
It makes it clear that the resource is owned by the display driver.
The destruction of the resource also needs a specific interface in DisplayDriver - because the resource can't be destroyed by a delete.
These are the reason behind the following base resource class (simplified) declaration:
virtual void releaseV() = 0;
virtual void resetV() = 0;
friend class DisplayDriver;
Hope you liked it :)