Detecting reason (success/fail) for cancelling tasks and my further scripting problems

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:

self._component_trace = self._entity:trace_components('render')
                           :on_added(function(key, value)
                                 self:_trace_collision_shape()
                              end)
                           :push_object_state()

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.

1 Like

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.

1 Like

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.

1 Like

Just wanted to pop and and say that this is an incredibly cool thread. Kudos to you both, @Pawel_Malecki and @max99x :wink:

Please continue!

1 Like

Well, at this point you know the pros and cons of both approaches, and neither is particularly bad, so it’s up to you which choice you make. ¯\_(ツ)_/¯

1 Like