3 This file is part of libmspcore
4 Copyright © 2006 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
9 #include "../debug/demangle.h"
10 #include "../time/units.h"
11 #include "../time/utils.h"
12 #include "application.h"
20 Constructs an instance of the registered application class and runs it. If the
21 application throws a UsageError, the static usage() function is called.
23 This function can only be called once. The global main() function provided by
24 the library normally does it automatically at program startup.
26 int Application::run(int argc, char **argv)
28 static bool called=false;
31 cerr<<"Trying to call Application::run_app twice!\n";
38 cerr<<"Trying to run with no application class registered!\n";
46 app_=reg_app_->create_app(argc, argv);
48 catch(const UsageError &e)
50 reg_app_->usage(e.what(), argv[0], e.get_brief());
54 int result=app_->main();
58 catch(const exception &e)
60 cerr<<"An uncaught exception occurred.\n";
61 cerr<<" type: "<<Debug::demangle(typeid(e).name())<<'\n';
62 cerr<<" what(): "<<e.what()<<'\n';
69 Prints a message describing the usage of the application. The default version
70 will blame the programmer for being lazy.
72 @param reason Why the function was called
73 @param argv0 The value of argv[0], to be used in the message
74 @param brief Whether to print a brief or long usage message
76 void Application::usage(const char *reason, const char *, bool)
79 cerr<<"UsageError: "<<reason<<'\n';
80 cerr<<"The programmer was lazy and didn't write a usage() function for this application.\n";
83 Application::Application():
85 loop_mode_(TICK_SLEEP)
89 Default main loop. Behavior depends on loop_mode_. A custom main loop should
90 monitor the done member variable and return exit_code.
92 int Application::main()
100 if(loop_mode_==SLEEP)
106 else if(loop_mode_==TICK_SLEEP)
109 Time::sleep(Time::msec);
111 else if(loop_mode_==TICK_YIELD)
126 Sets the specified signal to be delivered to the sighandler member function.
128 void Application::catch_signal(int s)
130 signal(s, &sighandler_);
134 Changes the main loop mode.
136 void Application::set_loop_mode(LoopMode l)
138 LoopMode old_mode=loop_mode_;
145 Causes the tick() function to be executed once if loop mode is SLEEP. Has no
146 effect with other loop modes.
148 void Application::induce_tick()
150 if(loop_mode_==SLEEP)
155 Causes the application to exit gracefully with the given exit code.
157 void Application::exit(int c)
161 if(loop_mode_==SLEEP)
166 Static wrapper function to call a member function of the Application instance.
168 void Application::sighandler_(int s)
173 Application::RegBase::RegBase()
177 cerr<<"Warning: registering the application twice\n";
184 Application *Application::app_=0;
185 Application::RegBase *Application::reg_app_=0;