This commit is contained in:
sfokin 2025-03-28 14:01:18 +03:00
commit 15d1752602
6 changed files with 1115 additions and 0 deletions

41
fabric_hive_processor.lua Normal file
View File

@ -0,0 +1,41 @@
if event.type == "program" then
mem.state = "lag_remove"
interrupt(1)
end
if event.type == "interrupt" then
if mem.state == "lag_remove" then
mem.state = "grab"
port.b = false
port.a = false
port.c = false
interrupt(20)
elseif mem.state == "grab" then
local count = mem.count or 0
mem.count = count + 1
digiline_send("monhive", "Hives\nprocessed:\n"..tostring(mem.count).."\n\n\n\n")
mem.state = "grab_end"
port.a = true
port.b = true
interrupt(1)
elseif mem.state == "grab_end" then
mem.state = "put_hive"
port.a = false
port.b = false
interrupt(10)
elseif mem.state == "put_hive" then
mem.state = "put_hive_end"
port.a = false
port.c = true
interrupt(1)
elseif mem.state == "put_hive_end" then
mem.state = "lag_remove"
port.a = false
port.c = false
interrupt(100)
end
end
if event.type == "digiline" then
end

View File

@ -0,0 +1,120 @@
function handleChestEvents(event)
if event.msg.event == nil then
handleChestGet_list(event)
end
if event.msg.event == "inject" then
--handle inject event
end
end
function handleChestGet_list(event)
local itemName = ""
local itemCount = 0
if mem.buttonState ~= 1 then
return
end
if event.msg ~= nil then
--for k, v in pairs(event.msg) do
for i = #event.msg, 1, -1 do
local v = event.msg[i]
if v ~= nil and type(v) == "string" and v ~= "technic:uranium35_dustthen" then
local spaceIndex = string.find(v, " ", 1, true)
if spaceIndex ~= nil then
itemName = string.sub(v, 1, spaceIndex -1)
itemCount = string.sub(v, spaceIndex + 1)
if tonumber(itemCount) >= 2 then
digiline_send("injector", {name=itemName, count = 2, tags=itemName})
break
end
end
end
end
end
mem.itemName = itemName
mem.itemCount = itemCount
end
function handleButtonEvents(event)
if mem.buttonState == 0 then
mem.buttonState = 1
digiline_send("uranbutton", "light_on")
digiline_send("uranchest",{command="sort"})
digiline_send("uranchest",{command="get_list"})
else
mem.buttonState = 0
digiline_send("uranbutton", "light_off")
mem.outputCount = 0
end
end
function handleDetectorEvents(event)
mem.outputCount = mem.outputCount + event.msg.count
mem.totalProcessed = mem.totalProcessed + event.msg.count
if mem.outputCount >= 2 then
mem.outputCount = 0
local str = "Uran fissiletotal items\nprocessed:\n" ..
tostring(mem.totalProcessed) .. "\n" ..
"Fuels done\n" ..
tostring(mem.fuelDone) ..
"\n"
digiline_send("uranmonitor", str)
if mem.buttonState == 1 then
digiline_send("uranchest",{command="sort"})
digiline_send("uranchest",{command="get_list"})
end
end
end
function logDigilineEvents(event)
local digilineEvents = {}
if mem.digilineEvents ~= nil then
digilineEvents = mem.digilineEvents
end
table.insert(digilineEvents, event)
mem.digilineEvents = digilineEvents
end
if event.type == "program" then
mem={}
mem.buttonState = 0
mem.outputCount = 0
if mem.totalProcessed == nill then
mem.totalProcessed = 0
end
if mem.fuelDone == nill then
mem.fuelDone = 0
end
digiline_send("uranchest",{command="sort"})
digiline_send("uranbutton", "light_off")
-- interrupt(1)
end
if event.type == "interrupt" then
end
if event.type == "digiline" then
if event ~= nil then
--logDigilineEvents(event)
end
if event.channel == "uranbutton" then
handleButtonEvents(event)
end
if event.channel == "urandetector" then
handleDetectorEvents(event)
end
if event.channel == "nuclearfueldetector" then
mem.fuelDone = mem.fuelDone + 1
end
if mem.buttonState ~= 1 then
return
end
if (event.channel == "uranchest") then
handleChestEvents(event)
end
end

65
fabric_power_monitor.lua Normal file
View File

@ -0,0 +1,65 @@
if event.type == "interrupt" then
digiline_send("pmw","get")
local str = "Powev MV\n" ..
"S:" .. tostring(mem.supply) .."\n" ..
"D:" .. tostring(mem.demand) .. "\n" ..
"Battery:" .. tostring(mem.bcount) .. "\n" ..
"BC:" .. tostring(mem.bc) .. "\n" .. "BCM:" .. tostring(mem.bcm)
digiline_send("monpoww", str)
digiline_send("pmhv","get")
str = "Powev HV\n" ..
"S:" .. tostring(mem.hvsupply) .. "\n" ..
"D:" .. tostring(mem.hvdemand) .. "\n" ..
"Battery:" .. tostring(mem.hvbcount) .. "\n" ..
"BC:" .. tostring(mem.hvbc) .. "\n" ..
"BCM:" .. tostring(mem.hvbcm)
digiline_send("monpowhv", str)
digiline_send("nuclear", "get")
str = "Nuclear\n" ..
"Siren:" .. tostring(mem.n_siren) .. "\n" ..
"Burn:" .. tostring(mem.n_burnTime) .. "\n" ..
"Rods:\n"
if type(mem.n_rods) == "table" then
str = str .. tostring(mem.n_rods[1] or 0) .. " " ..
tostring(mem.n_rods[2] or 0) .. " " ..
tostring(mem.n_rods[3] or 0) .. "\n" ..
tostring(mem.n_rods[4] or 0) .. " " ..
tostring(mem.n_rods[5] or 0) .. " " ..
tostring(mem.n_rods[6] or 0)
end
digiline_send("monnuclear", str )
interrupt(10)
end
if event.type == "program" then
mem.nrods = {0, 0, 0, 0, 0, 0, 0}
digiline_send("pmw", "get")
digiline_send("pmhv", "get")
digiline_send("nuclear", "get")
interrupt(1)
end
if event.type == "digiline" then
if event.channel == "pmw" then
mem.supply = event.msg.supply
mem.demand = event.msg.demand
mem.bc = event.msg.battery_charge
mem.bcm = event.msg.battery_charge_max
mem.bcount = event.msg.battery_count
end
if event.channel == "pmhv" then
mem.hvsupply = event.msg.supply
mem.hvdemand = event.msg.demand
mem.hvbc = event.msg.battery_charge
mem.hvbcm = event.msg.battery_charge_max
mem.hvbcount = event.msg.battery_count
end
if event.channel == "nuclear" then
mem.n_burnTime = event.msg.burn_time
mem.n_siren = event.msg.siren
mem.n_rods = event.msg.rods
end
end

View File

@ -0,0 +1,762 @@
--[[
Touch screen designer.
Simple WYSIWYG editor for touch screens.
Can export configuration through digiline
or through touch screen multi line text field.
Author: SX
--]]
local GRID_SIZE = mem.GRID_SIZE and mem.GRID_SIZE or 0.4
local initialize_designer = function()
mem.ALLOW_RESIZE_W = {
addfield = 1,
addpwdfield = 1,
addbutton = 1,
addimage_button = 1,
addtextarea = 1,
addtextlist = 1,
adddropdown = 1,
addimage = 1,
}
mem.ALLOW_RESIZE_H = {
addimage_button = 1,
addtextarea = 1,
addtextlist = 1,
addimage = 1,
}
mem.SELECTABLE_COMPONENTS = {
button = 1,
buttonexit = 1,
imagebutton = 1,
imagebuttonexit = 1,
}
mem.WORKSPACE_CONTROL = {
command = 'addimage_button',
image = 'signs_road_red.png',
name = '_ctrl',
type = 'ctrl',
label = '.',
W = 0.4,
H = 0.4,
}
mem.CTRL_OFFSET = {
addfield = {
X = -0.3,
Y = -0.4,
},
addpwdfield = {
X = -0.3,
Y = -0.4,
},
}
mem.COMPONENT_DEFAULTS = {
button = {
command = 'addbutton',
name = '_button_',
label = 'untitled',
X = 0.8,
Y = 0.8,
W = 1.6,
H = 0.8,
},
buttonexit = {
variant = '_exit',
command = 'addbutton',
name = '_buttonexit_',
label = 'untitled',
X = 0.8,
Y = 0.8,
W = 1.6,
H = 0.8,
},
imagebutton = {
command = 'addimage_button',
name = "_imagebutton_",
label = "untitled",
image = 'wool_yellow.png',
X = 0.8,
Y = 0.8,
W = 1.6,
H = 0.8,
},
imagebuttonexit = {
variant = '_exit',
command = 'addimage_button',
name = "_imagebuttonexit_",
label = "untitled",
image = 'wool_yellow.png',
X = 0.8,
Y = 0.8,
W = 1.6,
H = 0.8,
},
field = {
command = 'addfield',
name = '_field_',
label = 'untitled',
default = 'value',
X = 0.7,
Y = 0.7,
W = 1.6,
H = 0.8,
},
pwdfield = {
command = 'addpwdfield',
name = '_pwdfield_',
label = 'untitled',
X = 0.7,
Y = 0.7,
W = 1.6,
H = 0.8,
},
label = {
command = 'addlabel',
label = 'untitled',
name = '_label_', -- Deleted on export, required for editor
X = 0.7,
Y = 0.7,
W = 1.2, -- Deleted on export, required for editor
H = 0.8, -- Deleted on export, required for editor
},
vertlabel = {
command = 'addvertlabel',
label = 'untitled',
name = '_vertlabel_', -- Deleted on export, required for editor
X = 0.8,
Y = 0.8,
W = 0.8, -- Deleted on export, required for editor
H = 1.2, -- Deleted on export, required for editor
},
textarea = {
command = "addtextarea",
label = "untitled",
name = "_textarea_",
default = 'value',
X = 0.8,
Y = 0.8,
W = 2.6,
H = 1.8,
},
textlist = {
command = "addtextlist",
label = "untitled",
name = "_textlist_",
listelements = {},
transparent = false,
selected_id = 1,
X = 0.8,
Y = 0.8,
W = 2.6,
H = 1.8,
},
dropdown = {
command = "adddropdown",
label = "untitled",
name = "_dropdown_",
choices = {},
selected_id = 1,
X = 0.8,
Y = 0.8,
W = 1.6,
H = 0.8,
},
}
mem.COMPONENT_TYPES = {}
for k,_ in pairs(mem.COMPONENT_DEFAULTS) do
table.insert(mem.COMPONENT_TYPES, k)
end
end
local ALLOW_RESIZE_W = mem.ALLOW_RESIZE_W
local ALLOW_RESIZE_H = mem.ALLOW_RESIZE_H
local SELECTABLE_COMPONENTS = mem.SELECTABLE_COMPONENTS
local WORKSPACE_CONTROL = mem.WORKSPACE_CONTROL
local CTRL_OFFSET = mem.CTRL_OFFSET
local COMPONENT_DEFAULTS = mem.COMPONENT_DEFAULTS
local COMPONENT_TYPES = mem.COMPONENT_TYPES
local draw_designer = function()
local ui = {
{
command = "addbutton_exit", X=9.6, Y=-0.31, W=0.7, H=0.7,
name = "quit", label = "X"
},
}
if mem.draw_code then
digiline_send("touch", mem.touch_clear_commands)
table.insert(ui, {
command = "addbutton", X=9.5, Y=0.49, W=0.8, H=0.8,
name = "close_code", label = "[[>"
})
table.insert(ui, {
command = "addtextarea", X=0.5, Y=0.5, W=9, H=8.5,
name = "result", label = "Generated Touch Screen configuration code", default = mem.code
})
else
table.insert(ui, {
command = "addbutton", X=mem.draw_toolbar and 9.45 or 9.65, Y=0.5, W=mem.draw_toolbar and 0.85 or 0.65, H=0.8,
name = "hide_toolbar", label = mem.draw_toolbar and "[[>" or "<]]"
})
if not mem.draw_component_editor and mem.draw_workspace then
digiline_send("touch", mem.workspace)
else
digiline_send("touch", { command = "clear" })
end
if mem.draw_toolbar then
-- Static toolbar components
digiline_send("touch", mem.toolbar)
-- Dynamic toolbar components
digiline_send("touch", {
{
command = "addbutton", X=8.45, Y=0.5, W=0.7, H=0.8,
name = "toggle_grid_size", label = string.format('%.1f', GRID_SIZE)
},{
command = "addbutton", X=8.95, Y=1.2, W=0.7, H=0.8,
name = 'toggle_size_move', label = (mem.mode_move and 'move' or 'size')
},{
command = "addbutton", X=8.45, Y=1.9, W=0.7, H=0.8,
name = "edit_component", label = "edit"
},{
command = "addlabel", X=8.6, Y=3.3,
label = mem.selected.ref and string.format('X:%.1f Y:%.1f\nW:%.1f H:%.1f', mem.selected.ref.X, mem.selected.ref.Y, mem.selected.ref.W, mem.selected.ref.H) or 'No selection'
},{
command = "addfield", X=8.75, Y=4.75, W=1.7, H=0.6,
name = 'component_name', label = 'Ref. key:',
default = mem.selected.display_name and mem.selected.display_name or ''
}
})
--[[
for _,v in pairs(mem.toolbar) do
table.insert(ui, v)
end
table.insert(ui, {
command = "addfield", X=8.6, Y=4.9, W=1.7, H=0.6,
name = 'component_name', label = 'Ref. key:',
default = mem.selected.display_name and mem.selected.display_name or ''
})
--]]
end
if mem.draw_component_editor then
local editor_ui= {
{
command = 'addimage_button',
image = 'wool_red.png', X=2.5, Y=4.5, W=2, H=0.8,
name = "edit_component", label = "Cancel"
},{
command = 'addimage_button',
image = 'wool_green.png', X=4.6, Y=4.5, W=2, H=0.8,
name = 'component_editor_save', label = 'Save'
},
}
local input_y = 3.8
if mem.selected.ref.label then
table.insert(editor_ui, {
command = "addfield", X=2.8, Y=input_y, W=4, H=0.8,
name = 'component_label', label = 'Component label:',
default = mem.selected.ref.label
})
input_y = input_y - 1
end
if mem.selected.ref.default then
table.insert(editor_ui, {
command = "addfield", X=2.8, Y=input_y, W=4, H=0.8,
name = 'component_default', label = 'Default value:',
default = mem.selected.ref.default
})
input_y = input_y - 1
end
if mem.selected.ref.image then
table.insert(editor_ui, {
command = "addfield", X=2.8, Y=input_y, W=4, H=0.8,
name = 'component_image', label = 'Image:',
default = mem.selected.ref.image
})
input_y = input_y - 1
end
if mem.selected.ref.choices or mem.selected.ref.listelements then
table.insert(editor_ui, {
command = "addfield", X=2.8, Y=input_y, W=2.6, H=0.8,
name = 'component_listelement', label = 'New entry:',
default = ''
})
table.insert(editor_ui, {
command = "addbutton", X=5.2, Y=input_y - 0.3, W=0.8, H=0.8,
name = "component_listelement_add", label = 'Add'
})
table.insert(editor_ui, {
command = "addbutton", X=6, Y=input_y - 0.3, W=0.8, H=0.8,
name = "component_listelement_del", label = 'Del'
})
input_y = input_y - 2.6
table.insert(editor_ui, {
command = "addtextlist", X = 2.5, Y = input_y, W = 4, H = 2,
label = "Item editor:",
name = "component_editor_items",
listelements = mem.selected.ref.choices or mem.selected.ref.listelements,
selected_id = mem.component_editor_items_idx or 1,
})
input_y = input_y - 1
end
digiline_send("touch", editor_ui)
end
end
digiline_send("touch", ui)
end
local reset = function()
mem.component_index = {}
for k,_ in pairs(COMPONENT_DEFAULTS) do
mem.component_index[k] = 0
end
mem.workspace = {
{ command = "clear" } -- 'clear' command is special case and not indexed in workspace
}
mem.workspace_search = {}
mem.workspace_control = {}
mem.draw_workspace = true
mem.draw_toolbar = true
mem.draw_code = false
mem.mode_move = true
mem.locked = false
mem.code = ''
mem.selected = {
display_name = nil,
ref = nil,
ctrl = nil
}
-- Add only static controls here, keeping cached in memory reduces table constructors
mem.toolbar = {
{
command = "addbutton", X=8.95, Y=0.5, W=0.7, H=0.8,
name = "up", label = "^"
},{
command = "addbutton", X=8.45, Y=1.2, W=0.7, H=0.8,
name = "left", label = "<"
},{
command = "addbutton", X=9.45, Y=1.2, W=0.7, H=0.8,
name = "right", label = ">"
},{
command = "addbutton", X=8.95, Y=1.9, W=0.7, H=0.8,
name = "down", label = "v"
},{
command = "addbutton", X=9.45, Y=1.9, W=0.7, H=0.8,
name = "delete", label = "del"
},{
command = "addbutton", X=8.45, Y=2.6, W=1.7, H=0.8,
name = "reset", label = "Reset"
},{
command = "addtextlist", X=8.45, Y=5.1, W=1.48, H=1.8,
name="component_type", selected_id=1, listelements = COMPONENT_TYPES
},{
command = "addbutton", X=8.45, Y=6.9, W=1.7, H=0.8,
name = "create", label = "Create"
},{
command = "addbutton", X=8.45, Y=7.6, W=1.7, H=0.8,
name = "code", label = "Generate"
},
}
mem.component_type_id = 1
end
local info = function(msg)
digiline_send('lcd', msg)
end
local validate_component_name = function(name)
return type(name) == 'string' and #name > 0
end
local indexof = function(items, value)
for k,v in pairs(items) do
if v == value then
return k
end
end
return nil
end
local textlist_indexof = function(value)
if #value >= 5 and string.sub(value, 1, 4) == 'CHG:' then
return tonumber(string.sub(value, 5, #value))
end
return nil
end
local update_control_position = function(control, component)
if control then
if CTRL_OFFSET[component.command] then
control.X = component.X + CTRL_OFFSET[component.command].X
control.Y = component.Y + CTRL_OFFSET[component.command].Y
else
control.X = component.X
control.Y = component.Y
end
end
end
local get_next_unused_name = function(component_type, name)
local i = 1
local result = name
local prefix = COMPONENT_DEFAULTS[component_type].name
while mem.workspace_search[prefix .. result] do
-- add numbers until free unused name is found
result = name .. '_' .. i
end
return result
end
local create_component_name = function(component_type, name)
if not COMPONENT_DEFAULTS[component_type] then
return false
end
if validate_component_name(name) then
-- attempt to use supplied component name
return get_next_unused_name(component_type, name)
else
-- generate new component name
mem.component_index[component_type] = mem.component_index[component_type] + 1
return get_next_unused_name(component_type, component_type .. mem.component_index[component_type])
end
end
local create_component = function(component_type, name)
local result = {}
for k,v in pairs(COMPONENT_DEFAULTS[component_type]) do
if type(v) == 'table' then
result[k] = {'value'} -- Avoid references to default component values
else
result[k] = v
end
end
result.type = component_type
if result.name then
result.name = result.name .. name
end
return result
end
local create_control_component = function(component)
local result = {}
for k,v in pairs(WORKSPACE_CONTROL) do
result[k] = v
end
result.name = result.name .. component.name
update_control_position(result, component)
return result
end
local move_component = function(selection, X, Y)
if selection.ref then
if X ~= nil and selection.ref.X + X >= 0 and selection.ref.X + selection.ref.W + X <= 10 then
selection.ref.X = selection.ref.X + X
end
if Y ~= nil and selection.ref.Y + Y >= 0 and selection.ref.Y + selection.ref.H + Y <= 8 then
selection.ref.Y = selection.ref.Y + Y
end
update_control_position(selection.ctrl, selection.ref)
end
end
local resize_component = function(selection, W, H)
if not selection.ref then
return false
end
local enable_W = ALLOW_RESIZE_W[selection.ref.command] and true or false
local enable_H = ALLOW_RESIZE_H[selection.ref.command] and true or false
if selection.ref.W and selection.ref.H then
if enable_W and W ~= nil and selection.ref.W >= GRID_SIZE and selection.ref.W <= 10 then
selection.ref.W = selection.ref.W + W
end
if enable_H and H ~= nil and selection.ref.H >= GRID_SIZE and selection.ref.H <= 10 then
selection.ref.H = selection.ref.H + H
end
else
return false
end
return true
end
local nice_name = function(name)
local name_idx = string.find(name, "_", 2, true)
return string.sub(name, name_idx + 1, #name)
end
local deselect = function()
mem.selected.ref = nil
mem.selected.ctrl = nil
mem.selected.display_name = nil
mem.draw_component_editor = false
mem.component_editor_items_idx = nil
end
local select_component = function(name)
if mem.workspace_search[name] then
mem.selected.ref = mem.workspace[mem.workspace_search[name]]
mem.selected.ctrl = nil
mem.selected.display_name = nice_name(name)
return true
elseif mem.workspace_control[name] then
local main_name_idx = string.find(name, "_", #WORKSPACE_CONTROL.name + 1, true)
local main_name = string.sub(name, main_name_idx, #name)
mem.selected.ctrl = mem.workspace[mem.workspace_control[name]]
mem.selected.ref = mem.workspace[mem.workspace_search[main_name]]
mem.selected.display_name = nice_name(main_name)
return true
end
deselect()
return false
end
local workspace_cleanup = function()
mem.workspace_search = {}
mem.workspace_control = {}
workspace = {{command='clear'}}
for index,component in pairs(mem.workspace) do
if component and component.name and component.type ~= 'ctrl' then
table.insert(workspace, component)
mem.workspace_search[component.name] = table.maxn(workspace)
if not SELECTABLE_COMPONENTS[component.type] then
-- Add control anchor button to allow passive component selection
local control = create_control_component(component)
table.insert(workspace, control)
mem.workspace_control[control.name] = table.maxn(workspace)
end
end
end
mem.workspace = workspace
end
local functions = {
up = function()
if mem.mode_move then
move_component(mem.selected, nil, -GRID_SIZE)
else
resize_component(mem.selected, nil, GRID_SIZE)
end
end,
down = function()
if mem.mode_move then
move_component(mem.selected, nil, GRID_SIZE)
else
resize_component(mem.selected, nil, -GRID_SIZE)
end
end,
left = function()
if mem.mode_move then
move_component(mem.selected, -GRID_SIZE, nil)
else
resize_component(mem.selected, -GRID_SIZE, nil)
end
end,
right = function()
if mem.mode_move then
move_component(mem.selected, GRID_SIZE, nil)
else
resize_component(mem.selected, GRID_SIZE, nil)
end
end,
toggle_size_move = function()
mem.mode_move = not mem.mode_move
end,
toggle_grid_size = function()
GRID_SIZE = GRID_SIZE < 1.6 and GRID_SIZE + 0.4 or 0.4
mem.GRID_SIZE = GRID_SIZE
end,
delete = function()
if mem.selected.ref then
local name = mem.selected.ref.name
local id = mem.workspace_search[name]
mem.workspace[id] = nil
workspace_cleanup()
deselect()
end
end,
component_type = function(data)
local component_type_idx = textlist_indexof(data.component_type)
mem.component_type = COMPONENT_TYPES[component_type_idx]
mem.toolbar[7].selected_id = component_type_idx
end,
create = function(data)
local name = create_component_name(mem.component_type, data.component_name)
if name then
local component = create_component(mem.component_type, name)
table.insert(mem.workspace, component)
mem.workspace_search[component.name] = table.maxn(mem.workspace)
if not SELECTABLE_COMPONENTS[mem.component_type] then
-- Add control anchor button to allow passive component selection
local control = create_control_component(component)
table.insert(mem.workspace, control)
mem.workspace_control[control.name] = table.maxn(mem.workspace)
end
select_component(name)
end
end,
hide_toolbar = function()
mem.draw_toolbar = not mem.draw_toolbar
end,
edit_component = function()
mem.component_editor_items_idx = 1
mem.draw_component_editor = not mem.draw_component_editor
end,
component_editor_items = function(data)
mem.component_editor_items_idx = textlist_indexof(data.component_editor_items)
end,
component_listelement_add = function(data)
if mem.selected.ref then
local items = mem.selected.ref.choices or mem.selected.ref.listelements
if mem.component_editor_items_idx then
table.insert(items, mem.component_editor_items_idx + 1, data.component_listelement)
mem.component_editor_items_idx = mem.component_editor_items_idx + 1
elseif items then
table.insert(items, data.component_listelement)
end
else
mem.draw_component_editor = false
deselect()
end
end,
component_listelement_del = function(data)
if mem.selected.ref then
local items = mem.selected.ref.choices or mem.selected.ref.listelements
if items and mem.component_editor_items_idx then
table.remove(items, mem.component_editor_items_idx)
mem.component_editor_items_idx = math.max(1, mem.component_editor_items_idx - 1)
end
else
mem.draw_component_editor = false
deselect()
end
end,
component_editor_save = function(data)
if mem.selected.ref then
if data.component_label then
mem.selected.ref.label = data.component_label
end
if data.component_default then
mem.selected.ref.default = data.component_default
end
if data.component_image then
mem.selected.ref.image = data.component_image
end
end
mem.draw_component_editor = false
deselect()
end,
lock = function()
-- toggle lock, maybe add timeout for lock in public version?
mem.locked = not mem.locked
end,
reset = function()
-- add confirmation message before destroying everything?
reset()
end,
code = function()
local result = {}
local vk = { [true] = '="', [false] = '=', }
local vi = { [true] = '"', [false] = '', }
local ve = { [true] = '",\n', [false] = ',\n', }
local labelcleanup = { name = 1, H = 1, W = 1 }
local indent = 2
table.insert(result, 'digiline_send("touch",{\n')
for i,component in ipairs(mem.workspace) do
if mem.workspace_control[component.name] ~= i then
local islabel = component.command == 'addlabel' or component.command == 'addvertlabel'
table.insert(result, (i == 1 and string.rep(' ', indent) or '') .. '{\n')
indent = indent + 2
local pre = string.rep(' ', indent)
local pos = {}
for k,v in pairs(component) do
if type(v) == 'table' then
digiline_send('dbg', 'serializing table ' .. k)
table.insert(result, string.rep(' ', indent) .. k .. '={\n')
indent = indent + 2
pre = string.rep(' ', indent)
for _,li in ipairs(v) do
local quote = type(li) == 'string'
table.insert(result, pre .. vi[quote] .. li .. ve[quote])
end
indent = indent - 2
table.insert(result, string.rep(' ', indent) .. '},')
elseif k ~= 'type' then
if k == 'X' or k == 'Y' or k == 'H' or k == 'W' then
table.insert(pos, k .. '=' .. v .. ',')
else
local quote = type(v) == 'string'
if islabel and labelcleanup[k] then
-- noop
elseif k == 'name' then
table.insert(result, pre .. k .. vk[quote] .. nice_name(v) .. ve[quote])
else
table.insert(result, pre .. k .. vk[quote] .. tostring(v) .. ve[quote])
end
end
end
end
if table.maxn(pos) > 0 then
table.insert(result, pre .. table.concat(pos, ' ') .. '\n')
end
indent = indent - 2
table.insert(result, string.rep(' ', indent) .. '},')
end
end
table.insert(result, '{X=7.18,label="Created with SX Digi labs Touch Designer",Y=8.11,command="addlabel"}\n})\n')
mem.code = table.concat(result)
mem.draw_code = true
end,
close_code = function()
mem.draw_code = false
end,
quit = function()
deselect()
end,
}
local selectable = function(key)
-- Hack to get around the fact that touch screen will always populate input fields into incoming data
-- FIXME somehow, maybe find match from table?
local m = string.sub(key, 1, 2)
return m == '_b' or m == '_c' or m == '_i'
end
local execute_event = function(data)
for key,_ in pairs(data) do
if selectable(key) then
select_component(key)
return true
elseif functions[key] then
functions[key](data)
return true
end
end
return false
end
if event.type == 'digiline' then
if not execute_event(event.msg) then
local str = ''
for k,v in pairs(event.msg) do
str = str .. k
end
info('Exec failed' .. str)
end
elseif event.type == 'program' then
mem.touch_clear_commands = { command = "clear" }
elseif event.type == 'interrupt' then
if not mem.workspace then
reset()
end
end
if COMPONENT_TYPES then
draw_designer()
else
initialize_designer()
interrupt(1)
end

99
fabric_tree_farming.lua Normal file
View File

@ -0,0 +1,99 @@
if event.type == "program" then
mem.events = {}
mem.inventory = {sapling = 0, fertiliser = 0}
digiline_send("treedetector",{distance=0, command="get"})
digiline_send("extender1", {a = false, b = false, c = false, d = false})
digiline_send("extender2", {a = false, b = false, c = false, d = false})
mem.state = "idle"
end
if event.type == "digiline" then
if event.channel == "treesort" then
local count = mem.inventory[event.msg.name]
if count == nil then count = 0 end
mem.inventory[event.msg.name]= count + event.msg.count
end
if event.channel == "treedetector" then
mem.currentItem = event.msg
interrupt(1)
end
if event.channel == "chainsawindetector" then
digiline_send("extender1", {a = false, b = false, c = false, d = false})
mem.state = "prepare"
interrupt(30)
end
end
if event.type == "interrupt" then
if mem.state == "idle" then interrupt(10) end
if mem.state == "wait" then
local item = mem.currentItem
if item:find("sapling", 1, true) then
digiline_send("extender2", {a = false, b = false, c = false, d = false})
mem.state = "fertilising"
interrupt(1)
elseif item:find("trunk", 1, true) or item:find("tree", 1, true) then
digiline_send("extender2", {a = false, b = false, c = false, d = false})
digiline_send("extender1", {a = false, b = false, c = false, d = false})
mem.state = "cut"
interrupt(1)
elseif item == "air" then
digiline_send("extender1", {a = false, b = false, c = false, d = true})
mem.state = "recharge"
return
else
digiline_send("treedetector",{distance=0, command="get"})
interrupt(5)
end
end
if mem.state == "prepare" then
local item = mem.currentItem
if item ~= "air" then mem.state = "wait" interrupt(1) return end
if mem.inventory["sapling"] == 0 or mem.inventory["fertiliser"] == 0 then
--order from drawer default:sapling and bonemeal:fertiliser
mem.state = "prepare"
interrupt(20)
else
mem.state = "planting"
digiline_send("extender2", {c=false})
interrupt(20)
end
end
if mem.state == "planting" then
digiline_send("extender2", {c=true})
mem.inventory["sapling"] = mem.inventory["sapling"] - 1
mem.state = "wait"
mem.currentItem = ""
interrupt(1)
end
if mem.state == "fertilising" then
digiline_send("extender2", {b=true})
mem.inventory["fertiliser"] = mem.inventory["fertiliser"] - 1
mem.state = "wait"
mem.currentItem = ""
interrupt(1)
end
if mem.state == "cut" then
digiline_send("extender1", {c = true})
mem.state = "wait"
mem.currentItem = ""
interrupt(1)
end
end
if event.type == "on" and event.pin.name == "A" then
mem.state = "prepare"
interrupt(1)
end
if event.type == "off" and event.pin.name == "A" then
mem.state = "idle"
interrupt(1)
end

View File

@ -0,0 +1,28 @@
if event.type == "program" then
mem.events = {}
end
if event ~= nil then
local e = mem.events
table.insert(mem.events, event)
end
if event.type == "item" then
local name = event.item.name
mem.name = name
if name:find("sapling", 1, true) ~= nil then
if event.side == "white" then
digiline_send("treesort",{name="sapling", count=-event.item.count})
return "green"
else
digiline_send("treesort",{name="sapling", count=event.item.count})
return "white"
end
end
if name:find("fertiliser", 1, true) ~= nil then
digiline_send("treesort",{name="fertiliser", count=event.item.count})
return "black"
end
return "green"
end