top of page
image_2026-03-07_234357850.png
image_2026-03-07_234426150.png
image_2026-03-07_234946654.png

IDDO SHOIKHET

IMG_2160.jpeg

Iddo Shoikhet

Game programming student at Breda University of Applied Sciences

Where it started

The event expansion was meant to be comparable to Unity’s own event system as asked by another PR in my team. It is an in-engine editor only event system, which I attached to our custom VR engine; Offering more precision and control over what functions are invoked by which instances and when.

Event System Tool

The event expansion is an in-engine editor tool that allows the user to connect an existing entity to a function that is either a member of one of the components on the entity or a free function. These connections are made under an event (a struct made in code and triggered in code) once that event gets triggered all the functions connected to each entity will get invoked by that instance of entity. 

Where it stands

In addition to existing instances I improved on the original design to allow for the connection of component types to functions from either that component or any other included types, as well as any free functions.

This time once the event gets triggered any instance with all the included types will invoke the chosen function.

 

Of course the Improvements didn't stop there, I also implemented a recursive design for placing functions as parameters and the tool now also supports overloaded functions.

Pseudo code

The connector class defines 2 structs, one for the ImGui panel data and the other is for the information that a set connection between an instance and a function requires. The main function of this class is the "Trigger" function, which is added to ENTT's dispatcher's listener list when registering an event with the meta system,  with that event type as the templated parameter.

 

The "Trigger" function is called when that event's enqueued triggers are updated and are read from the queue, the function takes the event instance information and checks if the function is of an instance in the scene or of a component type. 

1. If it is of an instance (the entity isn't null) the function get's the instance from the registry and invokes the function with the argument information that it saves in the "connections" map variable.

2. If it's a component type (the meta type is valid) the function will get all the instances in the scene of that type (it will also filter in/out any of the types that are in the include or exclude lists) and it will invoke the function on all of those instances with the argument it gets from the map.

The function that constructs the arguments checks if the parameter data (which is of type entt::meta_any) can be cast into a vector<entt::meta_any> that means that it is a function that should be passed as an argument. The function "GetReturnFunc" will try and invoke the function and get the returned result as the argument. That function works recursively checking if any of the arguments of that function are vectors of meta_any and if so calls itself again; This could lead to a scenario as shown in the video above where a function requires a float to print so I use the Audio's GetVolume function instead of a set number, but that functions requires an audio name to get the volume of, then I use the Audio's GetCurrentAudio.

​

Recap: PrintFloat( <- GetVolume( <- GetCurrentAudio())

A snippet for your mind

The tool centers around the ECS architecture of the engine. In order to not slow down the performance and break the ECS workflow I naturally turned to ENTT's current event system which "enqueues" triggers and allows me to trigger them all together after a system is finished with it's logic

This is the base, in code one would use the "Enqueue()" function to add the event trigger to an array and later, at the end of the system's update function where the enqueue occurred and once the system finished accessing data, you would call the "UpdateEvent()" function to trigger the event. 

From here I made a class called "Connector" which connects between this code version and a tool in the editor. The class will create an editor widget and using meta information of classes that were pre-registered, it would offer the users the ability to  apply functions to instances/component types on a trigger of an event.

bottom of page