diff options
Diffstat (limited to 'dalos-luafilter.lua')
-rw-r--r-- | dalos-luafilter.lua | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/dalos-luafilter.lua b/dalos-luafilter.lua new file mode 100644 index 0000000..312aff7 --- /dev/null +++ b/dalos-luafilter.lua @@ -0,0 +1,174 @@ +dalosp.luafilter = { + templates = {}, + + default_code = [[ +-- available globals: + +-- ninputs, noutputs: numbers + +-- get_input(ind): handle +-- del_output(ind): nil +-- new_output(ind): nil +-- set_color(c) : nil + +function activate() +end + +function read(ind, count, userdata, offset) +end + +function seek(ind, offset) +end + +function input_change(ind) +end +]], + + get_settings = function (self) + return { ninputs = self.ninputs, noutputs = self.noutputs, code = self.extra.code } + end, + + run_in_localenv = function (self, f, ...) + local localenv = self.extra.localenv + local metatable = getmetatable(_G) + if not metatable then metatable = {} end + local oldni, oldi = metatable.__newindex, metatable.__index + metatable.__newindex = function (table, key, value) + localenv[key] = value + end + metatable.__index = function (table, key) + local l = localenv[key] + if l then return localenv[key] end + return rawget(_G, key) + end + setmetatable(_G, metatable) + + if type(f) ~= "function" then f = localenv[f] end + local rets = { true } + if f then rets = { pcall(f, ...) } end + + metatable.__newindex, metatable.__index = oldni, oldi + setmetatable(_G, metatable) + + if not rets[1] then error(rets[2]) end + table.remove(rets, 1) + return unpack(rets) + end, + + load_code = function (self, code) + self.extra.localenv = { + ninputs = self.ninputs + 0, + noutputs = self.noutputs + 0, + get_input = function(ind) return self:get_linked_input(ind) end, + del_output = function(ind) self:set_houtput(nil, ind) end, + new_output = function(ind, size, name) + self:set_houtput(dalos.luahandle{ + size = size, + getname = function () + return name + end, + do_read = function (lh, count, userdata) + return self:run_in_localenv("read", ind, count, userdata, lh.offset) + end, + do_seek = function (lh) + return self:run_in_localenv("seek", ind, lh.offset) + end, + }, ind) + end, + set_color = function(c) self.color = c self:draw() end, + } + if code and code ~= "" then + local f = loadstring(code) + if f then self:run_in_localenv(f) end + end + end, + + input_change = function (self, ind) + self:run_in_localenv("input_change", ind) + end, + + load_template = function (self) + local dlg = iup.filedlg { + dialogtype = "Open", + filter = "*.dtpl", + } + iup.Popup(dlg) + if dlg.status == -1 then return end + + local s, v = pcall(Input, dlg.value) + if not s then error("Problem loading file " .. dlg.value) end + local f = preload(v) + v:destroy() + if not f then error("Syntax error loading file " .. dlg.value) end + local data, otype, tname = f() + if otype ~= "Lua Filter" then error("Wrong template type: " .. otype) end + + self:apply_template(data.template) + end, + + gen_template = function (self) + return { code = self.extra.close } + end, + + apply_template = function (self, data) + self.extra.code = data.code + end, + + configure = function (self) + local okay = false + local text = iup.text { multiline = "Yes", font = "Courier", expand = "Yes", value = self.extra.code } + local bok = iup.button { title = "Ok", action = function () okay = true return iup.CLOSE end } + local bimport = iup.button { title = "Import", action = function() self:load_template() return iup.CLOSE end } + local bexport = iup.button { title = "Export", action = function() self:save_template(self:gen_template()) end } + local busetpl = iup.button { title = "Use Template", action = function() self:use_template(dalosp.luafilter.templates) end } + local bcancel = iup.button { title = "Cancel", action = function () okay = false return iup.CLOSE end } + local dlg = iup.dialog { iup.vbox { text, iup.hbox { bok, bimport, bexport, busetpl, iup.fill{}, bcancel, normalizesize = "Horizontal" } }, title = "Code for " .. self.name, size = "600x300" } + local r = dlg:popup() +-- if r ~= iup.NOERROR then return end + local newcode = text.value + if newcode and okay then + self.extra.code = newcode + self:load_code(newcode) + end + end, + + activate = function (self) + self:run_in_localenv "activate" + end, + + create = function (d, tab, settings) + tab.ninputs = settings and settings.ninputs + tab.noutputs = settings and settings.noutputs + tab.otype = dalos.objtype.LUA_FILTER + tab.configure = dalosp.luafilter.configure + tab.activate = dalosp.luafilter.activate + tab.input_change = dalosp.luafilter.input_change + tab.default_name = "Lua Filter" + tab.get_settings = dalosp.luafilter.get_settings + tab.ntype = "Lua Filter" + tab.gen_template = dalosp.luafilter.gen_template + tab.apply_template = dalosp.luafilter.apply_template + local extra = { localenv = {} } + extra.code = settings and settings.code + if not extra.code or extra.code == "" then extra.code = dalosp.luafilter.default_code end + local s = true + while not s and not tab.ninputs or not tab.noutputs do + s, tab.ninputs, tab.noutputs = iup.GetParam("Lua Filter", nil, "Inputs number: %i\nOutputs number: %i\n", 1, 1) + end + + local obj = dalos.object(d, tab, extra) + + obj.load_code = dalosp.luafilter.load_code + obj.run_in_localenv = dalosp.luafilter.run_in_localenv + obj:load_code(extra.code) + + return obj + end, + + register_template = function (data, tname) + dalosp.luafilters.templates[tname] = data + end, +} + +dalos.luafilter = dalosp.luafilter.create +dalos:register_obj("Lua Filter", dalos.luafilter, "Programmable", dalosp.luafilter.register_template) |