Game Events: more formatting and doc cleanup
This commit is contained in:
parent
d41396ac32
commit
c04e289c73
4 changed files with 343 additions and 260 deletions
|
@ -35,7 +35,6 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
static lg::log_domain log_engine("engine");
|
||||
#define DBG_NG LOG_STREAM(debug, log_engine)
|
||||
#define LOG_NG LOG_STREAM(info, log_engine)
|
||||
|
@ -44,10 +43,9 @@ static lg::log_domain log_engine("engine");
|
|||
static lg::log_domain log_event_handler("event_handler");
|
||||
#define DBG_EH LOG_STREAM(debug, log_event_handler)
|
||||
|
||||
|
||||
// This file is in the game_events namespace.
|
||||
namespace game_events {
|
||||
|
||||
namespace game_events
|
||||
{
|
||||
/* ** handler_list::iterator ** */
|
||||
|
||||
/**
|
||||
|
@ -57,29 +55,30 @@ namespace game_events {
|
|||
handler_ptr handler_list::iterator::operator*()
|
||||
{
|
||||
// Check for an available handler.
|
||||
while ( iter_.derefable() ) {
|
||||
while(iter_.derefable()) {
|
||||
// Handler still accessible?
|
||||
if ( handler_ptr lock = iter_->lock() )
|
||||
if(handler_ptr lock = iter_->lock()) {
|
||||
return lock;
|
||||
else
|
||||
} else {
|
||||
// Remove the now-defunct entry.
|
||||
iter_ = list_t::erase(iter_);
|
||||
}
|
||||
}
|
||||
|
||||
// End of the list.
|
||||
return handler_ptr();
|
||||
}
|
||||
|
||||
|
||||
/* ** event_handler ** */
|
||||
|
||||
event_handler::event_handler(const config &cfg, bool imi, handler_vec::size_type index, manager & man)
|
||||
event_handler::event_handler(const config& cfg, bool imi, handler_vec::size_type index, manager& man)
|
||||
: first_time_only_(cfg["first_time_only"].to_bool(true))
|
||||
, is_menu_item_(imi)
|
||||
, index_(index)
|
||||
, man_(&man)
|
||||
, cfg_(cfg)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables *this, removing it from the game.
|
||||
|
@ -93,8 +92,10 @@ void event_handler::disable()
|
|||
{
|
||||
assert(man_);
|
||||
assert(man_->event_handlers_);
|
||||
|
||||
// Handlers must have an index after they're created.
|
||||
assert ( index_ < man_->event_handlers_->size() );
|
||||
assert(index_ < man_->event_handlers_->size());
|
||||
|
||||
// Disable this handler.
|
||||
(*man_->event_handlers_)[index_].reset();
|
||||
}
|
||||
|
@ -108,20 +109,21 @@ void event_handler::disable()
|
|||
* @param[in,out] handler_p The caller's smart pointer to *this. It may be
|
||||
* reset() during processing.
|
||||
*/
|
||||
void event_handler::handle_event(const queued_event& event_info, handler_ptr& handler_p, game_lua_kernel & lk)
|
||||
void event_handler::handle_event(const queued_event& event_info, handler_ptr& handler_p, game_lua_kernel& lk)
|
||||
{
|
||||
// We will need our config after possibly self-destructing. Make a copy now.
|
||||
// TODO: instead of copying possibly huge config objects we should use shared things and only increase a refcount here.
|
||||
// TODO: instead of copying possibly huge config objects we should use shared things and only increase a refcount
|
||||
// here.
|
||||
vconfig vcfg(cfg_, true);
|
||||
|
||||
if (is_menu_item_) {
|
||||
if(is_menu_item_) {
|
||||
DBG_NG << cfg_["name"] << " will now invoke the following command(s):\n" << cfg_;
|
||||
}
|
||||
|
||||
if (first_time_only_)
|
||||
{
|
||||
if(first_time_only_) {
|
||||
// Disable this handler.
|
||||
disable();
|
||||
|
||||
// Also remove our caller's hold on us.
|
||||
handler_p.reset();
|
||||
}
|
||||
|
@ -131,20 +133,23 @@ void event_handler::handle_event(const queued_event& event_info, handler_ptr& ha
|
|||
sound::commit_music_changes();
|
||||
}
|
||||
|
||||
bool event_handler::matches_name(const std::string &name, const game_data * gd) const
|
||||
bool event_handler::matches_name(const std::string& name, const game_data* gd) const
|
||||
{
|
||||
const std::string my_names = !gd ? cfg_["name"].str() :
|
||||
utils::interpolate_variables_into_string(cfg_["name"], *gd);
|
||||
std::string::const_iterator itor,
|
||||
it_begin = my_names.begin(),
|
||||
it_end = my_names.end(),
|
||||
match_it = name.begin(),
|
||||
match_begin = name.begin(),
|
||||
match_end = name.end();
|
||||
const std::string my_names = !gd
|
||||
? cfg_["name"].str()
|
||||
: utils::interpolate_variables_into_string(cfg_["name"], *gd);
|
||||
|
||||
std::string::const_iterator
|
||||
itor, it_begin = my_names.begin(),
|
||||
it_end = my_names.end(),
|
||||
match_it = name.begin(),
|
||||
match_begin = name.begin(),
|
||||
match_end = name.end();
|
||||
|
||||
int skip_count = 0;
|
||||
for(itor = it_begin; itor != it_end; ++itor) {
|
||||
bool do_eat = false,
|
||||
do_skip = false;
|
||||
bool do_eat = false, do_skip = false;
|
||||
|
||||
switch(*itor) {
|
||||
case ',':
|
||||
if(itor - it_begin - skip_count == match_it - match_begin && match_it == match_end) {
|
||||
|
@ -171,6 +176,7 @@ bool event_handler::matches_name(const std::string &name, const game_data * gd)
|
|||
do_eat = (match_it != match_end && *match_it == *itor);
|
||||
break;
|
||||
}
|
||||
|
||||
if(do_eat) {
|
||||
++match_it;
|
||||
} else if(do_skip) {
|
||||
|
@ -185,11 +191,12 @@ bool event_handler::matches_name(const std::string &name, const game_data * gd)
|
|||
skip_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(itor - it_begin - skip_count == match_it - match_begin && match_it == match_end) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // end namespace game_events
|
||||
|
||||
|
|
|
@ -35,110 +35,149 @@ class game_lua_kernel;
|
|||
|
||||
namespace game_events
|
||||
{
|
||||
struct queued_event;
|
||||
class event_handler; // Defined a few lines down.
|
||||
class manager;
|
||||
struct queued_event;
|
||||
class event_handler; // Defined a few lines down.
|
||||
class manager;
|
||||
|
||||
/// Shared pointer to handler objects.
|
||||
typedef std::shared_ptr<event_handler> handler_ptr;
|
||||
/// Storage of event handlers.
|
||||
typedef std::vector<handler_ptr> handler_vec;
|
||||
/// Shared pointer to handler objects.
|
||||
typedef std::shared_ptr<event_handler> handler_ptr;
|
||||
|
||||
/// Storage of event handlers.
|
||||
typedef std::vector<handler_ptr> handler_vec;
|
||||
|
||||
class event_handler
|
||||
class event_handler
|
||||
{
|
||||
public:
|
||||
event_handler(const config& cfg, bool is_menu_item, handler_vec::size_type index, manager&);
|
||||
|
||||
/** The index of *this should only be of interest when controlling iterations. */
|
||||
handler_vec::size_type index() const
|
||||
{
|
||||
public:
|
||||
event_handler(const config &cfg, bool is_menu_item,
|
||||
handler_vec::size_type index, manager &);
|
||||
return index_;
|
||||
}
|
||||
|
||||
/// The index of *this should only be of interest when controlling iterations.
|
||||
handler_vec::size_type index() const { return index_; }
|
||||
bool matches_name(const std::string& name, const game_data* data) const;
|
||||
|
||||
bool matches_name(const std::string& name, const game_data * data) const;
|
||||
|
||||
bool is_menu_item() const { return is_menu_item_; }
|
||||
|
||||
/// Disables *this, removing it from the game.
|
||||
void disable();
|
||||
void handle_event(const queued_event& event_info, handler_ptr& handler_p, game_lua_kernel &);
|
||||
|
||||
const config &get_config() const { return cfg_; }
|
||||
|
||||
private:
|
||||
bool first_time_only_;
|
||||
bool is_menu_item_;
|
||||
handler_vec::size_type index_;
|
||||
manager * man_;
|
||||
config cfg_;
|
||||
};
|
||||
|
||||
|
||||
/// This is a wrapper for a list of weak pointers to handlers. It allows forward
|
||||
/// iterations of the list, with each element returned as a shared pointer.
|
||||
/// (Weak pointers that fail to lock are silently removed from the list.) These
|
||||
/// iterations can be used recursively, even when the innermost iteration might
|
||||
/// erase arbitrary elements from the list.
|
||||
///
|
||||
/// The interface is not the standard list interface because that would be
|
||||
/// inconvenient. The functionality implemented is that required by Wesnoth.
|
||||
class handler_list
|
||||
bool is_menu_item() const
|
||||
{
|
||||
/// The weak pointers that are used internally.
|
||||
typedef std::weak_ptr<event_handler> internal_ptr;
|
||||
/// The underlying list.
|
||||
typedef utils::smart_list<internal_ptr> list_t;
|
||||
return is_menu_item_;
|
||||
}
|
||||
|
||||
public: // types
|
||||
/// Handler list iterators are rather limited. They can be constructed
|
||||
/// from a reference iterator (not default constructed), incremented,
|
||||
/// and dereferenced. Consecutive dereferences are not guaranteed to
|
||||
/// return the same element (if the list mutates between them, the next
|
||||
/// element might be returned). An increment guarantees that the next
|
||||
/// dereference will differ from the previous (unless at the end of the
|
||||
/// list). The end of the list is indicated by dereferencing to a null
|
||||
/// pointer.
|
||||
class iterator
|
||||
/** Disables *this, removing it from the game. */
|
||||
void disable();
|
||||
void handle_event(const queued_event& event_info, handler_ptr& handler_p, game_lua_kernel&);
|
||||
|
||||
const config& get_config() const
|
||||
{
|
||||
return cfg_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool first_time_only_;
|
||||
bool is_menu_item_;
|
||||
handler_vec::size_type index_;
|
||||
manager* man_;
|
||||
config cfg_;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a wrapper for a list of weak pointers to handlers. It allows forward
|
||||
* iterations of the list, with each element returned as a shared pointer.
|
||||
* (Weak pointers that fail to lock are silently removed from the list.) These
|
||||
* iterations can be used recursively, even when the innermost iteration might
|
||||
* erase arbitrary elements from the list.
|
||||
*
|
||||
* The interface is not the standard list interface because that would be
|
||||
* inconvenient. The functionality implemented is that required by Wesnoth.
|
||||
*/
|
||||
class handler_list
|
||||
{
|
||||
/// The weak pointers that are used internally.
|
||||
typedef std::weak_ptr<event_handler> internal_ptr;
|
||||
|
||||
/// The underlying list.
|
||||
typedef utils::smart_list<internal_ptr> list_t;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Handler list iterators are rather limited. They can be constructed
|
||||
* from a reference iterator (not default constructed), incremented,
|
||||
* and dereferenced. Consecutive dereferences are not guaranteed to
|
||||
* return the same element (if the list mutates between them, the next
|
||||
* element might be returned). An increment guarantees that the next
|
||||
* dereference will differ from the previous (unless at the end of the
|
||||
* list). The end of the list is indicated by dereferencing to a null
|
||||
* pointer.
|
||||
*/
|
||||
class iterator
|
||||
{
|
||||
/// The current element.
|
||||
list_t::iterator iter_;
|
||||
|
||||
public:
|
||||
/// Initialized constructor (to be called by handler_list).
|
||||
explicit iterator(const list_t::iterator& base_iter)
|
||||
: iter_(base_iter)
|
||||
{
|
||||
/// The current element.
|
||||
list_t::iterator iter_;
|
||||
}
|
||||
|
||||
public:
|
||||
/// Initialized constructor (to be called by handler_list).
|
||||
explicit iterator(const list_t::iterator & base_iter) :
|
||||
iter_(base_iter)
|
||||
{}
|
||||
|
||||
/// Increment.
|
||||
iterator & operator++() { ++iter_; return *this; }
|
||||
/// Dereference.
|
||||
handler_ptr operator*();
|
||||
};
|
||||
friend class iterator;
|
||||
typedef iterator const_iterator;
|
||||
|
||||
public: // functions
|
||||
/// Default constructor.
|
||||
/// Note: This explicit definition is required (by the more pedantic
|
||||
/// compilers) in order to declare a default-constructed, static,
|
||||
/// and const variable in event_handlers::get(), in handlers.cpp.
|
||||
handler_list() : data_() {}
|
||||
|
||||
const_iterator begin() const { return iterator(const_cast<list_t &>(data_).begin()); }
|
||||
// The above const_cast is so the iterator can remove obsolete entries.
|
||||
const_iterator end() const { return iterator(const_cast<list_t &>(data_).end()); }
|
||||
|
||||
// push_front() is probably unneeded, but I'll leave the code here, just in case.
|
||||
// (These lists must be maintained in index order, which means pushing to the back.)
|
||||
void push_front(const handler_ptr & p) { data_.push_front(internal_ptr(p)); }
|
||||
void push_back(const handler_ptr & p) { data_.push_back(internal_ptr(p)); }
|
||||
|
||||
void clear() { data_.clear(); }
|
||||
|
||||
private:
|
||||
/// No implementation of operator=() since smart_list does not support it.
|
||||
handler_list & operator=(const handler_list &);
|
||||
|
||||
/// The actual list.
|
||||
list_t data_;
|
||||
/// Increment.
|
||||
iterator& operator++()
|
||||
{
|
||||
++iter_;
|
||||
return *this;
|
||||
}
|
||||
/// Dereference.
|
||||
handler_ptr operator*();
|
||||
};
|
||||
friend class iterator;
|
||||
typedef iterator const_iterator;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default constructor.
|
||||
* Note: This explicit definition is required (by the more pedantic
|
||||
* compilers) in order to declare a default-constructed, static,
|
||||
* and const variable in event_handlers::get(), in handlers.cpp.
|
||||
*/
|
||||
handler_list()
|
||||
: data_()
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return iterator(const_cast<list_t&>(data_).begin());
|
||||
}
|
||||
|
||||
// The above const_cast is so the iterator can remove obsolete entries.
|
||||
const_iterator end() const
|
||||
{
|
||||
return iterator(const_cast<list_t&>(data_).end());
|
||||
}
|
||||
|
||||
// push_front() is probably unneeded, but I'll leave the code here, just in case.
|
||||
// (These lists must be maintained in index order, which means pushing to the back.)
|
||||
void push_front(const handler_ptr& p)
|
||||
{
|
||||
data_.push_front(internal_ptr(p));
|
||||
}
|
||||
|
||||
void push_back(const handler_ptr& p)
|
||||
{
|
||||
data_.push_back(internal_ptr(p));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
data_.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
/// No implementation of operator=() since smart_list does not support it.
|
||||
handler_list& operator=(const handler_list&);
|
||||
|
||||
/// The actual list.
|
||||
list_t data_;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -27,108 +27,116 @@ class game_display;
|
|||
class game_data;
|
||||
class unit_map;
|
||||
|
||||
namespace game_events {
|
||||
|
||||
class wml_event_pump;
|
||||
|
||||
class event_handlers;
|
||||
|
||||
/// The game event manager loads the scenario configuration object,
|
||||
/// and ensures that events are handled according to the
|
||||
/// scenario configuration for its lifetime.
|
||||
///
|
||||
/// Thus, a manager object should be created when a scenario is played,
|
||||
/// and destroyed at the end of the scenario.
|
||||
/// If a second manager object is created before destroying the previous
|
||||
/// one, the game will crash with an assertion failure.
|
||||
class manager {
|
||||
private:
|
||||
/// This class is similar to an input iterator through event handlers,
|
||||
/// except each instance knows its own end (determined when constructed).
|
||||
/// Subsequent dereferences are not guaranteed to return the same element,
|
||||
/// so it is important to assign a dereference to a variable if you want
|
||||
/// to use it more than once. On the other hand, a dereference will not
|
||||
/// return a null pointer until the end of the iteration is reached (and
|
||||
/// this is how to detect the end of the iteration).
|
||||
///
|
||||
/// For simplicity, this class is neither assignable nor equality
|
||||
/// comparable nor default constructable, and there is no postincrement.
|
||||
/// Typedefs are also skipped.
|
||||
class iteration
|
||||
{
|
||||
public:
|
||||
/// Event-specific constructor.
|
||||
explicit iteration(const std::string & event_name, manager &);
|
||||
|
||||
// Increment:
|
||||
iteration & operator++();
|
||||
// Dereference:
|
||||
handler_ptr operator*();
|
||||
|
||||
private: // functions
|
||||
/// Gets the index from a pointer, capped at end_.
|
||||
handler_vec::size_type ptr_index(const handler_ptr & ptr) const
|
||||
{ return !bool(ptr) ? end_ : std::min(ptr->index(), end_); }
|
||||
|
||||
private: // data
|
||||
/// The fixed-name event handlers for this iteration.
|
||||
const handler_list & main_list_;
|
||||
/// The varying-name event handlers for this iteration.
|
||||
const handler_list & var_list_;
|
||||
/// The event name for this iteration.
|
||||
const std::string event_name_;
|
||||
/// The end of this iteration. We intentionally exclude handlers
|
||||
/// added after *this is constructed.
|
||||
const handler_vec::size_type end_;
|
||||
|
||||
/// Set to true upon dereferencing.
|
||||
bool current_is_known_;
|
||||
/// true if the most recent dereference was taken from main_list_.
|
||||
bool main_is_current_;
|
||||
/// The current (or next) element from main_list_.
|
||||
handler_list::iterator main_it_;
|
||||
/// The current (or next) element from var_list_.
|
||||
handler_list::iterator var_it_;
|
||||
|
||||
game_data * gamedata_;
|
||||
};
|
||||
|
||||
// Performs an assertion check to ensure these members are not null.
|
||||
friend void event_handler::disable();
|
||||
|
||||
const std::unique_ptr<event_handlers> event_handlers_;
|
||||
std::set<std::string> unit_wml_ids_;
|
||||
|
||||
const std::unique_ptr<game_events::wml_event_pump> pump_;
|
||||
game_events::wmi_manager wml_menu_items_;
|
||||
namespace game_events
|
||||
{
|
||||
class wml_event_pump;
|
||||
class event_handlers;
|
||||
|
||||
/**
|
||||
* The game event manager loads the scenario configuration object,
|
||||
* and ensures that events are handled according to the
|
||||
* scenario configuration for its lifetime.
|
||||
*
|
||||
* Thus, a manager object should be created when a scenario is played,
|
||||
* and destroyed at the end of the scenario.
|
||||
* If a second manager object is created before destroying the previous
|
||||
* one, the game will crash with an assertion failure.
|
||||
*/
|
||||
class manager
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* This class is similar to an input iterator through event handlers,
|
||||
* except each instance knows its own end (determined when constructed).
|
||||
* Subsequent dereferences are not guaranteed to return the same element,
|
||||
* so it is important to assign a dereference to a variable if you want
|
||||
* to use it more than once. On the other hand, a dereference will not
|
||||
* return a null pointer until the end of the iteration is reached (and
|
||||
* this is how to detect the end of the iteration).
|
||||
*
|
||||
* For simplicity, this class is neither assignable nor equality
|
||||
* comparable nor default constructable, and there is no postincrement.
|
||||
* Typedefs are also skipped.
|
||||
*/
|
||||
class iteration
|
||||
{
|
||||
public:
|
||||
manager(const manager&) = delete;
|
||||
manager& operator=(const manager&) = delete;
|
||||
/// Event-specific constructor.
|
||||
explicit iteration(const std::string& event_name, manager&);
|
||||
|
||||
explicit manager();
|
||||
void read_scenario(const config& scenario_cfg);
|
||||
~manager();
|
||||
// Increment:
|
||||
iteration& operator++();
|
||||
// Dereference:
|
||||
handler_ptr operator*();
|
||||
|
||||
/// Create an event handler.
|
||||
void add_event_handler(const config & handler, bool is_menu_item=false);
|
||||
/// Removes an event handler.
|
||||
void remove_event_handler(const std::string & id);
|
||||
/// Gets an event handler by ID
|
||||
const handler_ptr get_event_handler_by_id(const std::string & id);
|
||||
|
||||
void add_events(const config::const_child_itors &cfgs,
|
||||
const std::string& type = std::string());
|
||||
void write_events(config& cfg) const;
|
||||
|
||||
using event_func_t = std::function<void(game_events::manager&, handler_ptr)>;
|
||||
void execute_on_events(const std::string& event_id, event_func_t func);
|
||||
|
||||
game_events::wml_event_pump & pump();
|
||||
|
||||
game_events::wmi_manager& wml_menu_items()
|
||||
private:
|
||||
/// Gets the index from a pointer, capped at end_.
|
||||
handler_vec::size_type ptr_index(const handler_ptr& ptr) const
|
||||
{
|
||||
return wml_menu_items_;
|
||||
return !bool(ptr) ? end_ : std::min(ptr->index(), end_);
|
||||
}
|
||||
|
||||
private:
|
||||
/// The fixed-name event handlers for this iteration.
|
||||
const handler_list& main_list_;
|
||||
/// The varying-name event handlers for this iteration.
|
||||
const handler_list& var_list_;
|
||||
/// The event name for this iteration.
|
||||
const std::string event_name_;
|
||||
/// The end of this iteration. We intentionally exclude handlers
|
||||
/// added after *this is constructed.
|
||||
const handler_vec::size_type end_;
|
||||
|
||||
/// Set to true upon dereferencing.
|
||||
bool current_is_known_;
|
||||
/// true if the most recent dereference was taken from main_list_.
|
||||
bool main_is_current_;
|
||||
/// The current (or next) element from main_list_.
|
||||
handler_list::iterator main_it_;
|
||||
/// The current (or next) element from var_list_.
|
||||
handler_list::iterator var_it_;
|
||||
|
||||
game_data* gamedata_;
|
||||
};
|
||||
|
||||
// Performs an assertion check to ensure these members are not null.
|
||||
friend void event_handler::disable();
|
||||
|
||||
const std::unique_ptr<event_handlers> event_handlers_;
|
||||
std::set<std::string> unit_wml_ids_;
|
||||
|
||||
const std::unique_ptr<game_events::wml_event_pump> pump_;
|
||||
game_events::wmi_manager wml_menu_items_;
|
||||
|
||||
public:
|
||||
manager(const manager&) = delete;
|
||||
manager& operator=(const manager&) = delete;
|
||||
|
||||
explicit manager();
|
||||
void read_scenario(const config& scenario_cfg);
|
||||
~manager();
|
||||
|
||||
/** Create an event handler. */
|
||||
void add_event_handler(const config& handler, bool is_menu_item = false);
|
||||
|
||||
/** Removes an event handler. */
|
||||
void remove_event_handler(const std::string& id);
|
||||
|
||||
/** Gets an event handler by ID */
|
||||
const handler_ptr get_event_handler_by_id(const std::string& id);
|
||||
|
||||
void add_events(const config::const_child_itors& cfgs, const std::string& type = std::string());
|
||||
|
||||
void write_events(config& cfg) const;
|
||||
|
||||
using event_func_t = std::function<void(game_events::manager&, handler_ptr)>;
|
||||
void execute_on_events(const std::string& event_id, event_func_t func);
|
||||
|
||||
game_events::wml_event_pump& pump();
|
||||
|
||||
game_events::wmi_manager& wml_menu_items()
|
||||
{
|
||||
return wml_menu_items_;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -19,54 +19,83 @@
|
|||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace game_events {
|
||||
namespace game_events
|
||||
{
|
||||
// event_handlers is essentially the implementation details of the manager
|
||||
class event_handlers
|
||||
{
|
||||
private:
|
||||
typedef std::unordered_map<std::string, handler_list> map_t;
|
||||
typedef std::unordered_map<std::string, std::weak_ptr<event_handler>> id_map_t;
|
||||
|
||||
//event_handlers is essentially the implementation details of the manager
|
||||
class event_handlers {
|
||||
private:
|
||||
typedef std::unordered_map<std::string, handler_list> map_t;
|
||||
typedef std::unordered_map<std::string, std::weak_ptr<event_handler> > id_map_t;
|
||||
/**
|
||||
* Active event handlers. Will not have elements removed unless the event_handlers is clear()ed.
|
||||
* This is the only container that actually 'owns' any events in the form of shared_ptrs. The other
|
||||
* three storage methods own weak_ptrs.
|
||||
*/
|
||||
handler_vec active_;
|
||||
|
||||
handler_vec active_; /// Active event handlers. Will not have elements removed unless the event_handlers is clear()ed.
|
||||
map_t by_name_; /// Active event handlers with fixed event names, organized by event name.
|
||||
handler_list dynamic_; /// Active event handlers with variables in their event names.
|
||||
id_map_t id_map_; /// Allows quick locating of handlers by id.
|
||||
/** Active event handlers with fixed event names, organized by event name. */
|
||||
map_t by_name_;
|
||||
|
||||
void log_handlers();
|
||||
/// Utility to standardize the event names used in by_name_.
|
||||
static std::string standardize_name(const std::string & name);
|
||||
/** Active event handlers with variables in their event names. */
|
||||
handler_list dynamic_;
|
||||
|
||||
public:
|
||||
// TODO: remove
|
||||
typedef handler_vec::size_type size_type;
|
||||
/** Allows quick locating of handlers by id. */
|
||||
id_map_t id_map_;
|
||||
|
||||
event_handlers()
|
||||
: active_()
|
||||
, by_name_()
|
||||
, dynamic_()
|
||||
, id_map_()
|
||||
{}
|
||||
void log_handlers();
|
||||
|
||||
/// Read-only access to the handlers with varying event names.
|
||||
const handler_list & get_dynamic() const { return dynamic_; }
|
||||
/** Utility to standardize the event names used in by_name_. */
|
||||
static std::string standardize_name(const std::string& name);
|
||||
|
||||
/// Read-only access to the active event handlers.
|
||||
const handler_vec& get_active() const { return active_; }
|
||||
public:
|
||||
// TODO: remove
|
||||
typedef handler_vec::size_type size_type;
|
||||
|
||||
/// Read-only access to the handlers with fixed event names, by event name.
|
||||
const handler_list & get(const std::string & name) const;
|
||||
event_handlers()
|
||||
: active_()
|
||||
, by_name_()
|
||||
, dynamic_()
|
||||
, id_map_()
|
||||
{
|
||||
}
|
||||
|
||||
/// Adds an event handler.
|
||||
void add_event_handler(const config & cfg, manager & man, bool is_menu_item=false);
|
||||
/// Removes an event handler, identified by its ID.
|
||||
void remove_event_handler(const std::string& id);
|
||||
/// Gets an event handler, identified by its ID.
|
||||
const handler_ptr get_event_handler_by_id(const std::string & id);
|
||||
/** Read-only access to the handlers with varying event names. */
|
||||
const handler_list& get_dynamic() const
|
||||
{
|
||||
return dynamic_;
|
||||
}
|
||||
|
||||
/// The number of active event handlers.
|
||||
size_type size() const { return active_.size(); }
|
||||
/// Access to active event handlers by index.
|
||||
handler_ptr & operator[](size_type index) { return active_[index]; }
|
||||
};//event_handlers
|
||||
/** Read-only access to the active event handlers. Essentially gives all events. */
|
||||
const handler_vec& get_active() const
|
||||
{
|
||||
return active_;
|
||||
}
|
||||
|
||||
} //end namespace game_events
|
||||
/** Read-only access to the handlers with fixed event names, by event name. */
|
||||
const handler_list& get(const std::string& name) const;
|
||||
|
||||
/** Adds an event handler. */
|
||||
void add_event_handler(const config& cfg, manager& man, bool is_menu_item = false);
|
||||
|
||||
/** Removes an event handler, identified by its ID. */
|
||||
void remove_event_handler(const std::string& id);
|
||||
|
||||
/** Gets an event handler, identified by its ID. */
|
||||
const handler_ptr get_event_handler_by_id(const std::string& id);
|
||||
|
||||
/** The number of active event handlers. */
|
||||
size_type size() const
|
||||
{
|
||||
return active_.size();
|
||||
}
|
||||
|
||||
/** Access to active event handlers by index. */
|
||||
handler_ptr& operator[](size_type index)
|
||||
{
|
||||
return active_[index];
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace game_events
|
||||
|
|
Loading…
Add table
Reference in a new issue