Game Events/Manager: added function to encapsulate iteration-by-id interface

This allows manager::iteration to be made private in order to restrict access to handler iterators
within the manager class and not outside it.
This commit is contained in:
Charles Dang 2017-05-20 21:10:29 +11:00
parent 1005843c52
commit be665e29f1
4 changed files with 26 additions and 19 deletions

View file

@ -204,6 +204,16 @@ void manager::write_events(config& cfg) const
wml_menu_items_.to_config(cfg);
}
void manager::execute_on_events(const std::string& event_id, manager::event_func_t func)
{
iteration iter(event_id, *this);
while(handler_ptr hand = *iter) {
func(*this, hand);
++iter;
}
}
game_events::wml_event_pump& manager::pump()
{
return *pump_;

View file

@ -41,7 +41,7 @@ namespace game_events {
/// If a second manager object is created before destroying the previous
/// one, the game will crash with an assertion failure.
class manager {
public:
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,
@ -92,7 +92,6 @@ namespace game_events {
game_data * gamedata_;
};
private:
// Performs an assertion check to ensure these members are not null.
friend void event_handler::disable();
@ -121,6 +120,9 @@ namespace game_events {
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()

View file

@ -329,14 +329,13 @@ void wml_menu_item::update_command(const config& new_command)
// If there is an old command, remove it from the event handlers.
if(!command_.empty()) {
assert(resources::game_events);
manager::iteration iter(event_name_, *resources::game_events);
while(handler_ptr hand = *iter) {
if(hand->is_menu_item()) {
resources::game_events->execute_on_events(event_name_, [=](game_events::manager& man, handler_ptr ptr) {
if(ptr->is_menu_item()) {
LOG_NG << "Removing command for " << event_name_ << ".\n";
resources::game_events->remove_event_handler(command_["id"].str());
man.remove_event_handler(command_["id"].str());
}
++iter;
}
});
}
// Update our stored command.

View file

@ -552,20 +552,16 @@ bool wml_event_pump::operator()()
if ( event_id.empty() ) {
// Initialize an iteration over event handlers matching this event.
manager::iteration handler_iter(event_name, *impl_->my_manager);
// While there is a potential handler for this event name.
while ( handler_ptr cur_handler = *handler_iter ) {
// Handle events of this name.
impl_->my_manager->execute_on_events(event_name, [=](game_events::manager&, handler_ptr ptr) {
DBG_EH << "processing event " << event_name << " with id="<<
cur_handler->get_config()["id"] << "\n";
ptr->get_config()["id"] << "\n";
// Let this handler process our event.
process_event(cur_handler, ev);
// NOTE: cur_handler may be null at this point!
++handler_iter;
}
process_event(ptr, ev);
// NOTE: ptr may be null at this point!
});
}
else {