Skip to content

Commit

Permalink
[add] (lua) support for targeting specific entities when posting events
Browse files Browse the repository at this point in the history
  • Loading branch information
begla committed Apr 10, 2024
1 parent 4bf4385 commit 11c7f70
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 23 deletions.
45 changes: 39 additions & 6 deletions iolite_plugins/lua_plugin/init_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1656,24 +1656,57 @@ void script_init_state(sol::state& s)
// @param target_entity Ref The target entity listening for events.
// @param event_type string The type of events to stop listening for.
s["Events"]["unregister_event_listener"] = unregister_event_listener;

// @function post_event
// @summary Posts the given event type from the given source entity.
// @param source_entity Ref The entity the event is originating from.
// @param event_type string The type of the event to post.
s["Events"]["post_event"] = [](io_ref_t source_entity, const char* event_type) {
post_event(source_entity, event_type, nullptr, 0u);
};

// @function post_event
// @summary Posts the given event type from the given source entity.
// @param source_entity Ref The entity the event is originating from.
// @param event_type string The type of the event to post.
// @param target_entities table List of target entities this event should be delivered to

s["Events"]["post_event"] = sol::overload(
[](io_ref_t source_entity, const char* event_type) {
post_event(source_entity, event_type, nullptr, 0u, nullptr, 0u);
}, [](io_ref_t source_entity, const char* event_type, const sol::table& target_entities) {
std::vector<io_ref_t> targets(target_entities.size());
for (uint32_t i=0u; i<target_entities.size(); ++i)
targets[i] = target_entities[1u + i];
post_event(source_entity, event_type, nullptr, 0u, targets.data(), targets.size());
});

// @function post_event_with_payload
// @summary Posts the given event type from the given source entity with the provided payload of variants.
// @param source_entity Ref The entity the event is originating from.
// @param event_type string The type of the event to post.
// @param variants table Array of variants serving as the payload for the event.
s["Events"]["post_event_with_payload"] = [](io_ref_t source_entity, const char* event_type, const sol::table& variants) {

// @function post_event_with_payload
// @summary Posts the given event type from the given source entity with the provided payload of variants.
// @param source_entity Ref The entity the event is originating from.
// @param event_type string The type of the event to post.
// @param variants table Array of variants serving as the payload for the event.
// @param target_entities table List of target entities this event should be delivered to

s["Events"]["post_event_with_payload"] = sol::overload(
[](io_ref_t source_entity, const char* event_type, const sol::table& variants) {
std::vector<io_variant_t> vars(variants.size());
for (uint32_t i=0u; i<variants.size(); ++i)
vars[i] = variants[1u + i];
post_event(source_entity, event_type, vars.data(), vars.size());
};
post_event(source_entity, event_type, vars.data(), vars.size(), nullptr, 0u);
},
[](io_ref_t source_entity, const char* event_type, const sol::table& variants, const sol::table& target_entities) {
std::vector<io_variant_t> vars(variants.size());
for (uint32_t i=0u; i<variants.size(); ++i)
vars[i] = variants[1u + i];
std::vector<io_ref_t> targets(target_entities.size());
for (uint32_t i=0u; i<target_entities.size(); ++i)
targets[i] = target_entities[1u + i];
post_event(source_entity, event_type, vars.data(), vars.size(), targets.data(), targets.size());
});
};

s["UI"] = s.create_table();
Expand Down
53 changes: 42 additions & 11 deletions iolite_plugins/lua_plugin/lua_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,21 +371,29 @@ void unregister_event_listener(io_ref_t target_entity, const char* event_type)

//----------------------------------------------------------------------------//
void post_event(io_ref_t source_entity, const char* event_type,
io_variant_t* variants, io_size_t variants_length)
io_variant_t* variants, io_size_t variants_length,
io_ref_t* target_entities, io_size_t target_entities_length)
{
// Allocate event
lua_user_event_t::event_data_t* event =
(lua_user_event_t::event_data_t*)
io_custom_event_streams->post_event_uninitialized(
event_stream, event_type,
sizeof(lua_user_event_t) +
sizeof(io_variant_t) * variants_length);
sizeof(lua_user_event_t::event_data_t) +
sizeof(io_variant_t) * variants_length +
sizeof(io_ref_t) * target_entities_length);

// Copy payload
const auto begin = (io_variant_t*)(event + 1u);
memcpy(begin, variants, variants_length * sizeof(io_variant_t));
const auto variants_ptr = (io_variant_t*)(event + 1u);
memcpy(variants_ptr, variants, variants_length * sizeof(io_variant_t));
const auto target_entities_ptr = (io_ref_t*)(variants_ptr + variants_length);
memcpy(target_entities_ptr, target_entities,
target_entities_length * sizeof(io_ref_t));

// Set other metadata
event->variants = lua_array_wrapper_t(begin, variants_length);
event->variants = lua_array_wrapper_t(variants_ptr, variants_length);
event->target_entities =
lua_array_wrapper_t(target_entities_ptr, target_entities_length);
event->source_entity = source_entity;
}

Expand Down Expand Up @@ -420,14 +428,37 @@ void script_dispatch_user_events(sol::state& state, io_ref_t entity)

if (handle_event)
{
lua_user_event_t user_event;
const auto data =
*(lua_user_event_t::event_data_t*)io_events_get_data(event);

bool event_filtered = false;

// Filter target entities upfront (if provided)
if (!data.target_entities.empty())
{
user_event.data =
*(lua_user_event_t::event_data_t*)io_events_get_data(event);
user_event.type = io_base->name_get_string(event->type);
bool found = false;
for (auto it = data.target_entities.begin();
it != data.target_entities.end(); ++it)
{
if (io_ref_is_equal(entity, *it))
{
found = true;
break;
}
}

event_filtered = !found;
}

user_events.emplace_back(user_event);
if (!event_filtered)
{
lua_user_event_t user_event;
{
user_event.data = data;
user_event.type = io_base->name_get_string(event->type);
}
user_events.emplace_back(user_event);
}
}

event = io_events_get_next(event);
Expand Down
15 changes: 9 additions & 6 deletions iolite_plugins/lua_plugin/lua_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,12 @@ template <typename T> struct lua_array_wrapper_t
end_ptr = data + length;
}

inline T& operator[](size_t n) { return begin_ptr[n]; }
inline iterator begin() { return begin_ptr; }
inline iterator end() { return end_ptr; }
inline size_t size() { return size_t(end_ptr - begin_ptr); }
inline size_t max_size() { return size(); }
inline T& operator[](size_t n) const { return begin_ptr[n]; }
inline iterator begin() const { return begin_ptr; }
inline iterator end() const { return end_ptr; }
inline size_t size() const { return size_t(end_ptr - begin_ptr); }
inline bool empty() const { return size() == 0u; }
inline size_t max_size() const { return size(); }

T* begin_ptr{};
T* end_ptr{};
Expand All @@ -141,6 +142,7 @@ struct lua_user_event_t
{
io_ref_t source_entity;
lua_array_wrapper_t<io_variant_t> variants;
lua_array_wrapper_t<io_ref_t> target_entities;
} data;
};

Expand Down Expand Up @@ -184,4 +186,5 @@ void unregister_event_listener(io_ref_t target_entity, const char* event_type);
// provided variants as payload.
//----------------------------------------------------------------------------//
void post_event(io_ref_t source_entity, const char* event_type,
io_variant_t* variants, io_size_t variants_length);
io_variant_t* variants, io_size_t variants_length,
io_ref_t* target_entities, io_size_t target_entities_length);

0 comments on commit 11c7f70

Please sign in to comment.