The problem is that “inserting a track” is not an atomic operation, and the Lua notifiers get called some when in between a complex operation:
InsertTrack in Renoise, internally is:
** a the "real" track (the thing you see in the mixer, the thing with has DSP devices, renoise.song().tracks in Lua) to the song
* add a new track into each pattern
* add a new track into each slot in the pattern sequence (where the track mutes live)
* do a shitload of other track related stuff here and there
** is where your Lua notifier gets called.
At this time there is a new track in the song already, but not in the other places. And that’s why the track index refers to the previous track in the matrix, when being accessed !within! the notifier.
Actually it’s pretty evil that we do send out notifiers to Lua while the document is in inconsistent state. What we should do instead, is sending the notification as soon as all the shit is done, at the end of the internal track inserting stuff. Will try to do so for the next release.
Actually it’s pretty evil to modify the document itself while it’s firing notifications about document changes (muting a track while its being inserted). The track insert notifier is also called when cloning a track or when undo/redoing. There you don’t want to do such things and this will do strange things.
What we’d need instead, is a hook which is called as soon as the user adds a new track, and only then. Something like a post “initialize” function. This would for example also allow to do proper custom DSP or instrument preset customization.
Conner: For now as a workaround postphone the stuff to a timer (as usual), so it’s called after all the internal shit is done. The OneShotIdle class may help to do so:
[luabox]
– delay a function call by the given amount of time into a tools idle notifier
– for example: ´OneShotIdleNotifier(100, my_callback, some_arg, another_arg)´
– calls “my_callback” with the given arguments with a delay of about 100 ms
– a delay of 0 will call the callback “as soon as possible” in idle, but never
– immediately
class “OneShotIdleNotifier”
function OneShotIdleNotifier:__init(delay_in_ms, callback, …)
assert(type(delay_in_ms) == “number” and delay_in_ms >= 0.0)
assert(type(callback) == “function”)
self._callback = callback
self._args = arg
self._invoke_time = os.clock() + delay_in_ms / 1000
renoise.tool().app_idle_observable:add_notifier(self, self.__on_idle)
end
function OneShotIdleNotifier:__on_idle()
if (os.clock() >= self._invoke_time) then
renoise.tool().app_idle_observable:remove_notifier(self, self.__on_idle)
self._callback(unpack(self._args))
end
end
[/luabox]