Miam-Player  0.8.0
A nice music player
FactoryDefine.h
Go to the documentation of this file.
1 /******************************************************************************
2  Some macros to create a factory and register functions
3  Copyright (C) 2012-2015 Wang Bin <wbsecg1@gmail.com>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 ******************************************************************************/
19 
20 #ifndef FACTORYDEFINE_H
21 #define FACTORYDEFINE_H
22 
23 #include <stdio.h>
24 #include <string>
25 #include <vector>
26 
83 /*
84  * This should be in header
85  */
86 #define FACTORY_REGISTER(BASE, _ID, NAME) FACTORY_REGISTER_ID_TYPE(BASE, BASE##Id_##_ID, BASE##_ID, NAME)
87 
88 #define FACTORY_REGISTER_ID_TYPE(BASE, ID, TYPE, NAME) \
89  FACTORY_REGISTER_ID_TYPE_AUTO(BASE, ID, TYPE, NAME) \
90  void Register##TYPE##_Man() { \
91  FACTORY_REGISTER_ID_TYPE_MAN(BASE, ID, TYPE, NAME); \
92  }
93 
94 #define FACTORY_REGISTER_ID_AUTO(BASE, _ID, NAME) \
95  FACTORY_REGISTER_ID_TYPE_AUTO(BASE, BASE##Id_##_ID, BASE##_ID, NAME)
96 
97 #define FACTORY_REGISTER_ID_MAN(BASE, _ID, NAME) \
98  FACTORY_REGISTER_ID_TYPE_MAN(BASE, BASE##Id_##_ID, BASE##_ID, NAME)
99 
100 #define FACTORY_REGISTER_ID_TYPE_MAN(BASE, ID, TYPE, NAME) \
101  BASE##Factory::register_<TYPE>(ID); \
102  BASE##Factory::registerIdName(ID, NAME);
103 
104 /*
105  * FIXME: __init_##TYPE (only if static) and xxx_Man() has the same content, and are both defined, construtor functions will not be called for gcc5.
106  * maybe also happens for ios
107  * Remove xxx_Man() is also a workaround
108  */
109 #define FACTORY_REGISTER_ID_TYPE_AUTO(BASE, ID, TYPE, NAME) \
110  static int __init_##TYPE() { \
111  FACTORY_REGISTER_ID_TYPE_MAN(BASE, ID, TYPE, NAME) \
112  return 0; \
113  } \
114  PRE_FUNC_ADD(__init_##TYPE)
115 
116 /*
117  * This should be in header
118  */
119 #define FACTORY_DECLARE(T) FACTORY_DECLARE_ID(T, T##Id)
120 #define FACTORY_DECLARE_ID(T, ID) \
121  class Q_AV_EXPORT T##Factory \
122  { \
123  public: \
124  typedef T* (*T##Creator)(); \
125  static T* create(const ID& id); \
126  template<class C> \
127  static bool register_(const ID& id) { return registerCreator(id, create<C>); } \
128  static bool registerCreator(const ID&, const T##Creator&); \
129  static bool registerIdName(const ID& id, const std::string& name); \
130  static bool unregisterCreator(const ID& id); \
131  static ID id(const std::string& name, bool caseSensitive = true); \
132  static std::string name(const ID &id); \
133  static std::vector<ID> registeredIds(); \
134  static std::vector<std::string> registeredNames(); \
135  static size_t count(); \
136  static T* getRandom(); \
137  private: \
138  template<class C> static T* create() { return new C(); } \
139  };
140 
141 /*
142  * This should be in cpp
143  */
144 #define FACTORY_DEFINE(T) FACTORY_DEFINE_ID(T, T##Id)
145 #define FACTORY_DEFINE_ID(T, ID) \
146  class T##FactoryBridge : public Factory<ID, T, T##FactoryBridge> {}; \
147  T* T##Factory::create(const ID& id) { return T##FactoryBridge::Instance().create(id); } \
148  bool T##Factory::registerCreator(const ID& id, const T##Creator& callback) { return T##FactoryBridge::Instance().registerCreator(id, callback); } \
149  bool T##Factory::registerIdName(const ID& id, const std::string& name) { return T##FactoryBridge::Instance().registerIdName(id, name); } \
150  bool T##Factory::unregisterCreator(const ID& id) { return T##FactoryBridge::Instance().unregisterCreator(id); } \
151  ID T##Factory::id(const std::string& name, bool caseSensitive) { return T##FactoryBridge::Instance().id(name, caseSensitive); } \
152  std::string T##Factory::name(const ID &id) { return T##FactoryBridge::Instance().name(id); } \
153  std::vector<ID> T##Factory::registeredIds() { return T##FactoryBridge::Instance().registeredIds(); } \
154  std::vector<std::string> T##Factory::registeredNames() { return T##FactoryBridge::Instance().registeredNames(); } \
155  size_t T##Factory::count() { return T##FactoryBridge::Instance().count(); } \
156  T* T##Factory::getRandom() { fflush(0);return T##FactoryBridge::Instance().getRandom(); }
157 
158 #endif // FACTORYDEFINE_H