src/blitter/factory.hpp
branchgamebalance
changeset 9913 e79cd19772dd
child 7587 353e9434475c
equal deleted inserted replaced
9912:1ac8aac92385 9913:e79cd19772dd
       
     1 /* $Id$ */
       
     2 
       
     3 #ifndef BLITTER_FACTORY_HPP
       
     4 #define BLITTER_FACTORY_HPP
       
     5 
       
     6 #include "base.hpp"
       
     7 #include <string>
       
     8 #include <map>
       
     9 
       
    10 /**
       
    11  * The base factory, keeping track of all blitters.
       
    12  */
       
    13 class BlitterFactoryBase {
       
    14 private:
       
    15 	char *name;
       
    16 	typedef std::map<std::string, BlitterFactoryBase *> Blitters;
       
    17 
       
    18 	static Blitters &GetBlitters()
       
    19 	{
       
    20 		static Blitters &s_blitters = *new Blitters();
       
    21 		return s_blitters;
       
    22 	}
       
    23 
       
    24 	static Blitter **GetActiveBlitter()
       
    25 	{
       
    26 		static Blitter *s_blitter = NULL;
       
    27 		return &s_blitter;
       
    28 	}
       
    29 
       
    30 protected:
       
    31 	/**
       
    32 	 * Register a blitter internally, based on his name.
       
    33 	 * @param name the name of the blitter.
       
    34 	 * @note an assert() will be trigger if 2 blitters with the same name try to register.
       
    35 	 */
       
    36 	void RegisterBlitter(const char *name)
       
    37 	{
       
    38 		/* Don't register nameless Blitters */
       
    39 		if (name == NULL) return;
       
    40 
       
    41 		this->name = strdup(name);
       
    42 		std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(name, this));
       
    43 		assert(P.second);
       
    44 	}
       
    45 
       
    46 public:
       
    47 	BlitterFactoryBase() :
       
    48 		name(NULL)
       
    49 	{}
       
    50 
       
    51 	virtual ~BlitterFactoryBase() { if (this->name != NULL) GetBlitters().erase(this->name); free(this->name); }
       
    52 
       
    53 	/**
       
    54 	 * Find the requested blitter and return his class.
       
    55 	 * @param name the blitter to select.
       
    56 	 * @post Sets the blitter so GetCurrentBlitter() returns it too.
       
    57 	 */
       
    58 	static Blitter *SelectBlitter(const char *name)
       
    59 	{
       
    60 		if (GetBlitters().size() == 0) return NULL;
       
    61 
       
    62 		Blitters::iterator it = GetBlitters().begin();
       
    63 		for (; it != GetBlitters().end(); it++) {
       
    64 			BlitterFactoryBase *b = (*it).second;
       
    65 			if (strcasecmp(name, b->name) == 0) {
       
    66 				Blitter *newb = b->CreateInstance();
       
    67 				*GetActiveBlitter() = newb;
       
    68 				return newb;
       
    69 			}
       
    70 		}
       
    71 		return NULL;
       
    72 	}
       
    73 
       
    74 	/**
       
    75 	 * Get the current active blitter (always set by calling SelectBlitter).
       
    76 	 */
       
    77 	static Blitter *GetCurrentBlitter()
       
    78 	{
       
    79 		return *GetActiveBlitter();
       
    80 	}
       
    81 
       
    82 
       
    83 	static char *GetBlittersInfo(char *p, const char *last)
       
    84 	{
       
    85 		p += snprintf(p, last - p, "List of blitters:\n");
       
    86 		Blitters::iterator it = GetBlitters().begin();
       
    87 		for (; it != GetBlitters().end(); it++) {
       
    88 			BlitterFactoryBase *b = (*it).second;
       
    89 			p += snprintf(p, last - p, "%18s: %s\n", b->name, b->GetDescription());
       
    90 		}
       
    91 		p += snprintf(p, last - p, "\n");
       
    92 
       
    93 		return p;
       
    94 	}
       
    95 
       
    96 	/**
       
    97 	 * Get a nice description of the blitter-class.
       
    98 	 */
       
    99 	virtual const char *GetDescription() = 0;
       
   100 
       
   101 	/**
       
   102 	 * Create an instance of this Blitter-class.
       
   103 	 */
       
   104 	virtual Blitter *CreateInstance() = 0;
       
   105 };
       
   106 
       
   107 /**
       
   108  * A template factory, so ->GetName() works correctly. This because else some compiler will complain.
       
   109  */
       
   110 template <class T>
       
   111 class BlitterFactory: public BlitterFactoryBase {
       
   112 public:
       
   113 	BlitterFactory() { this->RegisterBlitter(((T *)this)->GetName()); }
       
   114 
       
   115 	/**
       
   116 	 * Get the long, human readable, name for the Blitter-class.
       
   117 	 */
       
   118 	const char *GetName();
       
   119 };
       
   120 
       
   121 #endif /* BLITTER_FACTORY_HPP */