mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-30 14:27:40 +00:00
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
@ -85,6 +85,11 @@ static lg::log_domain log_config("config");
|
|||||||
namespace game_events
|
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
|
namespace { // advance declarations
|
||||||
std::string get_caption(const vconfig& cfg, unit_map::iterator speaker);
|
std::string get_caption(const vconfig& cfg, unit_map::iterator speaker);
|
||||||
std::string get_image(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
|
* 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:
|
* Generated code looks like this:
|
||||||
* \code
|
* \code
|
||||||
* void wml_action_foo(...);
|
* void wml_func_foo(...);
|
||||||
* struct wml_func_register_foo {
|
* static wml_action wml_action_foo("foo", &wml_func_foo);
|
||||||
* wml_func_register_foo() {
|
|
||||||
* register_action("foo", &wml_func_foo);
|
|
||||||
* } wml_func_register_foo;
|
|
||||||
* void wml_func_foo(...)
|
* void wml_func_foo(...)
|
||||||
* {
|
* {
|
||||||
* // code for foo
|
* // code for foo
|
||||||
@ -625,12 +639,7 @@ void handle_wml_log_message(const config& cfg)
|
|||||||
*/
|
*/
|
||||||
#define WML_HANDLER_FUNCTION(pname, pei, pcfg) \
|
#define WML_HANDLER_FUNCTION(pname, pei, pcfg) \
|
||||||
static void wml_func_##pname(const queued_event &pei, const vconfig &pcfg); \
|
static void wml_func_##pname(const queued_event &pei, const vconfig &pcfg); \
|
||||||
struct wml_func_register_##pname \
|
static wml_action wml_action_##pname(#pname, &wml_func_##pname); \
|
||||||
{ \
|
|
||||||
wml_func_register_##pname() \
|
|
||||||
{ register_action(#pname, &wml_func_##pname); } \
|
|
||||||
}; \
|
|
||||||
static wml_func_register_##pname wml_func_register_##pname##_aux; \
|
|
||||||
static void wml_func_##pname(const queued_event& pei, const vconfig& pcfg)
|
static void wml_func_##pname(const queued_event& pei, const vconfig& pcfg)
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
class config;
|
class config;
|
||||||
struct map_location;
|
struct map_location;
|
||||||
|
class vconfig;
|
||||||
|
|
||||||
namespace t_translation {
|
namespace t_translation {
|
||||||
struct t_terrain;
|
struct t_terrain;
|
||||||
@ -37,8 +38,31 @@ namespace t_translation {
|
|||||||
|
|
||||||
namespace game_events
|
namespace game_events
|
||||||
{
|
{
|
||||||
|
struct queued_event;
|
||||||
|
|
||||||
|
|
||||||
// Most of the functionality in the source file is accessed via callbacks,
|
// 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.
|
* Changes a terrain location.
|
||||||
|
@ -48,7 +48,6 @@ static lg::log_domain log_event_handler("event_handler");
|
|||||||
namespace game_events {
|
namespace game_events {
|
||||||
|
|
||||||
namespace { // Types
|
namespace { // Types
|
||||||
typedef std::map<std::string, wml_handler_function> static_wml_action_map;
|
|
||||||
typedef std::pair< std::string, config* > wmi_command_change;
|
typedef std::pair< std::string, config* > wmi_command_change;
|
||||||
|
|
||||||
class t_event_handlers {
|
class t_event_handlers {
|
||||||
@ -215,7 +214,6 @@ namespace { // Types
|
|||||||
namespace { // Variables
|
namespace { // Variables
|
||||||
t_event_handlers event_handlers;
|
t_event_handlers event_handlers;
|
||||||
/** Map of the default action handlers known of the engine. */
|
/** 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> unit_wml_ids;
|
||||||
std::set<std::string> used_items;
|
std::set<std::string> used_items;
|
||||||
std::vector< wmi_command_change > wmi_command_changes;
|
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);
|
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. */
|
/** Removes a pending menu item command change. */
|
||||||
void remove_wmi_change(const std::string & id)
|
void remove_wmi_change(const std::string & id)
|
||||||
{
|
{
|
||||||
@ -338,8 +330,10 @@ manager::manager(const config& cfg)
|
|||||||
resources::lua_kernel = new LuaKernel(cfg);
|
resources::lua_kernel = new LuaKernel(cfg);
|
||||||
running_ = true;
|
running_ = true;
|
||||||
|
|
||||||
BOOST_FOREACH(static_wml_action_map::value_type &action, static_wml_actions) {
|
wml_action::map::const_iterator action_end = wml_action::end();
|
||||||
resources::lua_kernel->set_wml_action(action.first, action.second);
|
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"];
|
const std::string used = cfg["used_items"];
|
||||||
|
@ -27,18 +27,12 @@
|
|||||||
#include "../config.hpp"
|
#include "../config.hpp"
|
||||||
#include "../variable.hpp"
|
#include "../variable.hpp"
|
||||||
|
|
||||||
class vconfig;
|
|
||||||
|
|
||||||
|
|
||||||
namespace game_events
|
namespace game_events
|
||||||
{
|
{
|
||||||
struct queued_event;
|
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
|
class event_handler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -104,8 +98,6 @@ namespace game_events
|
|||||||
bool item_used(const std::string & id);
|
bool item_used(const std::string & id);
|
||||||
/// Records if an item has been used.
|
/// Records if an item has been used.
|
||||||
void item_used(const std::string & id, bool 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.
|
/// Removes an event handler.
|
||||||
void remove_event_handler(const std::string & id);
|
void remove_event_handler(const std::string & id);
|
||||||
/// Removes a pending menu item command change.
|
/// Removes a pending menu item command change.
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "../global.hpp"
|
#include "../global.hpp"
|
||||||
#include "pump.hpp"
|
#include "pump.hpp"
|
||||||
#include "conditional_wml.hpp"
|
#include "conditional_wml.hpp"
|
||||||
|
#include "handlers.hpp"
|
||||||
|
|
||||||
#include "../game_config.hpp"
|
#include "../game_config.hpp"
|
||||||
#include "../game_display.hpp"
|
#include "../game_display.hpp"
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
#include "attack_prediction.hpp"
|
#include "attack_prediction.hpp"
|
||||||
#include "filesystem.hpp"
|
#include "filesystem.hpp"
|
||||||
#include "game_display.hpp"
|
#include "game_display.hpp"
|
||||||
#include "game_events/action_wml.hpp"
|
|
||||||
#include "game_events/conditional_wml.hpp"
|
#include "game_events/conditional_wml.hpp"
|
||||||
#include "game_events/pump.hpp"
|
#include "game_events/pump.hpp"
|
||||||
#include "game_preferences.hpp"
|
#include "game_preferences.hpp"
|
||||||
@ -4454,7 +4453,7 @@ LuaKernel::~LuaKernel()
|
|||||||
*/
|
*/
|
||||||
static int cfun_wml_action(lua_State *L)
|
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)));
|
(lua_touserdata(L, lua_upvalueindex(1)));
|
||||||
|
|
||||||
vconfig vcfg = luaW_checkvconfig(L, 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.
|
* 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;
|
lua_State *L = mState;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#ifndef SCRIPTING_LUA_HPP
|
#ifndef SCRIPTING_LUA_HPP
|
||||||
#define SCRIPTING_LUA_HPP
|
#define SCRIPTING_LUA_HPP
|
||||||
|
|
||||||
#include "game_events/handlers.hpp"
|
#include "game_events/action_wml.hpp"
|
||||||
|
|
||||||
class unit;
|
class unit;
|
||||||
struct lua_State;
|
struct lua_State;
|
||||||
@ -44,7 +44,7 @@ public:
|
|||||||
void save_game(config &);
|
void save_game(config &);
|
||||||
void load_game();
|
void load_game();
|
||||||
bool run_event(game_events::queued_event const &);
|
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 &,
|
bool run_wml_action(std::string const &, vconfig const &,
|
||||||
game_events::queued_event const &);
|
game_events::queued_event const &);
|
||||||
bool run_filter(char const *name, unit const &u);
|
bool run_filter(char const *name, unit const &u);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "callable_objects.hpp"
|
#include "callable_objects.hpp"
|
||||||
#include "formula.hpp"
|
#include "formula.hpp"
|
||||||
#include "game_display.hpp"
|
#include "game_display.hpp"
|
||||||
|
#include "game_events/handlers.hpp"
|
||||||
#include "game_preferences.hpp"
|
#include "game_preferences.hpp"
|
||||||
#include "gamestatus.hpp"
|
#include "gamestatus.hpp"
|
||||||
#include "gettext.hpp"
|
#include "gettext.hpp"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user