Miam-Player  0.8.0
A nice music player
FactoryDefine.h File Reference
#include <stdio.h>
#include <string>
#include <vector>

Go to the source code of this file.

Macros

#define FACTORY_REGISTER(BASE, _ID, NAME)   FACTORY_REGISTER_ID_TYPE(BASE, BASE##Id_##_ID, BASE##_ID, NAME)
 A: Suppose we need a factory for class MyClass. More...
 
#define FACTORY_REGISTER_ID_TYPE(BASE, ID, TYPE, NAME)
 
#define FACTORY_REGISTER_ID_AUTO(BASE, _ID, NAME)   FACTORY_REGISTER_ID_TYPE_AUTO(BASE, BASE##Id_##_ID, BASE##_ID, NAME)
 
#define FACTORY_REGISTER_ID_MAN(BASE, _ID, NAME)   FACTORY_REGISTER_ID_TYPE_MAN(BASE, BASE##Id_##_ID, BASE##_ID, NAME)
 
#define FACTORY_REGISTER_ID_TYPE_MAN(BASE, ID, TYPE, NAME)
 
#define FACTORY_REGISTER_ID_TYPE_AUTO(BASE, ID, TYPE, NAME)
 
#define FACTORY_DECLARE(T)   FACTORY_DECLARE_ID(T, T##Id)
 
#define FACTORY_DECLARE_ID(T, ID)
 
#define FACTORY_DEFINE(T)   FACTORY_DEFINE_ID(T, T##Id)
 
#define FACTORY_DEFINE_ID(T, ID)
 

Macro Definition Documentation

#define FACTORY_DECLARE (   T)    FACTORY_DECLARE_ID(T, T##Id)
#define FACTORY_DECLARE_ID (   T,
  ID 
)
Value:
class Q_AV_EXPORT T##Factory \
{ \
public: \
typedef T* (*T##Creator)(); \
static T* create(const ID& id); \
template<class C> \
static bool register_(const ID& id) { return registerCreator(id, create<C>); } \
static bool registerCreator(const ID&, const T##Creator&); \
static bool registerIdName(const ID& id, const std::string& name); \
static bool unregisterCreator(const ID& id); \
static ID id(const std::string& name, bool caseSensitive = true); \
static std::string name(const ID &id); \
static std::vector<ID> registeredIds(); \
static std::vector<std::string> registeredNames(); \
static size_t count(); \
static T* getRandom(); \
private: \
template<class C> static T* create() { return new C(); } \
};
#define Q_AV_EXPORT
Definition: QtAV_Global.h:40
Definition: factory.h:84
#define FACTORY_DEFINE (   T)    FACTORY_DEFINE_ID(T, T##Id)
#define FACTORY_DEFINE_ID (   T,
  ID 
)
Value:
class T##FactoryBridge : public Factory<ID, T, T##FactoryBridge> {}; \
T* T##Factory::create(const ID& id) { return T##FactoryBridge::Instance().create(id); } \
bool T##Factory::registerCreator(const ID& id, const T##Creator& callback) { return T##FactoryBridge::Instance().registerCreator(id, callback); } \
bool T##Factory::registerIdName(const ID& id, const std::string& name) { return T##FactoryBridge::Instance().registerIdName(id, name); } \
bool T##Factory::unregisterCreator(const ID& id) { return T##FactoryBridge::Instance().unregisterCreator(id); } \
ID T##Factory::id(const std::string& name, bool caseSensitive) { return T##FactoryBridge::Instance().id(name, caseSensitive); } \
std::string T##Factory::name(const ID &id) { return T##FactoryBridge::Instance().name(id); } \
std::vector<ID> T##Factory::registeredIds() { return T##FactoryBridge::Instance().registeredIds(); } \
std::vector<std::string> T##Factory::registeredNames() { return T##FactoryBridge::Instance().registeredNames(); } \
size_t T##Factory::count() { return T##FactoryBridge::Instance().count(); } \
T* T##Factory::getRandom() { fflush(0);return T##FactoryBridge::Instance().getRandom(); }
const char * name(const ID &id) const
Definition: factory.h:190
Type * create(const ID &id)
Definition: factory.h:134
Definition: factory.h:84
size_t count() const
Definition: factory.h:215
bool unregisterCreator(const ID &id)
Definition: factory.h:160
ID id(const char *name, bool caseSensitive=true) const
Definition: factory.h:169
bool registerIdName(const ID &id, const char *name)
Definition: factory.h:154
Type * getRandom()
Definition: factory.h:222
std::vector< const char * > registeredNames() const
Definition: factory.h:205
bool registerCreator(const ID &id, const Creator &callback)
Definition: factory.h:146
const std::vector< ID > & registeredIds() const
Definition: factory.h:199
#define FACTORY_REGISTER (   BASE,
  _ID,
  NAME 
)    FACTORY_REGISTER_ID_TYPE(BASE, BASE##Id_##_ID, BASE##_ID, NAME)

A: Suppose we need a factory for class MyClass.

We can query a derived class of MyClass from factory by an id type MyClassId. To create the factory, just 2 steps

  1. In MyClass.h: #include "FactoryDefine.h" FACTORY_DECLARE(MyClass)
  2. In MyClass.cpp: #include "QtAV/private/factory.h" FACTORY_DEFINE(MyClass)

To create and register a new subclass MyClassSubA with it's id 0. In MyClassTypes.h (Usually just include this is enough to use the factory. And MyClassXXX.{h,cpp} can NOT include this file), MyClassSubA's ID: extern Q_AV_EXPORT MyClassId MyClassId_SubA; In MyClassTypes.cpp, define the id value: MyClassId MyClassId_SubA = some_value; We define the id in MyClassTypes.cpp because MyClassSubA may not be compiled(e.g. platform dependent features), but the id must be defined.

  1. create a source file MyClassSubA.cpp and implement the required members
  2. In MyClassSubA.cpp, add the following lines #include "QtAV/private/prepost.h" //for PRE_FUNC_ADD() //we don't want to depend on MyClassTypes.h, so extern extern MyClassId MyClassId_SubA; FACTORY_REGISTER_ID_AUTO(MyClass, SubA, "SubA's name") void RegisterMyClassSubA_Man() { FACTORY_REGISTER_ID_MAN(MyClass, SubA, "SubA's name") }
  3. In MyClass.cpp, add register function into MyClass_RegisterAll(); extern void RegisterMyClassSubA_Man(); void MyClass_RegisterAll() { RegisterMyClassSubA_Man(); //add this line }

B: If MyClass and it's factory already exist in the library and you want to add a new subclass without changing the library, just create MyClassSubA.cpp with the content:

#include "MyClass.h"
#include "QtAV/private/prepost.h" //for PRE_FUNC_ADD()
MyClassId MyClassId_SubA = some_value; //it can be used somewhere else as "extern"
FACTORY_REGISTER_ID_AUTO(MyClass, SubA, "SubA's name")
void RegisterMyClassSubA_Man() //call it when you need as "extern"
{
    FACTORY_REGISTER_ID_MAN(MyClass, SubA, "SubA's name")
}

class MyClassSubA : public MyClass
{
    ...
};
#define FACTORY_REGISTER_ID_AUTO (   BASE,
  _ID,
  NAME 
)    FACTORY_REGISTER_ID_TYPE_AUTO(BASE, BASE##Id_##_ID, BASE##_ID, NAME)
#define FACTORY_REGISTER_ID_MAN (   BASE,
  _ID,
  NAME 
)    FACTORY_REGISTER_ID_TYPE_MAN(BASE, BASE##Id_##_ID, BASE##_ID, NAME)
#define FACTORY_REGISTER_ID_TYPE (   BASE,
  ID,
  TYPE,
  NAME 
)
Value:
FACTORY_REGISTER_ID_TYPE_AUTO(BASE, ID, TYPE, NAME) \
void Register##TYPE##_Man() { \
FACTORY_REGISTER_ID_TYPE_MAN(BASE, ID, TYPE, NAME); \
}
#define FACTORY_REGISTER_ID_TYPE_AUTO(BASE, ID, TYPE, NAME)
Definition: FactoryDefine.h:109
#define FACTORY_REGISTER_ID_TYPE_AUTO (   BASE,
  ID,
  TYPE,
  NAME 
)
Value:
static int __init_##TYPE() { \
FACTORY_REGISTER_ID_TYPE_MAN(BASE, ID, TYPE, NAME) \
return 0; \
} \
PRE_FUNC_ADD(__init_##TYPE)
#define FACTORY_REGISTER_ID_TYPE_MAN (   BASE,
  ID,
  TYPE,
  NAME 
)
Value:
BASE##Factory::register_<TYPE>(ID); \
BASE##Factory::registerIdName(ID, NAME);
bool registerIdName(const ID &id, const char *name)
Definition: factory.h:154