commit 15d17526029f5ae3a39ea4e12789abbaecdaae66 Author: sfokin Date: Fri Mar 28 14:01:18 2025 +0300 init diff --git a/fabric_hive_processor.lua b/fabric_hive_processor.lua new file mode 100644 index 0000000..3250a8c --- /dev/null +++ b/fabric_hive_processor.lua @@ -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 diff --git a/fabric_nuclear_cells_produtction.lua b/fabric_nuclear_cells_produtction.lua new file mode 100644 index 0000000..f75fd50 --- /dev/null +++ b/fabric_nuclear_cells_produtction.lua @@ -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 \ No newline at end of file diff --git a/fabric_power_monitor.lua b/fabric_power_monitor.lua new file mode 100644 index 0000000..b926ae7 --- /dev/null +++ b/fabric_power_monitor.lua @@ -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 \ No newline at end of file diff --git a/fabric_touchscreen_designer.lua b/fabric_touchscreen_designer.lua new file mode 100644 index 0000000..ab2899f --- /dev/null +++ b/fabric_touchscreen_designer.lua @@ -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 \ No newline at end of file diff --git a/fabric_tree_farming.lua b/fabric_tree_farming.lua new file mode 100644 index 0000000..afa9aad --- /dev/null +++ b/fabric_tree_farming.lua @@ -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 diff --git a/fabric_tree_farming_sorting.lua b/fabric_tree_farming_sorting.lua new file mode 100644 index 0000000..5967c9e --- /dev/null +++ b/fabric_tree_farming_sorting.lua @@ -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 \ No newline at end of file