aesop-server/app/aesop-server/main.cpp

Go to the documentation of this file.
00001 /*
00002  * main.cpp
00003  *
00004  * Copyright (C) 2007-2009  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  *
00031  * Entry point for the aesop server.  Uses the aesop-srv library.
00032  */
00033 
00034 // includes --------------------------------------------------------------------
00035 #include <signal.h>
00036 
00037 #include "cmdline/cmdline.h"    // command-line parsing
00038 #include "aesop-srv/aesop-srv.h"        // server object
00039 #include "datahash/datahash_text.h"
00040 #include "mapzone/mapzone.h"    // reference implementation of maps/zones
00041 #include "perf/perf.h"
00042 #include "physics-loader/physics-loader.h"
00043 #include "srv-game-logic/srv-game-logic.h"
00044 
00045 
00046 
00047 ////////////////////////////////////////////////////////////////////////////////
00048 ///
00049 /// \ingroup aesop_app
00050 /// \defgroup aesop_server AESOP Reference Server
00051 ///
00052 /// \n
00053 /// The aesop server is the binary that runs on the server, and accepts client
00054 /// connections.
00055 ///
00056 /// The application code is minimal.  Pretty much all of the functionality is
00057 /// in the \ref aesop_srv, accessed through the aesop::Server object.
00058 ///
00059 ////////////////////////////////////////////////////////////////////////////////
00060 /*@{*/
00061 
00062 
00063 static smart_ptr<aesop::Server> s_server;       // the aesop server object
00064 
00065 
00066 ////////////////////////////////////////////////////////////////////////////////
00067 //
00068 //      static helper methods
00069 //
00070 ////////////////////////////////////////////////////////////////////////////////
00071 
00072 static void
00073 signalHandlerHUP
00074 (
00075 IN int signal
00076 )
00077 {
00078         if (s_server) {
00079                 int retval = 3;
00080                 s_server->requestStopTS(retval);
00081         }
00082 }
00083 
00084 
00085 
00086 static void
00087 initializeServer
00088 (
00089 IN const char * config_file
00090 )
00091 {
00092         perf::Timer timer("initializeServer");
00093         ASSERT(config_file, "null");
00094 
00095         // register our reference map implementation
00096         //   (server object shouldn't know about map implementations)
00097         smart_ptr<aesop::MapFormatReader> reader =
00098             mapzone::getMapFormatReader();
00099         ASSERT(reader, "failed to create basic map reader");
00100         aesop::registerMapFormatReader(reader);
00101 
00102         // register our physics loader
00103         smart_ptr<aesop::TypeComponentLoader> physics =
00104             aesop::getPhysicsLoader();
00105         ASSERT(physics, "failed to create physics loader");
00106         aesop::registerTypeComponentLoader(physics);
00107         DPRINTF("Just registered physics loader!");
00108 
00109         // load server config file
00110         smart_ptr<Datahash> server_params =
00111             readHashFromTextFile(config_file);
00112         ASSERT(server_params, "Failed to read server parameters");
00113 
00114         // create the server-side game logic
00115         smart_ptr<aesop::ServerGameLogic> gameLogic =
00116             aesop::createServerGameLogic();
00117         ASSERT(gameLogic, "Failed to create game logic object");
00118 
00119         // create server object
00120         s_server = aesop::Server::create(server_params, gameLogic);
00121         ASSERT(s_server, "failed to create server?");
00122 }
00123 
00124 
00125 
00126 ////////////////////////////////////////////////////////////////////////////////
00127 //
00128 //      entry point
00129 //
00130 ////////////////////////////////////////////////////////////////////////////////
00131 
00132 int
00133 main
00134 (
00135 IN int argc,
00136 IN const char * argv[]
00137 )
00138 {
00139         smart_ptr<CommandLine> cmd = CommandLine::create(argc, argv);
00140         ASSERT(cmd, "failed to create command-line parser");
00141 
00142         const char * srv_config_file = getSingleKeyValue(cmd, "config-file",
00143             true, "file that contains aesop server operational config");
00144         ASSERT(srv_config_file, "null");
00145 
00146         // add a signal handler...
00147         struct sigaction sigact;
00148         sigact.sa_handler = signalHandlerHUP;
00149         sigact.sa_flags = 0;
00150         ASSERT(!sigaction(SIGHUP, &sigact, NULL),
00151             "Failed to register handler for SIGHUP");
00152         ASSERT(!sigaction(SIGINT, &sigact, NULL),
00153             "Failed to register handler for SIGINT");
00154         ASSERT(!sigaction(SIGTERM, &sigact, NULL),
00155             "Failed to register handler for SIGTERM");
00156 
00157         int retval = 0;
00158         try {
00159                 perf::Timer timer("aesop-server-main");
00160 
00161                 // initialize
00162                 initializeServer(srv_config_file);
00163                 ASSERT(s_server, "should have server now!");
00164 
00165                 // actually run
00166                 retval = s_server->exec();
00167 
00168         } catch (std::exception& e) {
00169                 DPRINTF("Caught exception: %s", e.what());
00170                 retval = 1;
00171         } catch (...) {
00172                 DPRINTF("Caught unknown exception!");
00173                 retval = 2;
00174         }
00175 
00176         std::string summary;
00177         perf::getTimingSummary(summary);
00178         DPRINTF("Timers:\n%s", summary.c_str());
00179 
00180         return retval;
00181 }
00182