I cannot be the first to have written about this, but I couldn’t find anything, so here goes:
Sometimes it’s far more sensible to use Renoise objects as table keys directly, rather than use their index. Indexes can change, and some use cases like storing many samples across multiple instruments can get pretty painful this way.
The trouble is that every reference to a Renoise object in Lua code returns a unique userdata. But, the same underlying object will always be rawequal() to other userdatas that represent that object. So here is something I’ll call a rawtable, which works like a table in all ways except that when looking up objects, it tests by rawequal():
local rawtable = {}
function rawtable.new(t)
setmetatable(t, rawtable)
return t
end
function rawtable:__index(key)
for k, v in pairs(self) do
if (rawequal(k, key)) then
return v
end
end
end
function rawtable:__newindex(key, value)
for k, _ in pairs(self) do
if (rawequal(k, key)) then
rawset(self, k, value)
return
end
end
rawset(self, key, value)
end
-- Usage:
local instrs = rawtable.new {}
instrs[renoise.song().selected_instrument] = "foo"
print(instrs[renoise.song().selected_instrument]) -- Prints "foo"
Note that doing this is less efficient than using integer keys, as we’re doing a linear-time lookup by comparing against all objects in the table. But it should be fine unless you are storing a truly ridiculous number of objects.