How to unserialize DocumentList?

I am trying to use the renoise.Document API for saving song.tool_data, which seems pretty convenient! However, I cannot seem to unserialize/load it (as a document).

I have a bunch of objects/nodes in a DocumentList. Any pointers on how to load them from the xml string, using the from_string() method? Need I create some object as a prototype for the list? (I’ve tried that also, I think)

Here is the code, in which the second function doesn’t work.

Summary
function App:update_song_tool_data()
  local rhythms = renoise.Document.DocumentList()

  local main_doc = renoise.Document.create("Arranger") {
    Rhythms = rhythms
  }

  for rhythm_idx, rhythm in ipairs(self.rhythms) do
    rhythms:insert(rhythm)
  end

  renoise.song().tool_data = main_doc:to_string()
end


-- DOESN'T WORK
function App:load_song_tool_data() 

  local rhythms = renoise.Document.DocumentList()

  local main_doc = renoise.Document.create("Arranger") {
    Rhythms = rhythms
  }

  main_doc:from_string(renoise.song().tool_data) -- !!!!!

  -- print(main_doc:to_string()) -- yup. didn't unserialize
end

XML string:

Summary
<?xml version="1.0" encoding="UTF-8"?>
<Arranger doc_version="0">
  <Rhythms>
    <Rhythm type="lua_class:Rhythm">
      <rhythm>1.0</rhythm>
      <length>32</length>
      <linerot>0.0</linerot>
      <steprot>0.0</steprot>
      <inst_index>1.0</inst_index>
      <note_value>48</note_value>
      <track_index>1.0</track_index>
      <pattern_index>1.0</pattern_index>
    </Rhythm>
    <Rhythm type="lua_class:Rhythm">
      <rhythm>2</rhythm>
      <length>32</length>
      <linerot>0.0</linerot>
      <steprot>0.0</steprot>
      <inst_index>2</inst_index>
      <note_value>48</note_value>
      <track_index>2</track_index>
      <pattern_index>1.0</pattern_index>
    </Rhythm>
  </Rhythms>
</Arranger>

I think I found the fix. The automatic run of class:__init() is a bit obnoxious during Doc:load_file() and Doc:from_string().

Keep __init() as clean as possible by doing something like this, making sure it can be run without assigning any values:

Summary
class 'Rhythm' (renoise.Document.DocumentNode)

function Rhythm:__init(args)
  renoise.Document.DocumentNode.__init(self)
  
  if args then
    self.app = args.app
  end
  
  self:add_property("rhythm", renoise.Document.ObservableNumber())
  self:add_property("length", renoise.Document.ObservableNumber())
  self:add_property("linerot", renoise.Document.ObservableNumber())
  self:add_property("steprot", renoise.Document.ObservableNumber())
  self:add_property("inst_index", renoise.Document.ObservableNumber())
  self:add_property("note_value", renoise.Document.ObservableNumber())
  self:add_property("track_index", renoise.Document.ObservableNumber())
  self:add_property("pattern_index", renoise.Document.ObservableNumber())
  
  if args then
    self:property( "rhythm"        ).value = args.pattern or 1
    self:property( "length"        ).value = args.length or 32
    self:property( "linerot"       ).value = args.linerot or 0
    self:property( "steprot"       ).value = args.steprot or 0
    self:property( "inst_index"    ).value = args.inst_index or 1
    self:property( "note_value"    ).value = args.note_value or 48
    self:property( "track_index"   ).value = args.track_index or 1
    self:property( "pattern_index" ).value = args.pattern_index or 1
    
    self.gui = TrackGui { gui = self.app.gui, rhythm = self }.view
    
  end

end
1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.