603 lines
15 KiB
Lua
603 lines
15 KiB
Lua
local basaltEvent = require("basaltEvent")()
|
|
local baseObjects = require("loadObjects")
|
|
local moddedObjects
|
|
local pluginSystem = require("plugin")
|
|
local utils = require("utils")
|
|
local log = require("basaltLogs")
|
|
local uuid = utils.uuid
|
|
local wrapText = utils.wrapText
|
|
local count = utils.tableCount
|
|
local moveThrottle = 300
|
|
local dragThrottle = 0
|
|
local renderingThrottle = 0
|
|
local newObjects = {}
|
|
|
|
local baseTerm = term.current()
|
|
local version = "1.7.0"
|
|
|
|
local projectDirectory = fs.getDir(table.pack(...)[2] or "")
|
|
|
|
local activeKey, frames, monFrames, variables, schedules = {}, {}, {}, {}, {}
|
|
local mainFrame, activeFrame, focusedObject, updaterActive
|
|
|
|
local basalt = {}
|
|
|
|
if not term.isColor or not term.isColor() then
|
|
error('Basalt requires an advanced (golden) computer to run.', 0)
|
|
end
|
|
|
|
local defaultColors = {}
|
|
for k,v in pairs(colors)do
|
|
if(type(v)=="number")then
|
|
defaultColors[k] = {baseTerm.getPaletteColor(v)}
|
|
end
|
|
end
|
|
|
|
|
|
local function stop()
|
|
updaterActive = false
|
|
baseTerm.clear()
|
|
baseTerm.setCursorPos(1, 1)
|
|
for k,v in pairs(colors)do
|
|
if(type(v)=="number")then
|
|
baseTerm.setPaletteColor(v, colors.packRGB(table.unpack(defaultColors[k])))
|
|
end
|
|
end
|
|
end
|
|
|
|
local function schedule(f)
|
|
assert(f~="function", "Schedule needs a function in order to work!")
|
|
return function(...)
|
|
local co = coroutine.create(f)
|
|
local ok, result = coroutine.resume(co, ...)
|
|
if(ok)then
|
|
table.insert(schedules, co)
|
|
else
|
|
basalt.basaltError(result)
|
|
end
|
|
end
|
|
end
|
|
|
|
basalt.log = function(...)
|
|
log(...)
|
|
end
|
|
|
|
local setVariable = function(name, var)
|
|
variables[name] = var
|
|
end
|
|
|
|
local getVariable = function(name)
|
|
return variables[name]
|
|
end
|
|
|
|
local getObjects = function()
|
|
return moddedObjects
|
|
end
|
|
|
|
local getObject = function(objectName)
|
|
return getObjects()[objectName]
|
|
end
|
|
|
|
local createObject = function(basalt, objectName, id)
|
|
return getObject(objectName)(id, basalt)
|
|
end
|
|
|
|
local bInstance = {
|
|
getDynamicValueEventSetting = function()
|
|
return basalt.dynamicValueEvents
|
|
end,
|
|
|
|
getMainFrame = function()
|
|
return mainFrame
|
|
end,
|
|
|
|
setVariable = setVariable,
|
|
getVariable = getVariable,
|
|
|
|
setMainFrame = function(mFrame)
|
|
mainFrame = mFrame
|
|
end,
|
|
|
|
getActiveFrame = function()
|
|
return activeFrame
|
|
end,
|
|
|
|
setActiveFrame = function(aFrame)
|
|
activeFrame = aFrame
|
|
end,
|
|
|
|
getFocusedObject = function()
|
|
return focusedObject
|
|
end,
|
|
|
|
setFocusedObject = function(focused)
|
|
focusedObject = focused
|
|
end,
|
|
|
|
getMonitorFrame = function(name)
|
|
return monFrames[name] or monGroups[name][1]
|
|
end,
|
|
|
|
setMonitorFrame = function(name, frame, isGroupedMon)
|
|
if(mainFrame == frame)then mainFrame = nil end
|
|
if(isGroupedMon)then
|
|
monGroups[name] = {frame, sides}
|
|
else
|
|
monFrames[name] = frame
|
|
end
|
|
if(frame==nil)then
|
|
monGroups[name] = nil
|
|
end
|
|
end,
|
|
|
|
getTerm = function()
|
|
return baseTerm
|
|
end,
|
|
|
|
schedule = schedule,
|
|
|
|
stop = stop,
|
|
debug = basalt.debug,
|
|
log = basalt.log,
|
|
|
|
getObjects = getObjects,
|
|
|
|
getObject = getObject,
|
|
|
|
createObject = createObject,
|
|
|
|
getDirectory = function()
|
|
return projectDirectory
|
|
end
|
|
}
|
|
|
|
local function defaultErrorHandler(errMsg)
|
|
baseTerm.clear()
|
|
baseTerm.setBackgroundColor(colors.black)
|
|
baseTerm.setTextColor(colors.red)
|
|
local w,h = baseTerm.getSize()
|
|
if(basalt.logging)then
|
|
log(errMsg, "Error")
|
|
end
|
|
|
|
local text = wrapText("Basalt error: "..errMsg, w)
|
|
local yPos = 1
|
|
for _,v in pairs(text)do
|
|
baseTerm.setCursorPos(1,yPos)
|
|
baseTerm.write(v)
|
|
yPos = yPos + 1
|
|
end
|
|
baseTerm.setCursorPos(1,yPos+1)
|
|
updaterActive = false
|
|
end
|
|
|
|
local function handleSchedules(event, p1, p2, p3, p4)
|
|
if(#schedules>0)then
|
|
local finished = {}
|
|
for n=1,#schedules do
|
|
if(schedules[n]~=nil)then
|
|
if (coroutine.status(schedules[n]) == "suspended")then
|
|
local ok, result = coroutine.resume(schedules[n], event, p1, p2, p3, p4)
|
|
if not(ok)then
|
|
basalt.basaltError(result)
|
|
end
|
|
else
|
|
table.insert(finished, n)
|
|
end
|
|
end
|
|
end
|
|
for n=1,#finished do
|
|
table.remove(schedules, finished[n]-(n-1))
|
|
end
|
|
end
|
|
end
|
|
|
|
local function drawFrames()
|
|
if(updaterActive==false)then return end
|
|
if(mainFrame~=nil)then
|
|
mainFrame:render()
|
|
mainFrame:updateTerm()
|
|
end
|
|
for _,v in pairs(monFrames)do
|
|
v:render()
|
|
v:updateTerm()
|
|
end
|
|
end
|
|
|
|
local stopped, moveX, moveY = nil, nil, nil
|
|
local moveTimer = nil
|
|
local function mouseMoveEvent(_, stp, x, y)
|
|
stopped, moveX, moveY = stp, x, y
|
|
if(moveTimer==nil)then
|
|
moveTimer = os.startTimer(moveThrottle/1000)
|
|
end
|
|
end
|
|
|
|
local function moveHandlerTimer()
|
|
moveTimer = nil
|
|
mainFrame:hoverHandler(moveX, moveY, stopped)
|
|
activeFrame = mainFrame
|
|
end
|
|
|
|
local btn, dragX, dragY = nil, nil, nil
|
|
local dragTimer = nil
|
|
local function dragHandlerTimer()
|
|
dragTimer = nil
|
|
mainFrame:dragHandler(btn, dragX, dragY)
|
|
activeFrame = mainFrame
|
|
end
|
|
|
|
local function mouseDragEvent(_, b, x, y)
|
|
btn, dragX, dragY = b, x, y
|
|
if(dragThrottle<50)then
|
|
dragHandlerTimer()
|
|
else
|
|
if(dragTimer==nil)then
|
|
dragTimer = os.startTimer(dragThrottle/1000)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local renderingTimer = nil
|
|
local function renderingUpdateTimer()
|
|
renderingTimer = nil
|
|
drawFrames()
|
|
end
|
|
|
|
local function renderingUpdateEvent(timer)
|
|
if(renderingThrottle<50)then
|
|
drawFrames()
|
|
else
|
|
if(renderingTimer==nil)then
|
|
renderingTimer = os.startTimer(renderingThrottle/1000)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function basaltUpdateEvent(event, ...)
|
|
local a = {...}
|
|
if(basaltEvent:sendEvent("basaltEventCycle", event, ...)==false)then return end
|
|
if(event=="terminate")then basalt.stop() end
|
|
if(mainFrame~=nil)then
|
|
local mouseEvents = {
|
|
mouse_click = mainFrame.mouseHandler,
|
|
mouse_up = mainFrame.mouseUpHandler,
|
|
mouse_scroll = mainFrame.scrollHandler,
|
|
mouse_drag = mouseDragEvent,
|
|
mouse_move = mouseMoveEvent,
|
|
}
|
|
local mouseEvent = mouseEvents[event]
|
|
if(mouseEvent~=nil)then
|
|
mouseEvent(mainFrame, ...)
|
|
handleSchedules(event, ...)
|
|
renderingUpdateEvent()
|
|
return
|
|
end
|
|
end
|
|
|
|
if(event == "monitor_touch") then
|
|
for k,v in pairs(monFrames)do
|
|
if(v:mouseHandler(1, a[2], a[3], true, a[1]))then
|
|
activeFrame = v
|
|
end
|
|
end
|
|
handleSchedules(event, ...)
|
|
renderingUpdateEvent()
|
|
return
|
|
end
|
|
|
|
if(activeFrame~=nil)then
|
|
local keyEvents = {
|
|
char = activeFrame.charHandler,
|
|
key = activeFrame.keyHandler,
|
|
key_up = activeFrame.keyUpHandler,
|
|
}
|
|
local keyEvent = keyEvents[event]
|
|
if(keyEvent~=nil)then
|
|
if(event == "key")then
|
|
activeKey[a[1]] = true
|
|
elseif(event == "key_up")then
|
|
activeKey[a[1]] = false
|
|
end
|
|
keyEvent(activeFrame, ...)
|
|
handleSchedules(event, ...)
|
|
renderingUpdateEvent()
|
|
return
|
|
end
|
|
end
|
|
|
|
if(event=="timer")and(a[1]==moveTimer)then
|
|
moveHandlerTimer()
|
|
elseif(event=="timer")and(a[1]==dragTimer)then
|
|
dragHandlerTimer()
|
|
elseif(event=="timer")and(a[1]==renderingTimer)then
|
|
renderingUpdateTimer()
|
|
else
|
|
for _, v in pairs(frames) do
|
|
v:eventHandler(event, ...)
|
|
end
|
|
for _, v in pairs(monFrames) do
|
|
v:eventHandler(event, ...)
|
|
end
|
|
handleSchedules(event, ...)
|
|
renderingUpdateEvent()
|
|
end
|
|
end
|
|
|
|
local loadedObjects = false
|
|
local loadedPlugins = false
|
|
local function InitializeBasalt()
|
|
if not(loadedObjects)then
|
|
for _,v in pairs(newObjects)do
|
|
if(fs.exists(v))then
|
|
if(fs.isDir(v))then
|
|
local files = fs.list(v)
|
|
for _,object in pairs(files)do
|
|
if not(fs.isDir(v.."/"..object))then
|
|
local name = object:gsub(".lua", "")
|
|
if(name~="example.lua")and not(name:find(".disabled"))then
|
|
if(baseObjects[name]==nil)then
|
|
baseObjects[name] = require(v.."."..object:gsub(".lua", ""))
|
|
else
|
|
error("Duplicate object name: "..name)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
local name = v:gsub(".lua", "")
|
|
if(baseObjects[name]==nil)then
|
|
baseObjects[name] = require(name)
|
|
else
|
|
error("Duplicate object name: "..name)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
loadedObjects = true
|
|
end
|
|
if not(loadedPlugins)then
|
|
moddedObjects = pluginSystem.loadPlugins(baseObjects, bInstance)
|
|
local basaltPlugins = pluginSystem.get("basalt")
|
|
if(basaltPlugins~=nil)then
|
|
for k,v in pairs(basaltPlugins)do
|
|
for a,b in pairs(v(basalt))do
|
|
basalt[a] = b
|
|
bInstance[a] = b
|
|
end
|
|
end
|
|
end
|
|
local basaltPlugins = pluginSystem.get("basaltInternal")
|
|
if(basaltPlugins~=nil)then
|
|
for _,v in pairs(basaltPlugins)do
|
|
for a,b in pairs(v(basalt))do
|
|
bInstance[a] = b
|
|
end
|
|
end
|
|
end
|
|
loadedPlugins = true
|
|
end
|
|
end
|
|
|
|
local function createFrame(name)
|
|
InitializeBasalt()
|
|
for _, v in pairs(frames) do
|
|
if (v:getName() == name) then
|
|
return nil
|
|
end
|
|
end
|
|
local newFrame = moddedObjects["BaseFrame"](name, bInstance)
|
|
newFrame:init()
|
|
newFrame:load()
|
|
newFrame:draw()
|
|
table.insert(frames, newFrame)
|
|
if(mainFrame==nil)and(newFrame:getName()~="basaltDebuggingFrame")then
|
|
newFrame:show()
|
|
end
|
|
return newFrame
|
|
end
|
|
|
|
basalt = {
|
|
basaltError = defaultErrorHandler,
|
|
logging = false,
|
|
dynamicValueEvents = false,
|
|
drawFrames = drawFrames,
|
|
log = log,
|
|
getVersion = function()
|
|
return version
|
|
end,
|
|
|
|
memory = function()
|
|
return math.floor(collectgarbage("count")+0.5).."KB"
|
|
end,
|
|
|
|
addObject = function(path)
|
|
if(fs.exists(path))then
|
|
table.insert(newObjects, path)
|
|
end
|
|
end,
|
|
|
|
addPlugin = function(path)
|
|
pluginSystem.addPlugin(path)
|
|
end,
|
|
|
|
getAvailablePlugins = function()
|
|
return pluginSystem.getAvailablePlugins()
|
|
end,
|
|
|
|
getAvailableObjects = function()
|
|
local objectNames = {}
|
|
for k,_ in pairs(baseObjects)do
|
|
table.insert(objectNames, k)
|
|
end
|
|
return objectNames
|
|
end,
|
|
|
|
setVariable = setVariable,
|
|
getVariable = getVariable,
|
|
|
|
getObjects = getObjects,
|
|
getObject = getObject,
|
|
|
|
createObject = createObject,
|
|
|
|
setBaseTerm = function(_baseTerm)
|
|
baseTerm = _baseTerm
|
|
end,
|
|
|
|
resetPalette = function()
|
|
for k,v in pairs(colors)do
|
|
if(type(v)=="number")then
|
|
--baseTerm.setPaletteColor(v, colors.packRGB(table.unpack(defaultColors[k])))
|
|
end
|
|
end
|
|
end,
|
|
|
|
setMouseMoveThrottle = function(amount)
|
|
if(_HOST:find("CraftOS%-PC"))then
|
|
if(config.get("mouse_move_throttle")~=10)then config.set("mouse_move_throttle", 10) end
|
|
if(amount<100)then
|
|
moveThrottle = 100
|
|
else
|
|
moveThrottle = amount
|
|
end
|
|
return true
|
|
end
|
|
return false
|
|
end,
|
|
|
|
setRenderingThrottle = function(amount)
|
|
if(amount<=0)then
|
|
renderingThrottle = 0
|
|
else
|
|
renderingTimer = nil
|
|
renderingThrottle = amount
|
|
end
|
|
end,
|
|
|
|
setMouseDragThrottle = function(amount)
|
|
if(amount<=0)then
|
|
dragThrottle = 0
|
|
else
|
|
dragTimer = nil
|
|
dragThrottle = amount
|
|
end
|
|
end,
|
|
|
|
autoUpdate = function(isActive)
|
|
updaterActive = isActive
|
|
if(isActive==nil)then updaterActive = true end
|
|
local function f()
|
|
drawFrames()
|
|
while updaterActive do
|
|
basaltUpdateEvent(os.pullEventRaw())
|
|
end
|
|
end
|
|
while updaterActive do
|
|
local ok, err = xpcall(f, debug.traceback)
|
|
if not(ok)then
|
|
basalt.basaltError(err)
|
|
end
|
|
end
|
|
end,
|
|
|
|
update = function(event, ...)
|
|
if (event ~= nil) then
|
|
local args = {...}
|
|
local ok, err = xpcall(function() basaltUpdateEvent(event, table.unpack(args)) end, debug.traceback)
|
|
if not(ok)then
|
|
basalt.basaltError(err)
|
|
return
|
|
end
|
|
end
|
|
end,
|
|
|
|
stop = stop,
|
|
stopUpdate = stop,
|
|
|
|
isKeyDown = function(key)
|
|
if(activeKey[key]==nil)then return false end
|
|
return activeKey[key];
|
|
end,
|
|
|
|
getFrame = function(name)
|
|
for _, value in pairs(frames) do
|
|
if (value.name == name) then
|
|
return value
|
|
end
|
|
end
|
|
end,
|
|
|
|
getActiveFrame = function()
|
|
return activeFrame
|
|
end,
|
|
|
|
setActiveFrame = function(frame)
|
|
if (frame:getType() == "Container") then
|
|
activeFrame = frame
|
|
return true
|
|
end
|
|
return false
|
|
end,
|
|
|
|
getMainFrame = function()
|
|
return mainFrame
|
|
end,
|
|
|
|
onEvent = function(...)
|
|
for _,v in pairs(table.pack(...))do
|
|
if(type(v)=="function")then
|
|
basaltEvent:registerEvent("basaltEventCycle", v)
|
|
end
|
|
end
|
|
end,
|
|
|
|
schedule = schedule,
|
|
|
|
addFrame = createFrame,
|
|
createFrame = createFrame,
|
|
|
|
addMonitor = function(name)
|
|
InitializeBasalt()
|
|
for _, v in pairs(frames) do
|
|
if (v:getName() == name) then
|
|
return nil
|
|
end
|
|
end
|
|
local newFrame = moddedObjects["MonitorFrame"](name, bInstance)
|
|
newFrame:init()
|
|
newFrame:load()
|
|
newFrame:draw()
|
|
table.insert(monFrames, newFrame)
|
|
return newFrame
|
|
end,
|
|
|
|
removeFrame = function(name)
|
|
frames[name] = nil
|
|
end,
|
|
|
|
setProjectDir = function(dir)
|
|
projectDirectory = dir
|
|
end,
|
|
}
|
|
|
|
local basaltPlugins = pluginSystem.get("basalt")
|
|
if(basaltPlugins~=nil)then
|
|
for k,v in pairs(basaltPlugins)do
|
|
for a,b in pairs(v(basalt))do
|
|
basalt[a] = b
|
|
bInstance[a] = b
|
|
end
|
|
end
|
|
end
|
|
local basaltPlugins = pluginSystem.get("basaltInternal")
|
|
if(basaltPlugins~=nil)then
|
|
for k,v in pairs(basaltPlugins)do
|
|
for a,b in pairs(v(basalt))do
|
|
bInstance[a] = b
|
|
end
|
|
end
|
|
end
|
|
|
|
return basalt |