]> git.tdb.fi Git - libs/core.git/commitdiff
Streamline application class registration
authorMikko Rasa <tdb@tdb.fi>
Mon, 23 May 2011 18:20:23 +0000 (21:20 +0300)
committerMikko Rasa <tdb@tdb.fi>
Tue, 24 May 2011 06:02:35 +0000 (09:02 +0300)
source/core/application.cpp
source/core/application.h

index 17611c1429ac2ef716c1687ba892b3b6356e6f74..a588e9dbb7900cff2b3d15a200f41a9be2382d8f 100644 (file)
@@ -40,9 +40,9 @@ int Application::run(int argc, char **argv, void *data)
        }
        called=true;
 
-       if(!reg_app_)
+       if(!starter_)
        {
-               cerr<<"Trying to run with no application class registered!\n";
+               cerr<<"Trying to run with no RegisteredApplication class!\n";
                return 126;
        }
 
@@ -52,11 +52,11 @@ int Application::run(int argc, char **argv, void *data)
        {
                try
                {
-                       app_=reg_app_->create_app(argc, argv);
+                       app_=starter_->create_app(argc, argv);
                }
                catch(const UsageError &e)
                {
-                       reg_app_->usage(e.what(), argv[0], e.get_brief());
+                       starter_->usage(e.what(), argv[0], e.get_brief());
                        return 1;
                }
 
@@ -144,15 +144,12 @@ void Application::sighandler_(int s)
 }
 
 
-Application::RegBase::RegBase()
+Application::Starter::Starter()
 {
-       if(reg_app_)
-       {
-               cerr<<"Warning: registering the application twice\n";
-               delete reg_app_;
-       }
+       if(starter_)
+               throw InvalidState("Can't create more than one Starter instance");
 
-       reg_app_=this;
+       starter_=this;
 }
 
 Application *Application::app_=0;
index 38df732f1a5779782566d249b701a19ca99011a2..305fbfe34661967a3d8dbeca46ed30f2f9c1596f 100644 (file)
@@ -17,29 +17,22 @@ member of type RegApp<MainClass>.
 class Application
 {
 protected:
-       class RegBase
+       class Starter
        {
-       public:
-               virtual Application *create_app(int, char **)=0;
-               virtual void usage(const char *, const char *, bool)=0;
-               virtual ~RegBase() { }
        protected:
-               RegBase();
-       };
-
-       template<typename T>
-       class RegApp: public RegBase
-       {
+               Starter();
        public:
-               Application *create_app(int argc, char **argv) { return new T(argc, argv); }
-               void usage(const char *r, const char *a, bool b) { T::usage(r, a, b); }
+               virtual ~Starter() { }
+
+               virtual Application *create_app(int, char **) = 0;
+               virtual void usage(const char *, const char *, bool) = 0;
        };
 
        bool done;
        int exit_code;
 
 private:
-       static RegBase *reg_app_;
+       static Starter *starter_;
        static Application *app_;
        static void *data_;
 
@@ -60,11 +53,32 @@ protected:
        virtual void sighandler(int) { }
 private:
        static void sighandler_(int);
+};
 
        Application(const Application &);
        Application &operator=(const Application &);
+
+template<typename T>
+class RegisteredApplication: public Application
+{
+private:
+       class Starter: public Application::Starter
+       {
+       public:
+               Application *create_app(int argc, char **argv) { return new T(argc, argv); }
+               void usage(const char *r, const char *a, bool b) { T::usage(r, a, b); }
+       };
+
+       static Starter starter_;
+
+protected:
+       // Force the starter into existence
+       RegisteredApplication() { (void)starter_; }
 };
 
+template<typename T>
+typename RegisteredApplication<T>::Starter RegisteredApplication<T>::starter_;
+
 } // namespace Msp
 
 #endif