Wexus2 0.20
wexus2.src/wexus/Registry.h
00001 
00002 /*
00003  * Copyright (c) 2011 Aleksander B. Demko
00004  * This source code is distributed under the MIT license.
00005  * See the accompanying file LICENSE.MIT.txt for details.
00006  */
00007 
00008 #ifndef __INCLUDED_WEXUS_REGISTRY_H__
00009 #define __INCLUDED_WEXUS_REGISTRY_H__
00010 
00011 #include <typeinfo>
00012 
00013 #include <wexus/TR1.h>
00014 
00015 #include <wexus/MemberFunction.h>
00016 
00017 #include <QString>
00018 #include <QMap>
00019 
00020 namespace wexus
00021 {
00022   class Registry;
00023 
00024   template <class T> class RegisterApp;
00025   template <class APPTYPE, class T> class RegisterController;
00026   template <class CONTROLLERTYPE, void (CONTROLLERTYPE::*MFN)(void)> class RegisterAction;
00027 
00028   class Application;  // fwd
00029   class Controller; //fwd
00030 
00031   // convert this to return shared_ptr<>?
00032   typedef Application* (*ApplicationLoader)(void);
00033   template <class SUB> Application* ApplicationLoaderType(void) { return new SUB(); } // cant seem to nest this in ControllerInfo
00034 
00035   // convert this to return shared_ptr<>?
00036   typedef Controller* (*ControllerLoader)(void);
00037   template <class SUB> Controller* ControllerLoaderType(void) { return new SUB(); } // cant seem to nest this in ControllerInfo
00038 
00039   typedef void (*ActionFunc)(Controller *c);
00040 };
00041 
00042 /**
00043  * A type registry for applications, controllers and actions.
00044  * This is a singleton.
00045  *
00046  * @author Aleksander Demko
00047  */ 
00048 class wexus::Registry
00049 {
00050   public:
00051     class ControllerInfo;
00052     class AppInfo
00053     {
00054       public:
00055         typedef QMap<QString, std::shared_ptr<ControllerInfo>  > ControllerMap; // controllers by their name
00056       public:
00057         QString classtype; // the type string (from typeid)
00058         QString appname; // the application name
00059 
00060         ApplicationLoader loader;
00061 
00062         ControllerMap controllers;
00063     };
00064     class ActionInfo;
00065     class ControllerInfo
00066     {
00067       public:
00068         // maps actionames to actions
00069         typedef QMap<QString, std::shared_ptr<ActionInfo>  > ActionMap;
00070       public:
00071         QString classtype; // the type string (from typeid)
00072         QString name; // the controller name
00073 
00074         ControllerLoader loader;
00075 
00076         /// parent app
00077         std::shared_ptr<AppInfo> application;
00078 
00079         /// maps actionames to actions
00080         ActionMap actions;
00081     };
00082     class ActionInfo
00083     {
00084       public:
00085         MemberFunction mfn;
00086         QString actionname;
00087 
00088         /// parent controller
00089         std::shared_ptr<ControllerInfo> controller;
00090 
00091         ActionFunc func;
00092     };
00093 
00094   public:
00095     typedef QMap<QString, std::shared_ptr<AppInfo>  > AppTypeMap; // apps by the typeinfo.name()
00096     typedef QMap<QString, std::shared_ptr<AppInfo>  > AppNameMap; // apps by their name
00097 
00098     typedef QMap<QString, std::shared_ptr<ControllerInfo>  > ControllerTypeMap; // controllers by their typeinfo.name()
00099 
00100     typedef QList<std::shared_ptr<ActionInfo>  > ActionTypeList; // cant be a map cuz MemberFunction doesnt have operator<
00101 
00102     static AppTypeMap & appsByType(void) { return instance()->dm_apptype; }
00103     static AppNameMap & appsByName(void) { return instance()->dm_appname; }
00104 
00105     static ControllerTypeMap & controllersByType(void) { return instance()->dm_contype; }
00106 
00107     static ActionTypeList & actionList(void) { return instance()->dm_actionlist; }
00108 
00109     /// called by RegisterApp
00110     static std::shared_ptr<AppInfo> newAppInfo(const char *_appname, const char *_typename, ApplicationLoader loader);
00111     /// called by RegistrerController
00112     /// creates a app placeholder if needed
00113     static std::shared_ptr<AppInfo> linkAppInfo(const char *_apptype);
00114 
00115     /// called by RegistrerController
00116     static std::shared_ptr<ControllerInfo> newControllerInfo(const char *_cname, const char *_typename, const char *_apptype, ControllerLoader loader);
00117     /// called b y RegisterAction
00118     /// createa a controllerinfo placeholder if needed
00119     static std::shared_ptr<ControllerInfo> linkControllerInfo(const char *_ctype);
00120 
00121     /// called by RegisterAction
00122     static std::shared_ptr<ActionInfo> newActionInfo(wexus::MemberFunction mfn, const char *_actionname, const char *_ctype, ActionFunc func);
00123 
00124   protected:
00125     /// never returns null, makes it if need be
00126     static Registry * instance(void);
00127 
00128   protected:
00129     static Registry *dm_instance;
00130 
00131   protected:
00132     AppTypeMap dm_apptype;
00133     AppNameMap dm_appname;
00134 
00135     ControllerTypeMap dm_contype;
00136 
00137     ActionTypeList dm_actionlist;
00138 };
00139 
00140 template <class T> class wexus::RegisterApp
00141 {
00142   public:
00143     RegisterApp(const char *appname);
00144 };
00145 template <class T> wexus::RegisterApp<T>::RegisterApp(const char *appname)
00146 {
00147   /*std::shared_ptr<Registry::AppInfo> ai = */ Registry::newAppInfo(appname, typeid(T).name(), & ApplicationLoaderType<T> );
00148   // nothing more to fill out, .name is filled by new
00149 }
00150 
00151 template <class APPTYPE, class T> class wexus::RegisterController
00152 {
00153   public:
00154     RegisterController(const char *appname);
00155 };
00156 template <class APPTYPE, class T> wexus::RegisterController<APPTYPE,T>::RegisterController(const char *appname)
00157 {
00158   /*std::shared_ptr<Registry::ControllerInfo> ci =*/ Registry::newControllerInfo(appname, typeid(T).name(), typeid(APPTYPE).name(), & ControllerLoaderType<T> );
00159   // nothing more to fill out, .name is filled by new
00160 }
00161 
00162 template <class CONTROLLERTYPE, void (CONTROLLERTYPE::*MFN)(void)>
00163 class wexus::RegisterAction
00164 {
00165   private:
00166     template <class C, void (C::*LMETH)(void)>
00167       static void methodToFunc(Controller *c)
00168       {
00169         // bounce the function call to a method call
00170         C *here = dynamic_cast<C*>(c);
00171         assert(here);
00172 
00173         ((*here).*LMETH)();
00174       }
00175   public:
00176       RegisterAction(const char *actionname);;
00177 };
00178 
00179 template <class CONTROLLERTYPE, void (CONTROLLERTYPE::*MFN)(void)>
00180 wexus::RegisterAction<CONTROLLERTYPE,MFN>::RegisterAction(const char *actionname)
00181 {
00182   Registry::newActionInfo(MemberFunction(MFN), actionname,
00183       typeid(CONTROLLERTYPE).name(), methodToFunc<CONTROLLERTYPE,MFN>);
00184 }
00185 
00186 #endif
00187 
 All Classes Namespaces Functions Variables Enumerations Enumerator