summaryrefslogtreecommitdiff
path: root/dalos-luafilter.lua
diff options
context:
space:
mode:
Diffstat (limited to 'dalos-luafilter.lua')
-rw-r--r--dalos-luafilter.lua174
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)