src/proto2/Application.cc
author terom
Sun, 09 Nov 2008 20:40:46 +0000
changeset 24 b81cb670e6b2
parent 22 b70d30e1b0fe
child 25 af75a1894a32
permissions -rw-r--r--
the great :retab

#include "Engine.hh"

#include <stdexcept>
#include <cassert>

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

class ArgumentError : public std::exception {
    private:
        const char *message;
    
    public:
        ArgumentError (const std::string &message) : message(message.c_str()) { }

        virtual const char* what() const throw() {
            return message;
        }
};

class Main : public CL_ClanApplication {
    private:
        // arguments
        CL_CommandLine args;

        std::string arg_port;
        bool arg_dedicated;
        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('D', "dedicated", "", "act as a network server", true);
            args.add_option('c', "connect", "SERVERHOST", "act as a network client", true);

            // set defaults
            arg_port = NETWORK_PORT_STR;
            arg_dedicated = 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 'D':
                        arg_dedicated = true;
                        break;

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

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

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

                }
            }
            
            // check for valid combinations of arugments
            if (arg_dedicated && !arg_connect.empty())
                throw ArgumentError("-D and -c are mutually exclusive");
            
            if (!arg_dedicated && arg_connect.empty())
                throw ArgumentError("nothing to do");
        }

    public:
        virtual int main (int argc, char **argv) {
            // initialize core
            CL_SetupCore setup_core;
            
            try {
                // parse arugments
                parse_args(argc, argv);
                
                // run engine based on args
                if (arg_dedicated) {
                    Engine::runNetworkServer(arg_port);

                } else if (!arg_connect.empty()) {
                    Engine::runNetworkClient(arg_connect, arg_port);
                
                } else
                    assert(false);
                
                // 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;