src/proto2/Application.cc
author terom
Sat, 08 Nov 2008 18:02:58 +0000
changeset 21 32c6cc55256a
child 22 b70d30e1b0fe
permissions -rw-r--r--
change proto2 network code to use CL_NetSession

#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

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

				return 1;
			}
		}
} app;