[Scummvm-devel] Backend modularization (ATTN porters)
Max Horn
max at quendi.de
Sun Oct 22 17:43:14 CEST 2006
Hi folks,
this email is meant to explain the backend modifications that have
just hit HEAD in the repository. They break all backends except the
SDL one for now, but I hope all backends will very soon be fixed up
by you guys. With the explanations in this email, it should hopefully
be a matter of 10 minutes or so. And remember, if you run into
troubles, we are out here to help you with them :-).
One tidbit to keep in mind for the future: Your custom initBackend()
method should always invoke the parent's one, unless you have very
good reasons not to (and usually, it'll be better to fix those
reasons, contact me if you are in doubt).
BACKGROUND:
The changes are part of the backend modularization effort (see also
<http://wiki.scummvm.org/index.php/Modular_Backends>). Basically, we
want to make it possible for backends to hook up into and modify
higher level functionality, w/o forcing backends to do so. As an
example, view the TimerManager: Right now, every backend has to
provide a simple method, setTimerCallback(), and that's it. Easy to
do; but if you want to implement timers different (see the MorphOS
backend), you have to modify code outside backends/, and insert
#ifdef's etc..
So instead, we now allow (and force!) backends to return a
TimerManage instance of their own. Most backends will just want to
return the good old DefaultTimerManager (adding only a few lines of
code), but if they wanted to, they now *could* use a custom
TimerManager.
An existing example for this is the SavefileManager. Another is the
Audio::Mixer. More will follow, see also the Wiki for a list of ideas.
WHAT YOU HAVE TO DO, QUICK & SIMPLE WAY:
The quick solution to get your backend compiling again (if you
already provide a custom getSavefileManager() implementation, take
that into account; and make sure that your getSavefileManager()
always returns the same object, and does *not* use "new" to create a
new one each time. If it does, it should be trivial for you to fix it
by adapting the code given below):
1) Add some new members to your backend:
Common::SaveFileManager *_savefile;
Audio::Mixer *_mixer;
Common::TimerManager *_timer;
2) Also add these typedefs to your class (they used to be part of
OSystem):
typedef void (*SoundProc)(void *param, byte *buf, int len);
typedef int (*TimerProc)(int interval);
3) Add code to init them to your initBackend() method (or any other
place you feel suitable for this, e.g. your constructor or your main
()). Typically, that would be:
#include "backends/saves/default/default-saves.h"
#include "backends/timer/default/default-timer.h"
#include "sound/mixer.h"
...
static int timer_handler(int t) {
DefaultTimerManager *tm = (DefaultTimerManager *)g_system-
>getTimerManager();
return tm->handler(t);
}
...
_savefile = new DefaultSaveFileManager();
_mixer = new Audio::Mixer();
_timer = new DefaultTimerManager();
setSoundCallback(Audio::Mixer::mixCallback, _mixer);
setTimerCallback(&timer_handler, 10);
4) Add these methods to your code:
Common::SaveFileManager *YOUR_OSystem::getSavefileManager() { return
_savefile; }
Audio::Mixer * YOUR_OSystem::getMixer() { return _mixer; }
Common::TimerManager * YOUR_OSystem::getTimerManager() { return
_timer; }
5) Depending on your backend, you might want to add code to unhook
and delete these objects to your destructor / quit() method.
That's it!
WHAT YOU HAVE TO DO, GENERIC WAY:
Essentially, you have to provide getSavefileManager, getMixer and
getTimerManager implementations following the correct semantics. In
exchange, you may be able to remove setSoundCallback,
clearSoundCallback and setTimerCallback, and hook up the mixer and
the timer manager in a way that suits you best. Oh, and get rid of
the nasty timer_handler() function, too.
I will soon partially realize this for the SDL backend.
Cheers,
Max
P.S.: Another nice side effect of all this is of course that Torbjörn
has to recompile everything once again :)
More information about the Scummvm-devel
mailing list