Changed the singleton code to allow for custom object factories; this allowed me to change OSystem to use the singleton base class, too

svn-id: r16404
This commit is contained in:
Max Horn 2005-01-01 19:19:06 +00:00
parent c418282ec7
commit 74bf578bda
7 changed files with 37 additions and 34 deletions

View file

@ -103,6 +103,8 @@ public:
typedef Common::Array<Plugin *> PluginList;
class PluginManager;
/**
* Instances of this class manage all plugins, including loading them,
* making wrapper objects of class Plugin available, and unloading them.
@ -115,7 +117,7 @@ private:
bool tryLoadPlugin(Plugin *plugin);
friend class Common::Singleton<PluginManager>;
friend SingletonBaseType *makeInstance<>();
PluginManager();
public:

View file

@ -38,9 +38,6 @@ namespace Common {
* @todo Implement the callback based notification system (outline below)
* which sends out notifications to interested parties whenever the value
* of some specific (or any) configuration key changes.
* @todo Preserve the order of the entries in the config file. Maybe even add
* an API to query/modify that order, which could be used by the launcher
* to allow arranging the game targets.
*/
class ConfigManager : public Singleton<ConfigManager> {
struct IgnoreCaseComparator {
@ -117,7 +114,7 @@ public:
*/
private:
friend class Singleton<ConfigManager>;
friend SingletonBaseType *makeInstance<>();
ConfigManager();
void loadFile(const String &filename);

View file

@ -23,6 +23,18 @@
#ifndef COMMON_SINGLETON_H
#define COMMON_SINGLETON_H
/**
* The default object factory used by the template class Singleton.
* By specialising this template function, one can make a singleton use a
* custom object factory. For example, to support encapsulation, your
* singleton class might be pure virtual (or "abstract" in Java terminology),
* and you specialise makeInstance to return an instance of a subclass.
*/
template <class T>
T* makeInstance() {
return new T();
}
namespace Common {
/**
@ -47,13 +59,15 @@ public:
// order might become an issue. There are various approaches
// to solve that problem, but for now this is sufficient
if (!_singleton)
_singleton = new T;
_singleton = makeInstance<T>();
return *_singleton;
}
protected:
Singleton<T>() { }
~Singleton<T>() { }
};
virtual ~Singleton<T>() { }
typedef T SingletonBaseType;
};
#define DECLARE_SINGLETON(T) template<> T* Common::Singleton<T>::_singleton=0

View file

@ -31,9 +31,10 @@
#include "common/config-manager.h"
#include "common/system.h"
static OSystem *s_system = 0;
DECLARE_SINGLETON(OSystem);
static OSystem *createSystem() {
template <>
OSystem *makeInstance<>() {
// Attention: Do not call parseGraphicsMode() here, nor any other function
// which needs to access the OSystem instance, else you get stuck in an
// endless loop.
@ -58,13 +59,6 @@ static OSystem *createSystem() {
#endif
}
OSystem &OSystem::instance() {
if (!s_system)
s_system = createSystem();
return *s_system;
}
bool OSystem::setGraphicsMode(const char *name) {
if (!name)
return false;

View file

@ -27,6 +27,16 @@
#include "common/util.h"
#include "common/rect.h"
#include "common/savefile.h"
#include "common/singleton.h"
class OSystem;
/**
* Custome object factory for OSystem.
*/
template <>
OSystem *makeInstance<>();
/**
* Interface for ScummVM backends. If you want to port ScummVM to a system
@ -38,22 +48,8 @@
* methods to create timers, to handle user input events,
* control audio CD playback, and sound output.
*/
class OSystem {
class OSystem : public Common::Singleton<OSystem> {
public:
/**
* Returns a pointer to the (singleton) OSystem instance, that is, to the
* active backend.
* This is not quite a "proper" singleton, since OSystem is an interface
* not a real class (and thus it isn't based on our Singleton template).
* @return the pointer to the (singleton) OSystem instance
*/
static OSystem &instance();
public:
/** Empty virtual destructor. DO NOT REMOVE! */
virtual ~OSystem() {}
/** @name Feature flags */
//@{

View file

@ -56,7 +56,7 @@ typedef Common::FixedStack<Dialog *> DialogStack;
class NewGui : public Common::Singleton<NewGui> {
typedef Common::String String;
friend class Dialog;
friend class Common::Singleton<NewGui>;
friend SingletonBaseType *makeInstance<>();
NewGui();
public:

View file

@ -54,7 +54,7 @@ public:
Status getStatus() const;
private:
friend class Common::Singleton<AudioCDManager>;
friend SingletonBaseType *makeInstance<>();
AudioCDManager();
int getCachedTrack(int track);