Traces seem to be used rarely, mostly for engine-related stuff and all the examples are rather short. One the most similar to what you posted seems to appear in renderers/construction_data/construction_data_renderer.lua:
I’d rather wrap it into another function for shorter syntax. Assuming I want all existing components to call self:function_name(args) when my function is called I guess (I’ve never used a trace before) it would look like this:
function pawel_API:component_trigger(entity, function_name, args)
if entity and entity:is_valid() and type(function_name) == 'string' then
local component_trace = entity:trace_components('not important log text')
:on_added(function(function_name, component)
if type(component[function_name]) == 'function' then
component[function_name](component, args)
end
end
:push_object_state()
component_trace:destroy()
end
end
Correct me if I’m wrong. Also, I don’t know if such a solution is saving memory compared to listening to events.
Traces are a bit heavier than listeners, but honestly, unless you are seeing major memory impact, this feels like a case of premature optimization. Having an explicit listener is cleaner and more straightforward than automagically calling a private function on every component, and until performance issues are evident, clarity is more important than performance.
In most cases we’re speaking about two or three listeners per component. The autoharvest itself needs one to trace entity form and one for the time the harvest task is active. This adds one listener per renewable resource node and another one created on request_harvest() and listening to an event fired when the task is cancelled. I’ll need another one when I’ll start working on my territory claiming mod to listen to player_id changes.
For every component I want to react to entity form change (e.g. if I added a heat source like in Frostfeast) I need one listener to trace the form. This multiplies listeners when it is not necessary as all I want is for every component to call component:_on_removed_from_world() when an entity goes iconic and component:_on_added_to_world() when it is placed in the world.
When you add up herbs, fiber plants and berries/cacti this actually makes a lot of listeners. I’d better be safe than sorry.