Refactor static_wml_actions as class wml_action.
It's a bit more C++-like, but more importantly puts related static variables in the same file (so this should cure the static initialization fiasco known as bug #21020).
This commit is contained in:
parent
b4b957128c
commit
cab1c823b8
8 changed files with 55 additions and 35 deletions
|
@ -85,6 +85,11 @@ static lg::log_domain log_config("config");
|
|||
namespace game_events
|
||||
{
|
||||
|
||||
// This must be defined before any WML actions are.
|
||||
// (So keep it at the rop of this file?)
|
||||
wml_action::map wml_action::registry_;
|
||||
|
||||
|
||||
namespace { // advance declarations
|
||||
std::string get_caption(const vconfig& cfg, unit_map::iterator speaker);
|
||||
std::string get_image(const vconfig& cfg, unit_map::iterator speaker);
|
||||
|
@ -592,6 +597,18 @@ void handle_wml_log_message(const config& cfg)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Using this constructor for a static object outside action_wml.cpp
|
||||
* will likely lead to a static initialization fiasco.
|
||||
* @param[in] tag The WML tag for this action.
|
||||
* @param[in] function The callback for this action.
|
||||
*/
|
||||
wml_action::wml_action(const std::string & tag, handler function)
|
||||
{
|
||||
registry_[tag] = function;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* WML_HANDLER_FUNCTION macro handles auto registration for wml handlers
|
||||
*
|
||||
|
@ -612,11 +629,8 @@ void handle_wml_log_message(const config& cfg)
|
|||
*
|
||||
* Generated code looks like this:
|
||||
* \code
|
||||
* void wml_action_foo(...);
|
||||
* struct wml_func_register_foo {
|
||||
* wml_func_register_foo() {
|
||||
* register_action("foo", &wml_func_foo);
|
||||
* } wml_func_register_foo;
|
||||
* void wml_func_foo(...);
|
||||
* static wml_action wml_action_foo("foo", &wml_func_foo);
|
||||
* void wml_func_foo(...)
|
||||
* {
|
||||
* // code for foo
|
||||
|
@ -625,12 +639,7 @@ void handle_wml_log_message(const config& cfg)
|
|||
*/
|
||||
#define WML_HANDLER_FUNCTION(pname, pei, pcfg) \
|
||||
static void wml_func_##pname(const queued_event &pei, const vconfig &pcfg); \
|
||||
struct wml_func_register_##pname \
|
||||
{ \
|
||||
wml_func_register_##pname() \
|
||||
{ register_action(#pname, &wml_func_##pname); } \
|
||||
}; \
|
||||
static wml_func_register_##pname wml_func_register_##pname##_aux; \
|
||||
static wml_action wml_action_##pname(#pname, &wml_func_##pname); \
|
||||
static void wml_func_##pname(const queued_event& pei, const vconfig& pcfg)
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
class config;
|
||||
struct map_location;
|
||||
class vconfig;
|
||||
|
||||
namespace t_translation {
|
||||
struct t_terrain;
|
||||
|
@ -37,8 +38,31 @@ namespace t_translation {
|
|||
|
||||
namespace game_events
|
||||
{
|
||||
struct queued_event;
|
||||
|
||||
|
||||
// Most of the functionality in the source file is accessed via callbacks,
|
||||
// registered with register_action().
|
||||
// accessed by iterating over wml_action.
|
||||
|
||||
class wml_action {
|
||||
public:
|
||||
typedef void (*handler)(const queued_event &, const vconfig &);
|
||||
typedef std::map<std::string, handler> map;
|
||||
|
||||
/// Using this constructor for a static object outside action_wml.cpp
|
||||
/// will likely lead to a static initialization fiasco.
|
||||
wml_action(const std::string & tag, handler function);
|
||||
|
||||
/// The first registered action.
|
||||
static map::const_iterator begin() { return registry_.begin(); }
|
||||
/// One past the last registered action.
|
||||
static map::const_iterator end() { return registry_.end(); }
|
||||
|
||||
private:
|
||||
/// Tracks the known action handlers.
|
||||
static map registry_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes a terrain location.
|
||||
|
|
|
@ -48,7 +48,6 @@ static lg::log_domain log_event_handler("event_handler");
|
|||
namespace game_events {
|
||||
|
||||
namespace { // Types
|
||||
typedef std::map<std::string, wml_handler_function> static_wml_action_map;
|
||||
typedef std::pair< std::string, config* > wmi_command_change;
|
||||
|
||||
class t_event_handlers {
|
||||
|
@ -215,7 +214,6 @@ namespace { // Types
|
|||
namespace { // Variables
|
||||
t_event_handlers event_handlers;
|
||||
/** Map of the default action handlers known of the engine. */
|
||||
static_wml_action_map static_wml_actions;
|
||||
std::set<std::string> unit_wml_ids;
|
||||
std::set<std::string> used_items;
|
||||
std::vector< wmi_command_change > wmi_command_changes;
|
||||
|
@ -294,12 +292,6 @@ void item_used(const std::string & id, bool used)
|
|||
used_items.erase(id);
|
||||
}
|
||||
|
||||
/** Registers a standard action handler. */
|
||||
void register_action(const std::string & tag, wml_handler_function handler)
|
||||
{
|
||||
static_wml_actions[tag] = handler;
|
||||
}
|
||||
|
||||
/** Removes a pending menu item command change. */
|
||||
void remove_wmi_change(const std::string & id)
|
||||
{
|
||||
|
@ -338,8 +330,10 @@ manager::manager(const config& cfg)
|
|||
resources::lua_kernel = new LuaKernel(cfg);
|
||||
running_ = true;
|
||||
|
||||
BOOST_FOREACH(static_wml_action_map::value_type &action, static_wml_actions) {
|
||||
resources::lua_kernel->set_wml_action(action.first, action.second);
|
||||
wml_action::map::const_iterator action_end = wml_action::end();
|
||||
wml_action::map::const_iterator action_cur = wml_action::begin();
|
||||
for ( ; action_cur != action_end; ++action_cur ) {
|
||||
resources::lua_kernel->set_wml_action(action_cur->first, action_cur->second);
|
||||
}
|
||||
|
||||
const std::string used = cfg["used_items"];
|
||||
|
|
|
@ -27,18 +27,12 @@
|
|||
#include "../config.hpp"
|
||||
#include "../variable.hpp"
|
||||
|
||||
class vconfig;
|
||||
|
||||
|
||||
namespace game_events
|
||||
{
|
||||
struct queued_event;
|
||||
|
||||
|
||||
typedef void (*wml_handler_function)(const queued_event &event_info,
|
||||
const vconfig &cfg);
|
||||
typedef void (*action_handler)(const queued_event &, const vconfig &);
|
||||
|
||||
class event_handler
|
||||
{
|
||||
public:
|
||||
|
@ -104,8 +98,6 @@ namespace game_events
|
|||
bool item_used(const std::string & id);
|
||||
/// Records if an item has been used.
|
||||
void item_used(const std::string & id, bool used);
|
||||
/// Registers a standard action handler.
|
||||
void register_action(const std::string & tag, wml_handler_function handler);
|
||||
/// Removes an event handler.
|
||||
void remove_event_handler(const std::string & id);
|
||||
/// Removes a pending menu item command change.
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "../global.hpp"
|
||||
#include "pump.hpp"
|
||||
#include "conditional_wml.hpp"
|
||||
#include "handlers.hpp"
|
||||
|
||||
#include "../game_config.hpp"
|
||||
#include "../game_display.hpp"
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include "attack_prediction.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "game_display.hpp"
|
||||
#include "game_events/action_wml.hpp"
|
||||
#include "game_events/conditional_wml.hpp"
|
||||
#include "game_events/pump.hpp"
|
||||
#include "game_preferences.hpp"
|
||||
|
@ -4454,7 +4453,7 @@ LuaKernel::~LuaKernel()
|
|||
*/
|
||||
static int cfun_wml_action(lua_State *L)
|
||||
{
|
||||
game_events::action_handler h = reinterpret_cast<game_events::action_handler>
|
||||
game_events::wml_action::handler h = reinterpret_cast<game_events::wml_action::handler>
|
||||
(lua_touserdata(L, lua_upvalueindex(1)));
|
||||
|
||||
vconfig vcfg = luaW_checkvconfig(L, 1);
|
||||
|
@ -4465,7 +4464,7 @@ static int cfun_wml_action(lua_State *L)
|
|||
/**
|
||||
* Registers a function for use as an action handler.
|
||||
*/
|
||||
void LuaKernel::set_wml_action(std::string const &cmd, game_events::action_handler h)
|
||||
void LuaKernel::set_wml_action(std::string const &cmd, game_events::wml_action::handler h)
|
||||
{
|
||||
lua_State *L = mState;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#ifndef SCRIPTING_LUA_HPP
|
||||
#define SCRIPTING_LUA_HPP
|
||||
|
||||
#include "game_events/handlers.hpp"
|
||||
#include "game_events/action_wml.hpp"
|
||||
|
||||
class unit;
|
||||
struct lua_State;
|
||||
|
@ -44,7 +44,7 @@ public:
|
|||
void save_game(config &);
|
||||
void load_game();
|
||||
bool run_event(game_events::queued_event const &);
|
||||
void set_wml_action(std::string const &, game_events::action_handler);
|
||||
void set_wml_action(std::string const &, game_events::wml_action::handler);
|
||||
bool run_wml_action(std::string const &, vconfig const &,
|
||||
game_events::queued_event const &);
|
||||
bool run_filter(char const *name, unit const &u);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "callable_objects.hpp"
|
||||
#include "formula.hpp"
|
||||
#include "game_display.hpp"
|
||||
#include "game_events/handlers.hpp"
|
||||
#include "game_preferences.hpp"
|
||||
#include "gamestatus.hpp"
|
||||
#include "gettext.hpp"
|
||||
|
|
Loading…
Add table
Reference in a new issue