libASSA Programmer's Manual | ||
---|---|---|
<<< Previous | Chapter 1. Application Shell | Next >>> |
GenServer is based on the idea of organizing your C++ application in such manner that would allow you to avoid global variables as discussed in B. Stroustrup's "The C++ Progamming Language" [BjarneStroustrup97]. GenServer is an encapsulation of the most commonly used characteristics of a UNIX application. To create the actual application, you start with deriving your application class from GenServer base class. We derive our application class, HelloWorld from base class GenServer. File HelloWorld.h holds the class declaration:
Example 1-1. Example of the application framework (header file)
// HelloWorld.h 021 #ifndef HelloWorld_H 022 #define HelloWorld_H 023 024 025 #ifdef HAVE_CONFIG_H 026 # include "config.h" 027 #endif 028 #include <string> 029 using std::string; 030 031 #include <assa/GenServer.h> 032 #include <assa/Singleton.h> 033 #include <assa/TimeVal.h> 034 035 class HelloWorld : 036 public ASSA::GenServer, 037 public ASSA::Singleton<HelloWorld> 038 { 039 public: 040 HelloWorld (); 041 042 virtual void initServer (); 043 virtual void processServer (); 044 045 int get_exit_value () const { return m_exit_value; } 046 void set_exit_value (int v_) { m_exit_value = v_; } 047 048 private: 049 int m_exit_value; // Return status of the process 050 }; 051 052 053 /* Useful definitions */ 054 055 #define HELLOWORLD HelloWorld::getInstance() 056 #define REACTOR HELLOWORLD->getReactor() 057 058 059 #endif // HelloWorld_H |
Lines 25-27 attempt to include config.h if you happen to use automake tool.
Lines 31-33 include libassa header files.
Lines 35-37 derives class HelloWorld from both GenServer and Singleton<> classes. The latter is simply an implementation of Singleton Pattern (see Section 4.14). This ensures that our HelloWorld class can only be instantiated once per program lifetime.
Line 42 overloads initServer() virtual function. It is a placeholder for the initialization code you might want to execute before going into the data processing phase.
Lines 43 overloads processServer() virtual function. It is a placeholder for you event loop to process data.
Lines 45-49 deal with the return code of the program. This is mostly useful when you write test cases for your application. If test fails, the return value can be examined by the shell script to determine the outcome of the test.
Line 55 defines a shortcut for HelloWorld object. HelloWorld is a Singleton object that can be located from any part of your program. This way you can hide all global variables of your program in the scope of HelloWorld. They can be easily referenced using HELLOWORLD shortcut.
Line 56 is a shortcut to the even processing class, Reactor (see Section 4.8 for details.
Example 1-2. Example of the application framework (constructor)
// HelloWorld.cpp 026 HelloWorld* ASSA::Singleton<HelloWorld>::m_instance; 027 ASSA::Destroyer<HelloWorld> ASSA::Singleton<HelloWorld>::m_destroyer; 028 029 HelloWorld:: 030 HelloWorld () : 031 m_exit_value (0) 032 { 033 ... 062 m_debug_mask = ASSA::APP | ASSA::ERROR; 063 m_log_file = "HelloWorld.log"; 064 } 065 |
Lines 26-27 define static global variable of Singleton class that have to be defined in the translation unit.
Lines 29-64 define constructor for HelloWorld class.
Line 62 defines the debugging mask. Only logging messages of level ASSA::APP or ASSA::ERROR will be written to the log file.
Line 63 sets the name of the log file to the file HelloWorld.log.
Example 1-3. Example of the log file, HelloWorld.log
[GenServer::initInternals] [GenServer::initInternals] ================================================== [GenServer::initInternals] || Server configuration settings || [GenServer::initInternals] ================================================== [GenServer::initInternals] cmd_line_name = 'HelloWorld' [GenServer::initInternals] name = 'HelloWorld' [GenServer::initInternals] std cfg fname = '/home/vlg/.gnome/HelloWorld' [GenServer::initInternals] alt cfg fname = '' [GenServer::initInternals] debug_mask = 0x22 [GenServer::initInternals] ================================================== [GenServer::initInternals] [HelloWorld::initServer] Service has been initialized [HelloWorld::processServer] Service stopped! |
Log file shows that at some point initInternals() function of class GenServer was called to initialize base class internals. It also reported some basing configuration settings. Then initServer() function of class HelloWorld was called to initialize the program. At the end, processServer() function was called to perform data processing.
Example 1-4. Framework initialization
// From HelloWorld.cpp 067 void 068 HelloWorld:: 069 initServer () 070 { 071 trace("HelloWorld::initServer"); 072 073 // 074 // Insert initialization code here 075 // 076 077 DL((ASSA::APP,"Service has been initialized\n")); 078 } |
Function initServer() is the initialization code placeholder. Here you might want to open and parse your configuration file and initialize other components (such as mapping GUI mainwindow on the screen or, perhaps, opening listening socket as a TCP/IP server).
Example 1-5. Framework data processing
// From HelloWorld.cpp 079 080 #include <iostream> 081 082 void 083 HelloWorld:: 084 processServer () 085 { 086 trace("HelloWorld::processServer"); 087 088 // while (!stopServer()) { 089 // m_reactor.waitForEvents (); 090 // } 091 // 092 093 std::cout << "Hello, World!" << std::endl; 094 095 // Shut the service down 096 m_reactor.stopReactor (); 097 DL((ASSA::APP,"Service stopped!\n")); 098 } |
Function processServer() is where data processing activity of the program occurs. Both client and server applications would have some kind of an event loop here.
Lines 88-90 illustrate the event processing loop of GenServer framework. It mainly consists of asking Reactor to process events indefinitely. We have commented out these lines for our "Hello, World!" example.
We added line 93 to print "Hello, World!" message to the standard output.
Line 96 writes a message to the log file at the log level ASSA::APP.
Line 97 shuts down Reactor class.
<<< Previous | Home | Next >>> |
Hello, World! | Up | What's Under The Hood? |