1
Lua / Multi-tabbed programs
« on: September 04, 2011, 12:00:28 am »
I was experimenting with ways to have multiple lua scripts communicate with each other. Despite TI's best efforts, it turns out there is a fairly easy way to do it.
using var.store, var.recall, var.monitor, and on.varChage, you can implement full communication between lua scripts. Using a list of lists ([[to,from,data],[to,from,data]]) you can even implement a basic network stack. (Sort of) Anyway, I made a quick prototype that sort of demonstrates this using oclua. Just put the master program in one tab and the modified onclue in another. onclua should work pretty much as normal, (on.varChange and on.create aren't working for the target program yet) but when a program is running and you press enter on master, onclua will stop execution.
master:
oclua:
Using a stack like this, complex applications could be made. One idea that came to mind was an IDE that would actually run your code in another tab, keeping the namespace clean in the editor tab. Also, bby having multiple apps in one tab, you could even add run controls at the top, allowing for very easy application development and testing, even on the go.
using var.store, var.recall, var.monitor, and on.varChage, you can implement full communication between lua scripts. Using a list of lists ([[to,from,data],[to,from,data]]) you can even implement a basic network stack. (Sort of) Anyway, I made a quick prototype that sort of demonstrates this using oclua. Just put the master program in one tab and the modified onclue in another. onclua should work pretty much as normal, (on.varChange and on.create aren't working for the target program yet) but when a program is running and you press enter on master, onclua will stop execution.
master:
Code: [Select]
function on.create()
var.store("transfer","")
end
function on.enterKey()
var.store("transfer",var.recall("transfer").."E")
end
oclua:
Code: [Select]
__oc = {} -- protected scope for all global variables, not to conflict with the programs run
toolpalette.register({})
toolpalette.enablePaste(true)
__oc.NEVER_RUN_CODE = true
function __oc.copy_table(t)
local t2 = {}
for k,v in pairs(t) do
t2[k] = v
end
return t2
end
function __oc.trim(s)
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
end
function __oc.loadcode(code)
__oc.ERR = nil
local chunk, errload = loadstring(code)
if not chunk then
__oc.ERR = errload
platform.window:invalidate()
else
on = {} -- to find out which one are redefined
local status, errcall = pcall(chunk)
if not status then
__oc.ERR = errcall
else
__oc.NEVER_RUN_CODE = false
end
platform.window:invalidate()
__oc.reload_handlers()
end
end
function __oc.reload_handlers()
__oc.on = __oc.copy_table(on) -- those defined by the program
on.paste = function() -- cannot be redefined
if clipboard.getText() then
__oc.loadcode(clipboard.getText())
end
end
on.paint = function(gc)
if __oc.ERR then
gc:setFont("sansserif", "r", 8)
local maxchars, y = 60, 10
for i = 1, #(__oc.ERR), maxchars do
gc:drawString(__oc.trim(string.sub(__oc.ERR, i, i + maxchars - 1)), 0, y)
y = y + 10
end
else
if __oc.on.paint then
__oc.on.paint(gc)
end
end
if __oc.ERR or __oc.NEVER_RUN_CODE then
gc:setFont("sansserif", "r", 8)
gc:drawString("Paste some Lua code here to run it", 85, 210)
end
end
on.create = function()
var.monitor("transfer")
end
on.varChange = function(list)
__oc.ERR = nil
__oc.NEVER_RUN_CODE = true
__oc.on.paint = nil
platform.window:invalidate()
return 0
end
end
__oc.reload_handlers()
Using a stack like this, complex applications could be made. One idea that came to mind was an IDE that would actually run your code in another tab, keeping the namespace clean in the editor tab. Also, bby having multiple apps in one tab, you could even add run controls at the top, allowing for very easy application development and testing, even on the go.