Skip to content
Permalink
main
Go to file
 
 
Cannot retrieve contributors at this time
239 lines (198 sloc) 5.9 KB
--- Script class
-- @module script
local Script = {}
--- reset script environment.
-- ie redirect draw, key, enc functions, stop timers, clear engine, etc.
Script.clear = function()
print("# script clear")
-- script local state
local state = { }
setmetatable(_G, {
__index = function (_,k)
return state[k]
end,
__newindex = function(_,k,v)
state[k] = v
end,
})
-- reset cleanup script
cleanup = norns.none
-- reset oled redraw
redraw = norns.blank
-- redirect inputs to nowhere
key = norns.none
enc = norns.none
-- reset encoders
norns.enc.accel(0,true)
norns.enc.sens(0,2)
-- clear, redirect, and reset devices
grid.cleanup()
arc.cleanup()
midi.cleanup()
hid.cleanup()
-- stop all timers
metro.free_all()
-- stop clock
clock.cleanup()
-- stop all polls and clear callbacks
poll.clear_all()
-- clear engine
engine.name = nil
-- clear softcut
softcut.reset()
-- clear init
init = norns.none
-- clear crow functions
crow.init()
-- clear keyboard handlers
keyboard.clear()
-- clear last run
norns.state.script = ''
norns.state.name = 'none'
norns.state.shortname = 'none'
norns.state.path = _path["dust"]
norns.state.data = _path.data
norns.state.lib = norns.state.path
-- clear params
params:clear()
norns.pmap.clear()
-- add audio menu
audio.add_params()
-- add clock menu
clock.add_params()
-- re-enable crow clock if needed
if params:string("clock_source") == "crow" then
crow.input[1].change = function() end
crow.input[1].mode("change",2,0.1,"rising")
end
-- reset PLAY mode screen settings
local status = norns.menu.status()
if status == true then _norns.screen_restore() end
screen.aa(0)
screen.level(15)
screen.line_width(1)
screen.font_face(1)
screen.font_size(8)
if status == true then _norns.screen_save() end
-- ensure finalizers run before next script
collectgarbage()
end
Script.init = function()
print("# script init")
params.name = norns.state.shortname
init()
_norns.screen_save()
end
--- load a script from the /scripts folder.
-- @tparam string filename file to load. leave blank to reload current file.
Script.load = function(filename)
local name, path
if filename == nil then
filename = norns.state.script
name = norns.state.name
path = norns.state.path
else
filename = string.sub(filename,1,1) == "/" and filename or _path["dust"]..filename
path, scriptname = filename:match("^(.*)/([^.]*).*$")
name = string.sub(path, string.len(_path["code"]) + 1)
-- append scriptname to the name if it doesn't match directory name in case multiple scripts reside in the same directory
-- ex: we/study/study1, we/study/study2, ...
if string.sub(name, -#scriptname) ~= scriptname then
name_parts = tab.split(name, "/")
table.insert(name_parts, scriptname)
name = table.concat(name_parts, "/")
end
end
print("# script load: " .. filename)
local f=io.open(filename,"r")
if f==nil then
print("file not found: "..filename)
else
io.close(f)
local ok, err
ok, err = pcall(cleanup)
if ok then print("# cleanup")
else
print("### cleanup failed with error: "..err)
end
-- unload asl package entry so `require 'asl'` works
-- todo(pq): why is this not needed generally (e.g., for 'ui', 'util', etc.)?
if package.loaded['asl'] ~= nil then
package.loaded['asl'] = nil
end
Script.clear() -- clear script variables and functions
norns.state.script = filename
norns.state.name = name
norns.state.shortname = norns.state.name:match( "([^/]+)$" )
norns.state.path = path .. '/'
norns.state.lib = path .. '/lib/'
norns.state.data = _path.data .. name .. '/'
norns.state.pset_last = 1
if util.file_exists(norns.state.data) == false then
print("### initializing data folder")
util.make_dir(norns.state.data)
if util.file_exists(norns.state.path.."/data") then
os.execute("cp "..norns.state.path.."/data/*.pset "..norns.state.data)
print("### copied default psets")
end
end
local file = norns.state.data.."pset-last.txt"
if util.file_exists(file) then
local f = io.open(file,"r")
io.input(f)
local i = io.read("*line")
io.close(f)
if i then
print("pset last used: "..i)
norns.state.pset_last = tonumber(i)
end
end
local status = norns.try(function() dofile(filename) end, "load fail") -- do the new script
if status == true then
norns.state.save() -- remember this script for next launch
norns.script.nointerface = redraw == norns.blank -- check if redraw is present
norns.script.redraw = redraw -- store redraw function for context switching
redraw = norns.none -- block redraw until Script.init
Script.run() -- load engine then run script-specified init function
else
Script.clear()
end
end
end
--- load engine, execute script-specified init (if present).
Script.run = function()
print("# script run")
if engine.name ~= nil then
print("loading engine: " .. engine.name)
engine.load(engine.name, Script.init)
else
engine.load("None", Script.init)
end
norns.pmap.read() -- load parameter map
end
--- load script metadata.
-- @tparam string filename file to load
-- @treturn table meta table with metadata
Script.metadata = function(filename)
local meta = {}
local f=io.open(filename,"r")
if f==nil then
print("file not found: "..filename)
else
io.close(f)
for line in io.lines(filename) do
if util.string_starts(line,"--") then
local skip_hyphens = string.sub(line,4,-1)
local fix_newlines = string.gsub(skip_hyphens,"\r$","")
table.insert(meta, fix_newlines)
else
if #meta == 0 then
table.insert(meta, "no script information")
end
return meta
end
end
end
return meta
end
return Script