As a coincidence, I refined an old “line2table” scheme today with the aim of making it as fast as possible.
The main difference to danoise’s solution is that It tries to minimize overhead in terms of object creation, lookups and function calls. For a new scripter it probably has a simpler syntax as it avoids any OO, but it might not be the prettier solution in a bigger project
Click to view contents
-- for sequence tracks only
function line2table(line)
local t_line = {
["note_columns"] = {
{ ["delay_value"] = 0, ["effect_amount_value"] = 0, ["effect_number_value"] = 0, ["instrument_value"] = 255, ["note_value"] = 121, ["panning_value"] = 255, ["volume_value"] = 255, ["is_empty"] = true },
{ ["delay_value"] = 0, ["effect_amount_value"] = 0, ["effect_number_value"] = 0, ["instrument_value"] = 255, ["note_value"] = 121, ["panning_value"] = 255, ["volume_value"] = 255, ["is_empty"] = true },
{ ["delay_value"] = 0, ["effect_amount_value"] = 0, ["effect_number_value"] = 0, ["instrument_value"] = 255, ["note_value"] = 121, ["panning_value"] = 255, ["volume_value"] = 255, ["is_empty"] = true },
{ ["delay_value"] = 0, ["effect_amount_value"] = 0, ["effect_number_value"] = 0, ["instrument_value"] = 255, ["note_value"] = 121, ["panning_value"] = 255, ["volume_value"] = 255, ["is_empty"] = true },
{ ["delay_value"] = 0, ["effect_amount_value"] = 0, ["effect_number_value"] = 0, ["instrument_value"] = 255, ["note_value"] = 121, ["panning_value"] = 255, ["volume_value"] = 255, ["is_empty"] = true },
{ ["delay_value"] = 0, ["effect_amount_value"] = 0, ["effect_number_value"] = 0, ["instrument_value"] = 255, ["note_value"] = 121, ["panning_value"] = 255, ["volume_value"] = 255, ["is_empty"] = true },
{ ["delay_value"] = 0, ["effect_amount_value"] = 0, ["effect_number_value"] = 0, ["instrument_value"] = 255, ["note_value"] = 121, ["panning_value"] = 255, ["volume_value"] = 255, ["is_empty"] = true },
{ ["delay_value"] = 0, ["effect_amount_value"] = 0, ["effect_number_value"] = 0, ["instrument_value"] = 255, ["note_value"] = 121, ["panning_value"] = 255, ["volume_value"] = 255, ["is_empty"] = true },
{ ["delay_value"] = 0, ["effect_amount_value"] = 0, ["effect_number_value"] = 0, ["instrument_value"] = 255, ["note_value"] = 121, ["panning_value"] = 255, ["volume_value"] = 255, ["is_empty"] = true },
{ ["delay_value"] = 0, ["effect_amount_value"] = 0, ["effect_number_value"] = 0, ["instrument_value"] = 255, ["note_value"] = 121, ["panning_value"] = 255, ["volume_value"] = 255, ["is_empty"] = true },
{ ["delay_value"] = 0, ["effect_amount_value"] = 0, ["effect_number_value"] = 0, ["instrument_value"] = 255, ["note_value"] = 121, ["panning_value"] = 255, ["volume_value"] = 255, ["is_empty"] = true },
{ ["delay_value"] = 0, ["effect_amount_value"] = 0, ["effect_number_value"] = 0, ["instrument_value"] = 255, ["note_value"] = 121, ["panning_value"] = 255, ["volume_value"] = 255, ["is_empty"] = true }
},
["effect_columns"] = {
{ ["number_value"] = 0, ["amount_value"] = 0, ["is_empty"] = true },
{ ["number_value"] = 0, ["amount_value"] = 0, ["is_empty"] = true },
{ ["number_value"] = 0, ["amount_value"] = 0, ["is_empty"] = true },
{ ["number_value"] = 0, ["amount_value"] = 0, ["is_empty"] = true },
{ ["number_value"] = 0, ["amount_value"] = 0, ["is_empty"] = true },
{ ["number_value"] = 0, ["amount_value"] = 0, ["is_empty"] = true },
{ ["number_value"] = 0, ["amount_value"] = 0, ["is_empty"] = true },
{ ["number_value"] = 0, ["amount_value"] = 0, ["is_empty"] = true }
}
}
if not line.is_empty then
for ecol_index, ecol in ipairs(line.effect_columns) do
if (not ecol.is_empty) then
local t_ecol = t_line.effect_columns[ecol_index]
t_ecol.is_empty = false
t_ecol.number_value = ecol.number_value
t_ecol.amount_value = ecol.amount_value
end
end
for ncol_index, ncol in ipairs(line.note_columns) do
if (not ncol.is_empty) then
local t_ncol = t_line.note_columns[ncol_index]
t_ncol.is_empty = false
t_ncol.delay_value = ncol.delay_value
t_ncol.effect_amount_value = ncol.effect_amount_value
t_ncol.effect_number_value = ncol.effect_number_value
t_ncol.instrument_value = ncol.instrument_value
t_ncol.note_value = ncol.note_value
t_ncol.panning_value = ncol.panning_value
t_ncol.volume_value = ncol.volume_value
end
end
end
return t_line
end
function table2line(t_line, line)
for ecol_index, ecol in ipairs(t_line.effect_columns) do
local line_ecol = line:effect_column(ecol_index)
if ecol.is_empty then
if (not line_ecol.is_empty) then
line_ecol:clear()
end
else
line_ecol.number_value = ecol.number_value
line_ecol.amount_value = ecol.amount_value
end
end
for ncol_index, ncol in ipairs(t_line.note_columns) do
local line_ncol = line:note_column(ncol_index)
if ncol.is_empty then
if (not line_ncol.is_empty) then
line_ncol:clear()
end
else
line_ncol.delay_value = ncol.delay_value
line_ncol.effect_amount_value = ncol.effect_amount_value
line_ncol.effect_number_value = ncol.effect_number_value
line_ncol.instrument_value = ncol.instrument_value
line_ncol.note_value = ncol.note_value
line_ncol.panning_value = ncol.panning_value
line_ncol.volume_value = ncol.volume_value
end
end
end
I think this is as fast and simple as it can get. (Well, there might be (or not) a variation that is 5-10% faster, using line strings and string manipulation for extracting line data. But the code complexity of that didn’t seem justified)