From 583ec3285c41e9d253c4aaabd2af4dadac75f3a7 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 23 Nov 2008 12:34:07 +0000 Subject: clean module consturction/destruction --- src/core/Makefile.am | 6 +-- src/core/application.cc | 66 ++++++++++------------------- src/core/application.h | 3 +- src/core/commandbuffer.cc | 3 +- src/core/gameserver.cc | 22 ++++++---- src/core/loader.cc | 93 ++++++++++++++++++++++++++++++++++++++++ src/core/loader.h | 62 +++++++++++++++++++++++++++ src/core/module.cc | 106 ++++++---------------------------------------- src/core/module.h | 58 +++---------------------- 9 files changed, 216 insertions(+), 203 deletions(-) create mode 100644 src/core/loader.cc create mode 100644 src/core/loader.h (limited to 'src/core') diff --git a/src/core/Makefile.am b/src/core/Makefile.am index fbdf311..317a99e 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -3,8 +3,8 @@ INCLUDES = -I$(top_srcdir)/src libcore_la_SOURCES = application.cc commandbuffer.cc core.cc cvar.cc \ descriptions.cc entity.cc extension.cc func.cc gameconnection.cc gameinterface.cc \ - gameserver.cc module.cc netclient.cc netconnection.cc netplayer.cc netserver.cc \ - parser.cc player.cc stats.cc timer.cc zone.cc + gameserver.cc loader.cc module.cc netclient.cc netconnection.cc netplayer.cc \ + netserver.cc parser.cc player.cc stats.cc timer.cc zone.cc libcore_la_LDFLAGS = -avoid-version -no-undefined libcore_la_LIBADD = $(top_builddir)/src/model/libmodel.la \ $(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/math/libmath.la $(top_builddir)/src/sys/libsys.la \ @@ -14,4 +14,4 @@ noinst_LTLIBRARIES = libcore.la noinst_HEADERS = application.h commandbuffer.h core.h cvar.h entity.h func.h \ gameconnection.h gameinterface.h gameserver.h message.h module.h net.h netclient.h \ netconnection.h netserver.h player.h range.h stats.h timer.h parser.h descriptions.h \ - extension.h + extension.h loader.h diff --git a/src/core/application.cc b/src/core/application.cc index f24f0f7..1cba59a 100644 --- a/src/core/application.cc +++ b/src/core/application.cc @@ -23,6 +23,7 @@ #include "core/func.h" #include "core/gameconnection.h" #include "core/gameserver.h" +#include "core/loader.h" namespace core { @@ -66,7 +67,7 @@ Application *Application::application_instance = 0; Application::Application() { if (application_instance) { - std::cerr << "multiple core::Application instances!\n"; + std::cerr << "multiple core::Application instances\n"; sys::quit(2); } @@ -74,8 +75,6 @@ Application::Application() application_timestamp = 0; application_game = 0; - module_interactive = 0; - #ifndef _WIN32 sys::signal(SIGHUP, signal_handler); sys::signal(SIGINT, signal_handler); @@ -97,7 +96,9 @@ void Application::init(int count, char **arguments) { con_print << "^BInitializing core...\n"; con_debug << " debug messages enabled\n"; + filesystem::init("base", ""); + Loader::load("base"); CommandBuffer::init(); @@ -210,7 +211,7 @@ void Application::shutdown() save_config(); - Module::clear(); + Loader::clear(); // remove our engine functions Func::remove("msg"); @@ -238,57 +239,34 @@ void Application::quit(int status) } -Module *Application::load(std::string const &module_label) +bool Application::load(std::string const &label) { - if (!module_label.size()) { - if (Module::active()) { - con_print << " active module: " << Module::active()->label() << " " << Module::active()->name() << std::endl; - } - if (Module::loaded()) { - con_print << " loaded module: " << Module::loaded()->label() << " " << Module::loaded()->name() << std::endl; - } - if (module_interactive) { - con_print << " fallback module: " << module_interactive->label() << " " << module_interactive->name() << std::endl; - } - std::string helpstr(" available modules:"); - for(Module::Registry::iterator it = Module::registry().begin(); it != Module::registry().end(); it++) { - helpstr += ' '; - helpstr += (*it).first; - } - con_print << helpstr << std::endl; - return 0; + if (!label.size()) { + Loader::list(); + return false; } -/* - if (Module::active() && Module::active()->interactive()) { + + if (connected() && game()->interactive()) { con_warn << "Connected. Disconnect first.\n"; - return 0; + return false; } -*/ - if (Module::loaded() && Module::loaded()->interactive()) { - module_interactive = Module::loaded(); + + if (!Loader::load(label)) { + return false; } - return Module::load(module_label.c_str()); + + return true; } void Application::connect(std::string const &host) { - if (connected()) { - if (!Module::active()->interactive()) { - if ((Module::loaded() == Module::active()) && (module_interactive)) { - disconnect(); - Module::load(module_interactive->label().c_str()); - } else { - disconnect(); - } - } else { - con_warn << "Connected. Disconnect first.\n"; - return; - } + if (connected() && game()->interactive()) { + con_warn << "Connected. Disconnect first.\n"; + return; } if (application_game) { - delete application_game; - application_game = 0; + disconnect(); } if (host.size()) { @@ -317,9 +295,9 @@ void Application::connect(std::string const &host) void Application::disconnect() { if(application_game) { - notify_disconnect(); delete application_game; application_game = 0; + notify_disconnect(); con_print << "^BDisconnected.\n"; } } diff --git a/src/core/application.h b/src/core/application.h index e992131..45c316f 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -51,7 +51,7 @@ public: void disconnect(); /// load a module - Module *load(std::string const &module_name); + bool load(std::string const &module_name); /*----- virtual mutators ------------------------------------------ */ @@ -105,7 +105,6 @@ private: unsigned long application_timestamp; GameInterface *application_game; - Module *module_interactive; static Application *application_instance; diff --git a/src/core/commandbuffer.cc b/src/core/commandbuffer.cc index 4addd10..98cdc7a 100644 --- a/src/core/commandbuffer.cc +++ b/src/core/commandbuffer.cc @@ -17,6 +17,7 @@ #include "core/gameconnection.h" #include "core/func.h" #include "core/cvar.h" +#include "core/loader.h" #include "core/zone.h" namespace core @@ -72,7 +73,7 @@ void func_list_model(std::string const &args) void func_list_module(std::string const &args) { - Module::list(); + Loader::list(); } void func_set(std::string const &args) diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index b8f8730..f614fa9 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -12,6 +12,7 @@ #include "core/cvar.h" #include "core/func.h" #include "core/gameserver.h" +#include "core/loader.h" #include "core/netserver.h" #include "filesystem/filesystem.h" #include "sys/sys.h" @@ -125,26 +126,28 @@ GameServer::GameServer() : GameInterface() server_maxplayerid = 1; server_startup = application()->timestamp(); - server_module = Module::loaded(); + server_module = Loader::init(); if (!server_module) { con_error << "No module loaded.\n"; abort(); return; } - if (server_module->interactive()) - load_config(); //FIXME interferes with command line because of cmd.exec - - // set the name of the game - core::Cvar::set("g_name", server_module->name().c_str(), core::Cvar::Game | core::Cvar::ReadOnly); - - server_module->run(); if (!server_module->running()) { con_error << "Could not initialize module '" << server_module->name() << "'\n"; abort(); return; } + if (server_module->interactive()) { + //FIXME interferes with command line because of cmd.exec + load_config(); + } + + // set the name of the game + core::Cvar::set("g_name", server_module->name().c_str(), core::Cvar::Game | core::Cvar::ReadOnly); + + con_print << " module '^B" << server_module->name() << "^N'\n"; if (server_module->interactive() && (Cvar::sv_dedicated->value() || Cvar::sv_private->value())) { @@ -205,7 +208,8 @@ GameServer::~GameServer() if (server_module->running() && !Cvar::sv_dedicated->value()) player_disconnect(localplayer()); - server_module->terminate(); + delete server_module; + server_module = 0; } Func::remove("kick"); diff --git a/src/core/loader.cc b/src/core/loader.cc new file mode 100644 index 0000000..46e0990 --- /dev/null +++ b/src/core/loader.cc @@ -0,0 +1,93 @@ +/* + core/loader.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "auxiliary/functions.h" +#include "core/loader.h" +#include "sys/sys.h" + +namespace core { + +Loader::Registry Loader::loader_registry; +std::string Loader::loader_label; + +Loader::FactoryFuncPtr Loader::find(const char *label) +{ + Registry::iterator it = loader_registry.find(label); + if (it == loader_registry.end()) + return 0; + else + return (*it).second; +} + +Loader::FactoryFuncPtr Loader::find(const std::string &label) +{ + return (find(label.c_str())); +} + +void Loader::add(const std::string &label, FactoryFuncPtr factory) +{ + if (find(label)) { + con_warn << "module '" << label << "' already registered" << std::endl; + return; + } + + loader_registry[label] = factory; + con_debug << " registering module '" << label << "'" << std::endl; +} + +bool Loader::load(const char *label) +{ + FactoryFuncPtr factory = find(label); + if (!factory) { + con_warn << "module '" << label << "' not found" << std::endl; + return false; + } + + con_debug << " loading module '" << label << "'" << std::endl; + loader_label.assign(label); + return true; +} + +bool Loader::load(const std::string &label) +{ + return load(label.c_str()); +} + +Module *Loader::init() +{ + FactoryFuncPtr factory = find(loader_label); + if (!factory) { + con_warn << "module '" << loader_label << "' not found" << std::endl; + } + + Module *module = factory(); + module->set_label(loader_label); + return module; +} + +void Loader::clear() +{ + loader_registry.clear(); + loader_label.clear(); +} + +void Loader::list() +{ + std::string loaderlist; + for (Registry::iterator it = loader_registry.begin(); it != loader_registry.end(); it++) { + if (loaderlist.size()) + loaderlist += " "; + loaderlist += (*it).first; + + } + con_print << loaderlist << std::endl; + con_print << loader_registry.size() << " registered " << aux::plural("modules", loader_registry.size()) << std::endl; +} + + +} + + diff --git a/src/core/loader.h b/src/core/loader.h new file mode 100644 index 0000000..1fde764 --- /dev/null +++ b/src/core/loader.h @@ -0,0 +1,62 @@ +/* + core/loader.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_CORE_LOADER_H__ +#define __INCLUDED_CORE_LOADER_H__ + +#include + +#include "core/module.h" + +namespace core { + +/// module factory registry +/** The Loader contains a list of module factories and can load + * the desired module on request + */ +class Loader +{ +public: + /// function pointer type for a module factory + typedef Module * (* FactoryFuncPtr)(); + + /// find a registered mmodule factory + static FactoryFuncPtr find(const char *label); + + /// find a registered module factory + static FactoryFuncPtr find(const std::string &label); + + /// add a factory to the loader registry + static void add(const std::string & label, FactoryFuncPtr factory); + + /// assign the next module to init + static bool load(const char *label); + + /// assign the next module to init + static bool load(const std::string &label); + + static inline const std::string &label() { return loader_label; } + + /// initialize a game module + static Module *init(); + + /// list registered modules + static void list(); + + /// clear the loader registry + static void clear(); + +private: + typedef std::map Registry; + + static Registry loader_registry; + static std::string loader_label; +}; + +} + +#endif // __INCLUDED_CORE_LOADER_H__ + diff --git a/src/core/module.cc b/src/core/module.cc index eec250e..5dd07b5 100644 --- a/src/core/module.cc +++ b/src/core/module.cc @@ -11,117 +11,37 @@ namespace core { -/*-- static functions ----------------------------------------------*/ +Module* Module::module_instance = 0; -Module *Module::module_preload = 0; -Module *Module::module_active = 0; - -Module::Registry Module::module_registry; - -Module *Module::find(const std::string &label) -{ - Registry::iterator it = module_registry.find(label); - if (it == module_registry.end()) - return 0; - else - return (*it).second; -} - -Module *Module::find(const char *label) -{ - return(find(std::string(label))); -} - -Module *Module::add(Module *module) -{ - Module *m = find(module->label()); - if (m) { - con_warn << "module '" << module->label() << "' already registered!" << std::endl; - delete module; - return 0; - } - - module_registry[module->label()] = module; - - if (!module_preload) { - module_preload = module; - } - con_debug << " " << module->label() << " " << module->name() << std::endl; - - return module; -} - -Module *Module::load(const char *label) -{ - if (!label) - return 0; - - Module *module = find(label); - if (!module) { - con_warn << "Could not find module '" << label << "'" << std::endl; - return 0; - } - - con_print << " module " << module->label() << " " << module->name() << std::endl; - module_preload = module; - return module; -} - -void Module::clear() -{ - for (Registry::iterator it = module_registry.begin(); it != module_registry.end(); it++) { - Module *module = (*it).second; - con_print << " " << module->label() << " " << module->name() << std::endl; - } - - module_registry.clear(); - module_preload = 0; -} - -void Module::list() +Module::Module(const char *name, bool interactive) : + module_name(name) { - for (Registry::iterator it = module_registry.begin(); it != module_registry.end(); it++) { - Module *module = (*it).second; - con_print << " " << module->label() << " " << module->name() << std::endl; + module_running = true; + module_interactive = interactive; + if (module_instance) { + std::cerr << "multiple core::Module instances\n"; + abort(); + } else { + module_instance = this; } - con_print << module_registry.size() << " registered game " << aux::plural("modules", module_registry.size()) << std::endl; -} - -/*-- instance functions --------------------------------------------*/ - -Module::Module(const char *label, const char *name, bool interactive) : - module_label(label), module_name(name) -{ - module_running = false; - module_interactive = interactive; } Module::~Module() { module_running = false; module_name.clear(); + module_instance = 0; } -void Module::run() -{ - module_active = this; - module_running = true; - - init(); -} - -void Module::terminate() +void Module::set_label(const std::string &label) { - shutdown(); - module_running = false; - module_active = 0; + module_label.assign(label); } void Module::abort() { module_running = false; - module_active = 0; } } diff --git a/src/core/module.h b/src/core/module.h index 64b41bd..240488f 100644 --- a/src/core/module.h +++ b/src/core/module.h @@ -13,11 +13,11 @@ namespace core { -// a loadable game module +/// abstract base class for a game module class Module { public: - Module(const char *label, const char *name, bool interactive=true); + Module(const char *name, bool interactive=true); virtual ~Module(); /*----- inspectors ------------------------------------------------ */ @@ -38,12 +38,6 @@ public: /*----- mutators -------------------------------------------------- */ - /// run the game module - void run(); - - /// terminate a running game module - void terminate(); - /// run one timeframe virtual void frame(float seconds) = 0; @@ -53,61 +47,23 @@ public: /// is called when a player disconnects virtual void player_disconnect(Player *player) = 0; -/*----- static ---------------------------------------------------- */ - - typedef std::map Registry; - - /// find a registered game module - static Module *find(const char *label); - - /// find a registered game module - static Module *find(const std::string &label); - - /// register a game module - static Module *add(Module *module); - - /// load a registered game module - static Module *load(const char *label); - - /// list modules - static void list(); - - /// unload all modules - static void clear(); + /// set the module label + void set_label(const std::string &label); - /// currently active module - static inline Module *active() { return module_active; } - - /// currently loaded module - static inline Module *loaded() { return module_preload; } - - /// module registry - static inline Registry & registry() { return module_registry; } + static inline Module *instance() { return module_instance; } protected: - - /// initialize the game module - virtual void init() = 0; - - /// shutdown the game module - virtual void shutdown() = 0; - /// abort a running module void abort(); private: - bool module_interactive; bool module_running; std::string module_label; - std::string module_name; - - static Registry module_registry; + std::string module_name; - static Module *module_preload; - static Module *module_active; - + static Module* module_instance; }; } -- cgit v1.2.3