Lua ООП с метатаблицами, проблемы с загрузкой функции из файла

Я пытаюсь сохранить данные в файле, достаточном для создания метатабличного «класса» в таком формате, чтобы его можно было загрузить как функцию.

Основная идея здесь: Как загрузить данные из другого lua файл?

Мне удалось создать файл и успешно загрузить его. Я знаю, что все данные читаются, потому что у меня были синтаксические ошибки, пока файл не был правильно отформатирован. Но я не могу получить доступ к полям в данных.

Редактировать: спасибо плакату ниже, который указал, что мне нужны кавычки для строковых значений в написанном файле. Исходя из этого у меня он почти работает

Однако у меня все еще есть проблема с настройкой метатаблиц для функции файла после загрузки. Каждый объект плагина имеет несколько банков, и когда я загружаю их, я получаю дополнительную подтаблицу банка. Это либо дубликат одной из таблиц (не всегда один и тот же), а иногда и неправильно сформированная таблица, которая не реализует метод tostring. Вот код:


local Bank = {}
Bank.__index = Bank

function Bank.new(name,hue,sat,preset)
    local self = setmetatable({}, Bank) 
    self.name = name
    self.hue = hue or 0
    self.sat = sat or 0
    self.params = {}
    self.presets = {preset} or {}
    return self
end

function Bank:addPreset(name)
    table.insert(self.presets,name)
end

function Bank:setParam(control,name)
    self.params[control]=name
end

function Bank:getParam(control)
    return self.params.name
end

function getParamStr(params)
    paramT= {}
    paramStr = 'params = {'
    for control,param in pairs(params) do
        table.insert(paramT,control..' = '..esc(param))
    end
    paramStr = paramStr..table.concat(paramT,',')..'},'
    return paramStr
end

local   Plugin = {}
Plugin.__index = Plugin

function Plugin:__tostring() 
    bankT = {}
    plugStr = 'return {\n'..'name = '..esc(self.name)..', '    
    bankPre = '\n    banks = {\n    '
    for bankName in pairs(self.banks) do 
        table.insert(bankT,tostring(self.banks[bankName]))
    end
    return plugStr..getParamStr(self.params)..bankPre..table.concat(bankT,',\n    ')..'\n    }\n'..'}'  
end
function Bank:__tostring()
    rtnStr = '    '..self.name..' = { '..'name = '..esc(self.name)..', hue = '..self.hue..', sat = '..self.sat..', ' 
    ..getParamStr(self.params)..'\n'
    ..'            presets = {\"'..table.concat (self.presets,'\", \"')..'\" }\n'
    ..'        }'
    return rtnStr
end

function Plugin.new(vstName)
    local self = setmetatable({}, Plugin)
    self.name = vstName
    self.params = {}
    self.banks = {}
    return self
end


function Plugin:getPresetList()
    return table.sort(self.presets)
end

function Plugin:addBank(bankName,hue,sat,preset)
    --just quietly overwrite any existing bank?  for now...
    self.banks[bankName] = Bank.new(bankName,hue,sat,preset)
end

function Plugin:addPresetToBank(bankName,preset)    
    self.banks[bankName]:addPreset(preset)
end

function Plugin:getBank(bank)
    return self.banks[bank]
end

function Plugin:setColor(hue,sat)
    self.hue = hue
    self.sat = sat
end

function Plugin:getColor(level)
    return 'hue: '..self.hue..' and sat: '..self.sat
end

function Plugin:setParam(control,name)
    self.params[control]=name   
end

function Plugin:getParam(control)
    --print(self.params.control)
    return self.params[control]
end

function Bank.init(data)
    local self = setmetatable(data,Bank)
    return self
end

function Plugin.load(filename)
    local f = assert(loadfile('c:\\lua\\'..filename..'.lua'))
    data = f()
    local self = setmetatable(data,Plugin)   
    for bankName,table in pairs(self.banks) do
        self.banks.bankName = Bank.init(table)
    end
    return self
end
function Plugin:save()
    filename = 'c:\\lua\\'..self.name..'.lua'
    local file = io.open(filename,'w')
    file:write(tostring(self))
    file:close() 
end

function Plugin.test(name)
    plug = Plugin.new(name)
    plug:setColor(120,.08)
    plug:setParam('A1','Reverb')
    plug:setParam('A2','Chorus')
    plug:addBank('favorites',120,.05,'Ice Bell')
    plug:addBank('pianos',10,.09,'Black')
    plug:addPresetToBank('pianos','Grandeur')
    plug:addPresetToBank('favorites','OB pad')
    curBank = plug:getBank('favorites')
    curBank:setParam('A5','Wah')
    plug:getBank('pianos'):setParam('A1','Reverb')
    return plug
end

plugName = 'test'
plug = Plugin.test(plugName)
plug:save()
plug2 = Plugin.load(plugName)
print(plug2)
plug2.name = 'test2'
plug2:save()


Сгенерированный файл данных выглядит следующим образом:

return {
name = "test", params = {A1 = "Reverb",A2 = "Chorus"},
    banks = {
        favorites = { name = "favorites", hue = 120, sat = 0.05, params = {A5 = "Wah"},
            presets = {"Ice Bell", "OB pad" }
        },
        pianos = { name = "pianos", hue = 10, sat = 0.09, params = {A1 = "Reverb"},
            presets = {"Black", "Grandeur" }
        }
    }
}

но после загрузки я получаю что-то вроде этого:

return {
name = "test2", params = {A1 = "Reverb",A2 = "Chorus"},
    banks = {
    table: 00e8eae0,
        favorites = { name = "favorites", hue = 120, sat = 0.05, params = {A5 = "Wah"},
            presets = {"Ice Bell", "OB pad" }
        },
        favorites = { name = "favorites", hue = 120, sat = 0.05, params = {A5 = "Wah"},
            presets = {"Ice Bell", "OB pad" }
        }
    }
}

Не уверен, откуда берется "фантомная" таблица... Я также не понял, как избежать дублирования имени банка в файле, но это не имеет большого значения.

Заранее спасибо!!!!


person eric moon    schedule 21.10.2020    source источник
comment
Файл ничего не возвращает?   -  person user253751    schedule 21.10.2020
comment
Кажется, вы склеили два файла вместе, как будто они были одним файлом? Это не работает. Пожалуйста, покажите два отдельных файла.   -  person user253751    schedule 21.10.2020
comment
Это один файл. Я обновлю сообщение, включив в него созданный файл данных.   -  person eric moon    schedule 21.10.2020
comment
вокруг ваших строк нет ", поэтому name = kontakt совпадает с name = nil, потому что kontakt не определено.   -  person Nifim    schedule 21.10.2020
comment
Есть ли более элегантный способ записать их в виде строк, чем просто заключать в кавычки с обратной косой чертой?   -  person eric moon    schedule 21.10.2020
comment
в lua вы можете использовать ' или " для определения строки. если вы делаете return {\n'..'name = "'..self.name..'", ', побег не нужен.   -  person Nifim    schedule 21.10.2020
comment
Код обновлен, чтобы включить escape-строки, и метатаблицы в основном работают.   -  person eric moon    schedule 22.10.2020


Ответы (1)


РЕДАКТИРОВАТЬ 1: Сделать мои поля фактическими строками и изменить метод инициализации плагина на это:

function Plugin.init(data)
    self = setmetatable(data,Plugin)
    return self
end

Кажется, работает правильно.

РЕДАКТИРОВАТЬ 2:

Проблема со странными таблицами Bank заключалась в синтаксической ошибке в методе Plugin.Load:

self.banks.bankName = Bank.init(table) --sort of worked??
self.banks[bankName] = Bank.init(table) --good

Если кто-нибудь может объяснить, почему первые дали непредсказуемые результаты, это было бы интересно узнать. Это не очевидно для меня. Но сейчас работает отлично.

person eric moon    schedule 21.10.2020