3 This file is part of libmspcore
4 Copyright © 2006-2008, 2011 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
11 #include "../debug/backtrace.h"
12 #include "../debug/demangle.h"
13 #include "../time/units.h"
14 #include "../time/utils.h"
15 #include "application.h"
22 Application *Application::app_ = 0;
23 Application::Starter *Application::starter_ = 0;
24 void *Application::data_ = 0;
26 Application::Application():
31 Constructs an instance of the registered application class and runs it. If the
32 application throws a UsageError, the static usage() function is called.
34 This function can only be called once. The global main() function provided by
35 the library normally does it automatically at program startup.
37 int Application::run(int argc, char **argv, void *data)
39 static bool called = false;
42 cerr<<"Trying to call Application::run_app twice!\n";
49 cerr<<"Trying to run with no RegisteredApplication class!\n";
59 app_ = starter_->create_app(argc, argv);
61 catch(const UsageError &e)
63 starter_->usage(e.what(), argv[0], e.get_brief());
67 int result = app_->main();
68 Application *a = app_;
73 catch(const exception &e)
78 string msg = Debug::demangle(typeid(e).name())+":\n"+e.what();
79 MessageBoxA(0, msg.c_str(), "Uncaught exception", MB_OK|MB_ICONERROR);
81 cerr<<"An uncaught exception occurred.\n";
82 cerr<<" type: "<<Debug::demangle(typeid(e).name())<<'\n';
83 cerr<<" what(): "<<e.what()<<'\n';
85 const Exception *exc = dynamic_cast<const Exception *>(&e);
86 if(exc && !exc->get_backtrace().get_frames().empty())
88 cerr<<" backtrace:\n";
89 const list<Debug::Backtrace::StackFrame> &frames = exc->get_backtrace().get_frames();
90 for(list<Debug::Backtrace::StackFrame>::const_iterator i=frames.begin(); i!=frames.end(); ++i)
100 Prints a message describing the usage of the application. The default version
101 will blame the programmer for being lazy.
103 @param reason Why the function was called
104 @param argv0 The value of argv[0], to be used in the message
105 @param brief Whether to print a brief or long usage message
107 void Application::usage(const char *reason, const char *, bool)
110 cerr<<"UsageError: "<<reason<<'\n';
111 cerr<<"The programmer was lazy and didn't write a usage() function for this application.\n";
115 Default main loop. Calls tick() repeatedly until exit() is called. A custom
116 main loop should monitor the done member variable and return exit_code.
118 int Application::main()
128 Sets the specified signal to be delivered to the sighandler member function.
130 void Application::catch_signal(int s)
132 signal(s, &sighandler_);
136 Causes the application to exit gracefully with the given exit code.
138 void Application::exit(int c)
145 Static wrapper function to call a member function of the Application instance.
147 void Application::sighandler_(int s)
153 Application::Starter::Starter()
156 throw InvalidState("Can't create more than one Starter instance");