Lua/API FX device objects not registering as deleted

Ran into this where if the user deletes a device like an EQ in renoise, the base reference does not delete properly and remains truthy. Mini tool to demonstrate:

ledger.scripts.ObjectExistsTest_V1.xrnx (1.1 KB)

Shortcut: Object Exists Test

  1. Open a fresh renoise song
  2. Hit the shortcut for the tool
  3. IMPORTANT: Now manually delete the newly added eq from renoise
  4. Hit the shortcut a second time

You will now get a valid oprint() of the device in the terminal, followed by an error in trying to read its display_name property.

The only way around this is to use a pcall to filter these “ghost instances” out, but my sense is that this is buggy rather than expected?

--global
local dev = nil

---------------------
function main()
---------------------
  --song/track
  local song = renoise.song()
  local track = song.selected_track
  
  if dev == nil then
    --insert a new eq 10
    dev = track:insert_device_at("Audio/Effects/Native/EQ 10", #track.devices + 1)
    return
  end
  
  --NOW DELETE THE ADDED EQ MANUALLY IN RENOISE

  --"Ghost Reference" Still prints even after device is deleted by user
  oprint(dev)
 
  --Errors out!
  oprint(dev.display_name)
  
end



pcall() function needed as a workaround:

--NOTE: dev object will still be valid (truthy) after the device (EQ 10) it points to in renoise
--is deleted by user, however its properties will not so we can test with a pcall to protect from
--an error firing
---------------------------
function pcall_dev(dev)
---------------------------
  local ok, result = pcall(function()
    return dev.name
  end)
  --true if dev legitimate, false if not
  return ok 
end
---

return just ends the project, i.e. returns. it doesn’t return any specific thing.

if Legs_has_a_question then
print("here is your answer")
return
else
print("Legs hasd no question")
end

that’s all.

= it returns from that loop then.

2 Likes

yep, just used here to exit the function avoiding an overarching if/else block like:

if dev == nil then
    --insert a new eq 10
    dev = track:insert_device_at("Audio/Effects/Native/EQ 10", #track.devices + 1)

else

    --NOW DELETE THE ADDED EQ MANUALLY IN RENOISE
  
    --"Ghost Reference" Still prints even after device is deleted by user
    oprint(dev)
   
    --Errors out!
    oprint(dev.display_name)

end

no so, just style choice

You’ll probably have to monitor this yourself using “track.devices_observable”

1 Like

The Lua user data no longer points to a valid object This is expected and actually can happen with all references to objects that are created within Renoise rather than from Lua.

Unfortunately, we can’t magically set such dangling references to nil from within Renoise.

But, we could add a global or member helper function to check whether the object that the Lua wrapper refers still exists.

I’m not sure how practical this would be. It maybe makes more sense to me to avoid such dangling references, or to keep track of them via notifiers, as martblek mentioned.

‘return’ in LUA, like most languages, can return a value to the caller; defaults to undef/nil.

Psuedo:
$retVal = function();
if $retVal {
#function returned a value
}

1 Like

the pcall() function does work for this, if used carefully i.e. to catch and not bypass errors, should it be ok for this task?

---------------------------
function pcall_dev(dev)
---------------------------
  local ok, result = pcall(function()
    return dev.name
  end)
  --true if dev legitimate, false if not
  return ok 
end
---