add endon

This commit is contained in:
m 2021-08-27 23:40:09 -05:00
parent e07590a6e5
commit 86a1db1a76
6 changed files with 127 additions and 14 deletions

View File

@ -417,6 +417,7 @@ namespace scripting::lua
void context::notify(const event& e)
{
this->scheduler_.dispatch(e);
this->event_handler_.dispatch(e);
}

View File

@ -2,6 +2,9 @@
#include "../event.hpp"
#pragma warning(push)
#pragma warning(disable: 4702)
#define SOL_ALL_SAFETIES_ON 1
#define SOL_PRINT_ERRORS 0
#include <sol/sol.hpp>

View File

@ -3,6 +3,8 @@
#include "error.hpp"
#include "value_conversion.hpp"
#include "event_handler.hpp"
namespace scripting::lua
{
event_handler::event_handler(sol::state& state)
@ -14,26 +16,22 @@ 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)
{
std::vector<sol::lua_value> arguments;
bool has_built_arguments = false;
event_arguments arguments{};
for (const auto& argument : event.arguments)
{
arguments.emplace_back(convert(this->state_, argument));
}
this->dispatch_to_specific_listeners(event, arguments);
}
void event_handler::dispatch_to_specific_listeners(const event& event,
const event_arguments& arguments)
{
callbacks_.access([&](task_list& tasks)
{
this->merge_callbacks();
this->handle_endon_conditions(event);
for (auto i = tasks.begin(); i != tasks.end();)
{
@ -74,6 +72,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)
@ -116,4 +135,36 @@ namespace scripting::lua
});
});
}
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;
for (const auto& argument : event.arguments)
{
arguments.emplace_back(convert(this->state_, argument));
}
return arguments;
}
}

View File

@ -1,4 +1,5 @@
#pragma once
#include <utils/concurrency.hpp>
namespace scripting::lua
{
@ -19,6 +20,7 @@ namespace scripting::lua
event_callback callback = {};
bool is_volatile = false;
bool is_deleted = false;
std::vector<std::pair<scripting::entity, std::string>> endon_conditions{};
};
class event_handler final
@ -46,9 +48,12 @@ namespace scripting::lua
utils::concurrency::container<task_list> new_callbacks_;
utils::concurrency::container<task_list, std::recursive_mutex> callbacks_;
void dispatch_to_specific_listeners(const event& event, const event_arguments& arguments);
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;
};
}

View File

@ -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)

View File

@ -19,6 +19,7 @@ namespace scripting::lua
std::chrono::milliseconds delay{};
bool is_volatile = false;
bool is_deleted = false;
std::vector<std::pair<entity, std::string>> 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<task_list, std::recursive_mutex> 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();
};