" renoise.Document " probs in 3.5.2 (Tagged Plugin Search tool)

A baffling but consistent bug to do with renoise.Document in as of renoise 3.5.2; wasn’t there in renoise 3.4.3 - also confirmed on separate Windows machine.

Tagged Plugin Search Tool (tool version 0.58 still)

The tool can be toggled on and off successfully 4/5 times then starts throwing up errors that don’t really make sense on closer inspection. They are about the creation of the document structure needed to load the xml that stores the plugin paths etc. even though the doc is created from scratch/fresh in the function firing the error.

Will keep investigating but thought I’d post in case anyone knows about changes with latest API, or is running into any similar probs with latest renoise with renoise.Document?


--------- Snippets ------------

Click: relevant function code I'm working on
--called by main
-------------------------------
function create_document()
-------------------------------
   
  local song = renoise.song()
  
  --NOTES:
  --------
  --list/node/list/node (??not lists to lists??)
  --Nodes can be added to lists
  --lists can be added to nodes
  
  -------
  --lists
  --------
  --list as "value" to be added into main doc 
  local plugin_type_list = renoise.Document.DocumentList()
  local page_list = renoise.Document.DocumentList()
  local tag_list = renoise.Document.DocumentList()
  local plug_list = renoise.Document.DocumentList()
  
  local root = nil
  ----------------------
  --create main doc/root
  ----------------------
  root = renoise.Document.create("TaggedPluginsTool") {   
    plugin_types = plugin_type_list,
    --name = NUL,
   }
   
   --> root.plugin_types[]
  
  --------------------
  --define node models 
  --------------------
  
  --level 1 node model
  --------------------
  renoise.Document.create("PluginType") {
    name = NUL,
    pages = page_list, --creates type(doc_list), empty at moment in declaration but will be defined below
   } 
   
  --> root.plugin_types[].pages[]
  -------------------------------
  
  --level 2 node model
  --------------------
  renoise.Document.create("Page") {
    tags = tag_list, --creates tag(doc_list), empty at moment in declaration but will be defined below
    name = NUL
   }
   
   --> root.plugin_types[].pages[].tags[]
   --> root.plugin_types[].pages[].name.value
   -------------------------------------------
  
  --level 3 node model
  --------------------
  renoise.Document.create("Tag") {
    plugs = plug_list,
    name = NUL,
    number = NUL,
   }
   
   --> root.plugin_types[].pages[].tags[].plugs[]
   --> root.plugin_types[].pages[].tags[].name.value
   -------------------------------------------------
 
  --level 4 node model (MOST NESTED)
  ----------------------------------
  renoise.Document.create("Plugin") { --model name registration
     plug_name = "",
     plug_path = "",
   }
   
   --> root.plugin_types[].pages[].tags[].plugs[].plug_name.value
   --> root.plugin_types[].pages[].tags[].plugs[].plug_path.value
   
   
   -- root = nil
  -----------------------------------
  
  --Populate empty lists with nodes to create structure
  -----------------------------------------------------
  --instantiate models:
  --IMPORTANT! NEEDS TO BE DONE REVERSE ORDER: 'most nested' node first (--??)
  ----------------------------------------------------------------------  
  
  --4) NOT NEEDED AS PLUGS ARE ADDED BY FUNCTION LATER WHICH DOES INSTANTIATION + INSERTION ITSELF
  --4) instantiate "Plugin" then add as node :
  ----------------------------------------
  --local my_plugin = renoise.Document.instantiate("Plugin")
  --insert "Plugin" doc node, into plug_list object "List":
  --plug_list:insert(my_plugin)
  ---------------------------------
  
  

  
  
  
  
  --3) Instantiate and insert insert 12 tags per page
  ------------------------------------------------
  for i = 1,12 do
    --instantiate "Tag"node model
    local my_tag = renoise.Document.instantiate("Tag")   
    tag_list:insert(my_tag)
  end
     
  --2) instantiate "Page"s then add as nodes in page_list so we get <Page><Tag><Plugin>
  ------------------------------------------------
  --print(g_retrieved_xml)
  --pcall(function() print(renoise.Document.instantiate("Page"))end)
  
 -- print(renoise.Document.instantiate("Page"))

  local my_page = renoise.Document.instantiate("Page")
  local my_page2 = renoise.Document.instantiate("Page")
  local my_page3 = renoise.Document.instantiate("Page")
  --insert 
  page_list:insert(my_page)
  page_list:insert(my_page2)
  page_list:insert(my_page3)
  
  --1) instantiate type, [1] will be instruments and [2] effects
  --------------------------------------------------------------
  local my_type = renoise.Document.instantiate("PluginType")
  local my_type_2 = renoise.Document.instantiate("PluginType")
  
  plugin_type_list:insert(my_type)
  plugin_type_list:insert(my_type_2)
  -----
  
  --print(#root.plugin_types)

  --put in values
  -----------------------
  --1) default instrument
  -----------------------
  local inst = root.plugin_types[1]
  ------------------------------------------------------
  --set the default page names (REMEMBER to use '.value')
  -------------------------------------------------------
  inst.pages[1].name.value = "Page 1"
  inst.pages[2].name.value = "Page 2"
  inst.pages[3].name.value = "Page 3"
  
  --set the tag numbers for instruments
  --------------------------------------
  for page = 1,3 do
    for tag = 1,12 do
      inst.pages[page].tags[tag].number.value = tostring(tag)
    end
  end
  
  --set the default tag names ---------------------------(TODO use vars for efficiency i.e. local pge =)
  ---------------------------
  for page = 1,3 do
    for tag = 1,12 do
      inst.pages[page].tags[tag].name.value = tostring(tag) --"Tag "..tag
    end
  end
  
  ---------------
  --2) default fx
  ---------------
  local fx = root.plugin_types[2]
  ------------------------------------------------------
  --set the default page names (REMEMBER to use '.value')
  -------------------------------------------------------
  fx.pages[1].name.value = "Page 1"
  fx.pages[2].name.value = "Page 2"
  fx.pages[3].name.value = "Page 3"
  
  --set the tag numbers for fx
  ----------------------------
  for page = 1,3 do
    for tag = 1,12 do
      fx.pages[page].tags[tag].number.value = tostring(tag)
    end
  end
  
  --set the default tag names ------------------------------(TODO use vars for efficiency i.e. local pge =)
  ---------------------------
  for page = 1,3 do
    for tag = 1,12 do
      fx.pages[page].tags[tag].name.value = tostring(tag) --"Tag "..tag
    end
  end
  
  --set type names as Instrument or FX
  --------------------------------------
  inst.name.value = "Instrument"
  fx.name.value = "Effect"
    
  --sort nodes alphabetically??
  
 -- oprint(root)
  -----------------
  --Document object
  -----------------
  return root

end

One of the errors keeps firing about this line:

line 122 :

local my_page = renoise.Document.instantiate("Page")

Click: Error that fires

*** std::logic_error: ‘document lists in models must be empty. add initial nodes after instantiating the model.’
*** stack traceback:
*** [C]: in function ‘instantiate’
*** .\fns_create_save_file.lua:122: in function ‘create_document’
*** main.lua:216: in function ‘load_data_from_xml_file’
*** main.lua:442: in function ‘main’
*** main.lua:190: in function ‘main_toggle’
*** main.lua:50: in function main.lua:50

Each time the whole function runs it should populate the doc structure with fresh locally created properties but when the error fires it says there is already data present that should not be there..? Again this only happens after toggling the tool on an off a few times already, so the structure build fine at first, and no probs in rns 3.4.3

Anyway I’ll keep combing through and maybe try and rebuild a test function to create the same structure differently, but still strange this only happens in latest renoise.

Update: after some chatbot consulting, I added garbage collection when the tool toggles open/closed. This seems to crash the tool after fewer toggles i.e. 3 rather than 5, so it seems to accelerate the failure:

Conversely, adding this when in renoise 3.4.4, the tool happily does the prints and continues working.



line 160 in main.lua

--------------------------------------------------------------
--toggle the tool open and closed (keyboard shortcut start-up)
--------------------------------------------------------------
function main_toggle()
----------------------

  print("Memory before GC:", collectgarbage("count"))
  collectgarbage("collect")
  print("Memory after GC:", collectgarbage("count"))

I have no idea about the code you posted, also never used renoise.Document. But isn’t this again an event problem, like when Renoise.document actually is available? The difference in 3.4.3 vs. 3.5.2 most likely will be the JIT character of LUA. What if you run your code inside the idle or song created event?

Good point! didn’t consider the JIT stuff, will have a test using idle.

Update:

It seems this may have something to do with Lua JIT being more picky about the .Document definition and initialisation rules/order. Hopefully will be able to rescue the tool keeping current document and saved .xml structure, without having to write some updater code to fit into something new. I’ll post up what I find out after, but first steps have been untangling from this:

This seems to have been instantiating the .Document.DocumentList() which I was then using in the definition to build the final document/xml.

  --list as "value" to be added into main doc 
  local plugin_type_list = renoise.Document.DocumentList()
  local page_list = renoise.Document.DocumentList()
  local tag_list = renoise.Document.DocumentList()
  local plug_list = renoise.Document.DocumentList()
  renoise.Document.create("PluginType") {
    name = NUL,
    pages = page_list, --PROBLEM: page_list already an instance 
   }

First step was to change to this (sans parenthesis()), so I wasn’t initialising but just referencing

local plugin_type_list = renoise.Document.DocumentList

then decided to clear the redundancy and just use renoise.Document.DocumentList() directly while building the doc. like so:

renoise.Document.create("PluginType") {  
    name = NUL, --Instrument or FX
    pages = renoise.Document.DocumentList(),  --Now describes an empty "placeholder"
   }

Some progress but think I am on the right track now..

1 Like

indeed :grin:

1 Like