From 918adb652a3a24646e10f7e25f03e26176cfa2db Mon Sep 17 00:00:00 2001 From: Maurice Heumann Date: Tue, 11 May 2021 13:22:46 +0200 Subject: [PATCH] Support endon for scripts --- src/client/game/scripting/lua/context.cpp | 1 + .../game/scripting/lua/event_handler.cpp | 51 ++++++++++++++++++- .../game/scripting/lua/event_handler.hpp | 4 ++ src/client/game/scripting/lua/scheduler.cpp | 49 ++++++++++++++++++ src/client/game/scripting/lua/scheduler.hpp | 4 ++ 5 files changed, 107 insertions(+), 2 deletions(-) diff --git a/src/client/game/scripting/lua/context.cpp b/src/client/game/scripting/lua/context.cpp index 3f0cfc1..3c61e4d 100644 --- a/src/client/game/scripting/lua/context.cpp +++ b/src/client/game/scripting/lua/context.cpp @@ -328,6 +328,7 @@ namespace scripting::lua void context::notify(const event& e) { + this->scheduler_.dispatch(e); this->event_handler_.dispatch(e); } diff --git a/src/client/game/scripting/lua/event_handler.cpp b/src/client/game/scripting/lua/event_handler.cpp index 3c83259..7121ea6 100644 --- a/src/client/game/scripting/lua/event_handler.cpp +++ b/src/client/game/scripting/lua/event_handler.cpp @@ -14,6 +14,11 @@ namespace scripting::lua { this->remove(handle); }; + + event_listener_handle_type["endon"] = [this](const event_listener_handle& handle, const entity& entity, const std::string& event) + { + this->add_endon_condition(handle, entity, event); + }; } void event_handler::dispatch(const event& event) @@ -24,6 +29,7 @@ namespace scripting::lua callbacks_.access([&](task_list& tasks) { this->merge_callbacks(); + this->handle_endon_conditions(event); for (auto i = tasks.begin(); i != tasks.end();) { @@ -70,6 +76,27 @@ namespace scripting::lua return {id}; } + void event_handler::add_endon_condition(const event_listener_handle& handle, const entity& entity, + const std::string& event) + { + auto merger = [&](task_list& tasks) + { + for(auto& task : tasks) + { + if(task.id == handle.id) + { + task.endon_conditions.emplace_back(entity, event); + } + } + }; + + callbacks_.access([&](task_list& tasks) + { + merger(tasks); + new_callbacks_.access(merger); + }); + } + void event_handler::clear() { callbacks_.access([&](task_list& tasks) @@ -106,13 +133,33 @@ namespace scripting::lua { new_callbacks_.access([&](task_list& new_tasks) { - tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), - std::move_iterator(new_tasks.end())); + tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), + std::move_iterator(new_tasks.end())); new_tasks = {}; }); }); } + void event_handler::handle_endon_conditions(const event& event) + { + auto deleter = [&](task_list& tasks) + { + for(auto& task : tasks) + { + for(auto& condition : task.endon_conditions) + { + if(condition.first == event.entity && condition.second == event.name) + { + task.is_deleted = true; + break; + } + } + } + }; + + callbacks_.access(deleter); + } + event_arguments event_handler::build_arguments(const event& event) const { event_arguments arguments; diff --git a/src/client/game/scripting/lua/event_handler.hpp b/src/client/game/scripting/lua/event_handler.hpp index 273ec95..fc95b70 100644 --- a/src/client/game/scripting/lua/event_handler.hpp +++ b/src/client/game/scripting/lua/event_handler.hpp @@ -19,6 +19,7 @@ namespace scripting::lua event_callback callback = {}; bool is_volatile = false; bool is_deleted = false; + std::vector> endon_conditions{}; }; class event_handler final @@ -48,6 +49,9 @@ namespace scripting::lua void remove(const event_listener_handle& handle); void merge_callbacks(); + void handle_endon_conditions(const event& event); + + void add_endon_condition(const event_listener_handle& handle, const entity& entity, const std::string& event); event_arguments build_arguments(const event& event) const; }; diff --git a/src/client/game/scripting/lua/scheduler.cpp b/src/client/game/scripting/lua/scheduler.cpp index 32d3ae1..1afb7df 100644 --- a/src/client/game/scripting/lua/scheduler.cpp +++ b/src/client/game/scripting/lua/scheduler.cpp @@ -12,6 +12,35 @@ namespace scripting::lua { this->remove(handle); }; + + task_handle_type["endon"] = [this](const task_handle& handle, const entity& entity, const std::string& event) + { + this->add_endon_condition(handle, entity, event); + }; + } + + void scheduler::dispatch(const event& event) + { + auto deleter = [&](task_list& tasks) + { + for(auto& task : tasks) + { + for(auto& condition : task.endon_conditions) + { + if(condition.first == event.entity && condition.second == event.name) + { + task.is_deleted = true; + break; + } + } + } + }; + + callbacks_.access([&](task_list& tasks) + { + deleter(tasks); + new_callbacks_.access(deleter); + }); } void scheduler::run_frame() @@ -89,6 +118,26 @@ namespace scripting::lua return {id}; } + void scheduler::add_endon_condition(const task_handle& handle, const entity& entity, const std::string& event) + { + auto merger = [&](task_list& tasks) + { + for(auto& task : tasks) + { + if(task.id == handle.id) + { + task.endon_conditions.emplace_back(entity, event); + } + } + }; + + callbacks_.access([&](task_list& tasks) + { + merger(tasks); + new_callbacks_.access(merger); + }); + } + void scheduler::remove(const task_handle& handle) { auto mask_as_deleted = [&](task_list& tasks) diff --git a/src/client/game/scripting/lua/scheduler.hpp b/src/client/game/scripting/lua/scheduler.hpp index a939d65..17c9079 100644 --- a/src/client/game/scripting/lua/scheduler.hpp +++ b/src/client/game/scripting/lua/scheduler.hpp @@ -19,6 +19,7 @@ namespace scripting::lua std::chrono::milliseconds delay{}; bool is_volatile = false; bool is_deleted = false; + std::vector> endon_conditions{}; }; class scheduler final @@ -32,6 +33,7 @@ namespace scripting::lua scheduler(const scheduler&) = delete; scheduler& operator=(const scheduler&) = delete; + void dispatch(const event& event); void run_frame(); void clear(); @@ -44,6 +46,8 @@ namespace scripting::lua utils::concurrency::container callbacks_; std::atomic_int64_t current_task_id_ = 0; + void add_endon_condition(const task_handle& handle, const entity& entity, const std::string& event); + void remove(const task_handle& handle); void merge_callbacks(); };