Fixed the terminal not fully functional error
[utio.git] / demo / stdmain.h
blob4f92ed1957e65b5d3ce9bec1573a39f702435320
1 // This file is part of the utio library, a terminal I/O library.
2 //
3 // Copyright (C) 2004 by Mike Sharov <msharov@users.sourceforge.net>
4 // This file is free software, distributed under the MIT License.
5 //
6 // \file stdmain.h
7 //
8 // \brief Standard program main with error handling.
9 //
10 // The reason for using the singleton and all this error handling is that it
11 // is very important for CKeyboard object to be able to clean up on exit. If
12 // it fails to do so, the keyboard remains in the UI state and the shell will
13 // not be very usable. There will be no echo, no cursor, and no scrollback.
14 // (You can manually fix it with "stty sane" and "echo ^v ESC c")
16 // So main installs various cleanup handlers to catch fatal conditions, like
17 // signals, exceptions, or terminates, and exit normally, calling destructors
18 // on all objects. The singleton pattern is required because if the program
19 // exits from a signal handler, destructors of local objects in main will not
20 // be called, resulting in a garbled console. Hence the static Instance()
21 // function, whose static member object is destructed on exit.
23 // This cleanup problem is common to all UI environments, be it console, the
24 // framebuffer, or X. Crashing the UI environment without cleanup is a very
25 // bad idea and you will have to write something like the code in this file
26 // for every UI framework you choose to implement on top of utio.
29 #ifndef STDMAIN_H_6A5A6F7B06CC2ED07880C5283C61797A
30 #define STDMAIN_H_6A5A6F7B06CC2ED07880C5283C61797A
32 #include <utio.h>
33 using namespace utio;
34 using namespace utio::gdt;
35 using namespace ustl;
37 extern "C" void InstallCleanupHandlers (void);
39 /// Declares singleton Instance() call in \p DemoClass.
40 #define DECLARE_SINGLETON(DemoClass) \
41 static DemoClass& Instance (void) { static DemoClass obj; return (obj); }
43 /// Exception handling harness for demos
44 template <typename T>
45 int RunDemo (void) throw()
47 int rv = EXIT_FAILURE;
48 try {
49 T::Instance().Run();
50 rv = EXIT_SUCCESS;
51 } catch (ustl::exception& e) {
52 cout.flush();
53 cerr << "Error: " << e << endl;
54 } catch (...) {
55 cout.flush();
56 cerr << "Unexpected error." << endl;
58 return (rv);
61 /// Standard main with error handling.
62 #define StdDemoMain(DemoClass) \
63 int main (void) \
64 { \
65 InstallCleanupHandlers(); \
66 return (RunDemo<DemoClass>()); \
69 #endif