]> git.tdb.fi Git - libs/core.git/blob - source/core/application.h
d5a571a28a9f73306dffae3e99b470e39a2fcb47
[libs/core.git] / source / core / application.h
1 #ifndef MSP_CORE_APPLICATION_H_
2 #define MSP_CORE_APPLICATION_H_
3
4 #include <stdexcept>
5 #include <string>
6 #include "mspcore_api.h"
7 #include "noncopyable.h"
8
9 namespace Msp {
10
11 /**
12 Base class for applications.  See also RegisteredApplication.
13 */
14 class MSPCORE_API Application: private NonCopyable
15 {
16 protected:
17         class MSPCORE_API Starter
18         {
19         protected:
20                 Starter();
21         public:
22                 virtual ~Starter() = default;
23
24                 virtual Application *create_app(int, char **) = 0;
25         };
26
27         bool done = false;
28         int exit_code = 0;
29
30 private:
31         static Starter *_starter;
32         static Application *_app;
33         static const char *_argv0;
34         static std::string _name;
35         static void *_data;
36
37 protected:
38         Application(const std::string & = std::string());
39 public:
40         virtual ~Application() = default;
41
42         /** Constructs an instance of the registered application class and runs it.
43         If the application throws a usage_error, a help message is printed.  The
44         GetOpt class will throw such exceptions automatically in error conditions.
45
46         This function can only be called once.  The global main() function provided
47         by the library normally does it automatically at program startup. */
48         static int run(int, char **, void * = nullptr, void (*)(void *) = nullptr);
49
50         /** Sets application startup info, including argv[0] value and platform-
51         specific data.
52
53         This function can only be called once, and is normally called by
54         Application::run(). */
55         static void set_startup_info(const char *, void *);
56
57         static void *get_data();
58         static const char *get_argv0();
59         static const std::string &get_name();
60
61 protected:
62         /** Default main loop.  Calls tick() repeatedly until exit() is called.  A
63         custom main loop should monitor the done member variable and return
64         exit_code. */
65         virtual int main();
66
67         /** Sets the specified signal to be delivered to the sighandler member
68         function. */
69         void catch_signal(int);
70
71         /** Causes the application to exit gracefully with the given exit code. */
72         void exit(int);
73
74         virtual void tick() { }
75         virtual void sighandler(int) { }
76
77 private:
78         /** Static wrapper function to call a member function of the Application
79         instance. */
80         static void _sighandler(int);
81 };
82
83
84 /**
85 Registers the class to be used for program startup.  The main application class
86 should be derived from this.
87 */
88 template<typename T>
89 class RegisteredApplication: public Application
90 {
91 private:
92         class Starter: public Application::Starter
93         {
94         public:
95                 Application *create_app(int argc, char **argv) { return new T(argc, argv); }
96         };
97
98         static Starter _starter;
99
100 protected:
101         RegisteredApplication(const std::string &n = std::string()):
102                 Application(n)
103         { (void)_starter; }  // Force the starter into existence
104 };
105
106 template<typename T>
107 typename RegisteredApplication<T>::Starter RegisteredApplication<T>::_starter;
108
109 } // namespace Msp
110
111 #endif