]> git.tdb.fi Git - libs/core.git/blob - source/core/application.cpp
Add window and input management signals for Android
[libs/core.git] / source / core / application.cpp
1 #include <typeinfo>
2 #include <signal.h>
3 #include <msp/debug/demangle.h>
4 #include <msp/debug/errorreporter.h>
5 #include <msp/io/print.h>
6 #include "application.h"
7 #include "getopt.h"
8
9 using namespace std;
10
11 namespace Msp {
12
13 Application *Application::app_ = 0;
14 Application::Starter *Application::starter_ = 0;
15 void *Application::data_ = 0;
16
17 Application::Application():
18         exit_code(0)
19 {
20         if(app_)
21                 throw logic_error("instance already exists");
22 }
23
24 int Application::run(int argc, char **argv, void *data, void (*created_callback)(void *))
25 {
26         if(!starter_)
27         {
28                 IO::cerr.write("Application::run called with no RegisteredApplication class!\n");
29                 return 126;
30         }
31
32         data_ = data;
33
34         try
35         {
36                 try
37                 {
38                         app_ = starter_->create_app(argc, argv);
39                 }
40                 catch(const usage_error &e)
41                 {
42                         IO::print(IO::cerr, "%s\n%s\n", e.what(), e.help());
43                         return 1;
44                 }
45
46                 if(created_callback)
47                         created_callback(data);
48
49                 int result = app_->main();
50                 Application *a = app_;
51                 app_ = 0;
52                 delete a;
53                 return result;
54         }
55         catch(const exception &e)
56         {
57                 bool handled = false;
58                 if(const Debug::ErrorReporter *er = Debug::ErrorReporter::get_current())
59                         handled = er->report_uncaught_exception(e);
60
61                 if(!handled)
62                 {
63                         IO::print(IO::cerr, "An uncaught exception occurred.\n");
64                         IO::print(IO::cerr, "  type:   %s\n", Debug::demangle(typeid(e).name()));
65                         IO::print(IO::cerr, "  what(): %s\n", e.what());
66                 }
67
68                 delete app_;
69                 app_ = 0;
70
71                 return 124;
72         }
73 }
74
75 int Application::main()
76 {
77         done = false;
78         while(!done)
79                 tick();
80
81         return exit_code;
82 }
83
84 void Application::catch_signal(int s)
85 {
86         signal(s, &sighandler_);
87 }
88
89 void Application::exit(int c)
90 {
91         done = true;
92         exit_code = c;
93 }
94
95 void Application::sighandler_(int s)
96 {
97         app_->sighandler(s);
98 }
99
100
101 Application::Starter::Starter()
102 {
103         if(starter_)
104                 throw logic_error("Can't create more than one Starter instance");
105
106         starter_ = this;
107 }
108
109 } // namespace Msp