From 003375d3755fe06227894e941b177491770c17fe Mon Sep 17 00:00:00 2001 From: truelight Date: Sun, 17 Jun 2007 20:30:28 +0000 Subject: (svn r10190) -Codechange: merged renderer and blitter to one single class API: blitter -Codechange: introduced a hierachy of blitters to avoid a lot of code duplication Note: this allows much easier adding other types of video-drivers, like OpenGL --- src/blitter/factory.hpp | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 src/blitter/factory.hpp (limited to 'src/blitter/factory.hpp') diff --git a/src/blitter/factory.hpp b/src/blitter/factory.hpp new file mode 100644 index 000000000..a55250071 --- /dev/null +++ b/src/blitter/factory.hpp @@ -0,0 +1,121 @@ +/* $Id$ */ + +#ifndef BLITTER_FACTORY_HPP +#define BLITTER_FACTORY_HPP + +#include "base.hpp" +#include +#include + +/** + * The base factory, keeping track of all blitters. + */ +class BlitterFactoryBase { +private: + char *name; + typedef std::map Blitters; + + static Blitters &GetBlitters() + { + static Blitters &s_blitters = *new Blitters(); + return s_blitters; + } + + static Blitter **GetActiveBlitter() + { + static Blitter *s_blitter = NULL; + return &s_blitter; + } + +protected: + /** + * Register a blitter internally, based on his name. + * @param name the name of the blitter. + * @note an assert() will be trigger if 2 blitters with the same name try to register. + */ + void RegisterBlitter(const char *name) + { + /* Don't register nameless Blitters */ + if (name == NULL) return; + + this->name = strdup(name); + std::pair P = GetBlitters().insert(Blitters::value_type(name, this)); + assert(P.second); + } + +public: + BlitterFactoryBase() : + name(NULL) + {} + + virtual ~BlitterFactoryBase() { if (this->name != NULL) GetBlitters().erase(this->name); free(this->name); } + + /** + * Find the requested blitter and return his class. + * @param name the blitter to select. + * @post Sets the blitter so GetCurrentBlitter() returns it too. + */ + static Blitter *SelectBlitter(const char *name) + { + if (GetBlitters().size() == 0) return NULL; + + Blitters::iterator it = GetBlitters().begin(); + for (; it != GetBlitters().end(); it++) { + BlitterFactoryBase *b = (*it).second; + if (strcasecmp(name, b->name) == 0) { + Blitter *newb = b->CreateInstance(); + *GetActiveBlitter() = newb; + return newb; + } + } + return NULL; + } + + /** + * Get the current active blitter (always set by calling SelectBlitter). + */ + static Blitter *GetCurrentBlitter() + { + return *GetActiveBlitter(); + } + + + static char *GetBlittersInfo(char *p, const char *last) + { + p += snprintf(p, last - p, "List of blitters:\n"); + Blitters::iterator it = GetBlitters().begin(); + for (; it != GetBlitters().end(); it++) { + BlitterFactoryBase *b = (*it).second; + p += snprintf(p, last - p, "%18s: %s\n", b->name, b->GetDescription()); + } + p += snprintf(p, last - p, "\n"); + + return p; + } + + /** + * Get a nice description of the blitter-class. + */ + virtual const char *GetDescription() = 0; + + /** + * Create an instance of this Blitter-class. + */ + virtual Blitter *CreateInstance() = 0; +}; + +/** + * A template factory, so ->GetName() works correctly. This because else some compiler will complain. + */ +template +class BlitterFactory: public BlitterFactoryBase { +public: + BlitterFactory() { this->RegisterBlitter(((T *)this)->GetName()); } + + /** + * Get the long, human readable, name for the Blitter-class. + */ + const char *GetName(); +}; + +#endif /* BLITTER_FACTORY_HPP */ -- cgit v1.2.3-54-g00ecf