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

View file

@ -38,9 +38,6 @@ namespace Common {
* @todo Implement the callback based notification system (outline below) * @todo Implement the callback based notification system (outline below)
* which sends out notifications to interested parties whenever the value * which sends out notifications to interested parties whenever the value
* of some specific (or any) configuration key changes. * 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> { class ConfigManager : public Singleton<ConfigManager> {
struct IgnoreCaseComparator { struct IgnoreCaseComparator {
@ -117,7 +114,7 @@ public:
*/ */
private: private:
friend class Singleton<ConfigManager>; friend SingletonBaseType *makeInstance<>();
ConfigManager(); ConfigManager();
void loadFile(const String &filename); void loadFile(const String &filename);

View file

@ -23,6 +23,18 @@
#ifndef COMMON_SINGLETON_H #ifndef COMMON_SINGLETON_H
#define 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 { namespace Common {
/** /**
@ -47,12 +59,14 @@ public:
// order might become an issue. There are various approaches // order might become an issue. There are various approaches
// to solve that problem, but for now this is sufficient // to solve that problem, but for now this is sufficient
if (!_singleton) if (!_singleton)
_singleton = new T; _singleton = makeInstance<T>();
return *_singleton; return *_singleton;
} }
protected: protected:
Singleton<T>() { } Singleton<T>() { }
~Singleton<T>() { } virtual ~Singleton<T>() { }
typedef T SingletonBaseType;
}; };
#define DECLARE_SINGLETON(T) template<> T* Common::Singleton<T>::_singleton=0 #define DECLARE_SINGLETON(T) template<> T* Common::Singleton<T>::_singleton=0

View file

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

View file

@ -27,6 +27,16 @@
#include "common/util.h" #include "common/util.h"
#include "common/rect.h" #include "common/rect.h"
#include "common/savefile.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 * 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, * methods to create timers, to handle user input events,
* control audio CD playback, and sound output. * control audio CD playback, and sound output.
*/ */
class OSystem { class OSystem : public Common::Singleton<OSystem> {
public: 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 */ /** @name Feature flags */
//@{ //@{

View file

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

View file

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