src/proto2/Application.cc
author terom
Thu, 20 Nov 2008 19:25:56 +0000
branchno-netsession
changeset 36 785d220fc6b7
parent 35 e21cfda0edde
child 38 4189b8bf3a5b
permissions -rw-r--r--
...

#include "Engine.hh"
#include "Error.hh"

#include <stdexcept>
#include <cassert>

#include <ClanLib/core.h>
#include <ClanLib/application.h>

class ArgumentError : public Error {
    public:
        ArgumentError (const std::string &message) : Error(message) { }
};

class Main : public CL_ClanApplication {
    private:
        // arguments
        CL_CommandLine args;
        
        bool arg_graphics;
        std::string arg_port;
        bool arg_server;
        std::string arg_connect;

        void parse_args (int argc, char **argv) {
            // set up the options
            args.add_option('p', "port", "PORT", "set network port used", true);
            args.add_option('s', "server", "", "act as a network server", true);
            args.add_option('c', "client", "SERVERHOST", "act as a network client", true);
            args.add_option('g', "graphics", "", "run graphics/local input. Implied with --connect", true);

            // set defaults
            arg_graphics = false;
            arg_port = NETWORK_PORT_STR;
            arg_server = false;
            arg_connect = "";
            
            try {
                // parse args
                args.parse_args(argc, argv);

            } catch (CL_Error &e) {
                throw ArgumentError(e.message);
            }

            while (args.next()) {
                switch (args.get_key()) {
                    case 'p':
                        arg_port = args.get_argument();
                        break;

                    case 's':
                        arg_server = true;
                        break;

                    case 'c':
                        arg_connect = args.get_argument();
                        arg_graphics = true;
                        break;

                    case 'g':
                        arg_graphics = true;
                        break;

                    case CL_CommandLine::REST_ARG:
                        throw ArgumentError(args.get_argument());

                    default:
                        throw ArgumentError(std::string(1, (char) args.get_key()));

                }
            }
            
            // check for invalid combinations of arugments
            if (arg_server and !arg_connect.empty())
                throw ArgumentError("cannot be both server and client");
        }

    public:
        virtual int main (int argc, char **argv) {
            // initialize the ClanLib components that we use
            CL_SetupCore setup_core;
            CL_SetupNetwork setup_network;
            CL_SetupDisplay setup_disp;
            CL_SetupGL setup_gl;

            try {
                // parse arugments
                parse_args(argc, argv);

                // our engine
                Engine engine;
                
                // setup graphics
                if (arg_graphics)
                    engine.setupGraphics();

                // setup either network server, client or singleplayer
                if (arg_server) {
                    engine.setupNetworkServer(arg_port);

                } else if (!arg_connect.empty()) {
                    engine.setupNetworkClient(arg_connect, arg_port);
                
                } else {
                    engine.setupSinglePlayer();
                }

                // run the main loop
                engine.run();
                
                // succesful return
                return 0;
            
            } catch (ArgumentError &e) {
                std::cerr << e.what() << std::endl;
                args.print_help();

                // XXX: handle --help
                return 1;

            } catch (std::exception &e) {
                std::cerr << e.what() << std::endl;

                return 1;
            }
        }
} app;