entirely rework event handling take 2

This commit is contained in:
2025-12-29 01:15:42 -05:00
parent 2312355418
commit 74dd72f478
2 changed files with 311 additions and 0 deletions

109
events.lua Normal file
View File

@ -0,0 +1,109 @@
--[[
Event Management System
Centralized event dispatcher with priority-based routing
]]
local events = {}
-- Event queue and handler registry
local eventHandlers = {}
local handlerPriorities = {}
---------------------------------------------
-- PRIORITY LEVELS (higher = more priority)
---------------------------------------------
events.PRIORITY = {
PASSWORD_INPUT = 100, -- Highest priority - password entry
ENTITY_READ = 50, -- Entity tracking
MESSAGE = 50, -- Message handling
DISCONNECT_BUTTON = 30, -- Manual disconnect button
ACTIVATION = 20, -- Incoming wormhole
DISCONNECT_CHECK = 10, -- Natural disconnection
TIMEOUT = 5, -- Timeout handlers
DEFAULT = 1 -- Default priority
}
---------------------------------------------
-- HANDLER REGISTRATION
---------------------------------------------
function events.registerHandler(eventType, callback, priority)
priority = priority or events.PRIORITY.DEFAULT
if not eventHandlers[eventType] then
eventHandlers[eventType] = {}
handlerPriorities[eventType] = {}
end
table.insert(eventHandlers[eventType], callback)
table.insert(handlerPriorities[eventType], priority)
end
function events.clearHandlers(eventType)
if eventType then
eventHandlers[eventType] = {}
handlerPriorities[eventType] = {}
else
eventHandlers = {}
handlerPriorities = {}
end
end
---------------------------------------------
-- EVENT DISPATCHER
---------------------------------------------
function events.dispatch(eventType, ...)
local handlers = eventHandlers[eventType]
if not handlers or #handlers == 0 then
return nil
end
-- Sort handlers by priority (highest first)
local sortedHandlers = {}
for i = 1, #handlers do
table.insert(sortedHandlers, {
callback = handlers[i],
priority = handlerPriorities[eventType][i]
})
end
table.sort(sortedHandlers, function(a, b)
return a.priority > b.priority
end)
-- Call handlers in priority order until one handles the event
for _, handler in ipairs(sortedHandlers) do
local result = handler.callback(...)
if result ~= nil then
return result
end
end
return nil
end
---------------------------------------------
-- EVENT POLLING
---------------------------------------------
function events.pullEvent(filter)
while true do
local eventData = {os.pullEvent(filter)}
local eventType = eventData[1]
local result = events.dispatch(eventType, table.unpack(eventData))
-- If a handler processed the event and returned something, return it
if result ~= nil then
return result, eventType, eventData
end
end
end
function events.waitForAny(...)
local functions = {...}
return parallel.waitForAny(table.unpack(functions))
end
return events

202
handlers.lua Normal file
View File

@ -0,0 +1,202 @@
--[[
Event Handlers
All event handling functions for the stargate control system
]]
local handlers = {}
-- Module references (set by init)
local config, gate, mon, utils, display, events
-- State variables
local state = {
incomingAddress = {},
incomingEntityType = "",
incomingEntityName = "",
lastReceivedMessage = nil,
enteringPassword = false,
remoteHasComputer = false,
destAddress = {},
destAddressname = ""
}
function handlers.init(cfg, gateInterface, monitor, utilsModule, displayModule, eventsModule)
config = cfg
gate = gateInterface
mon = monitor
utils = utilsModule
display = displayModule
events = eventsModule
end
function handlers.getState()
return state
end
---------------------------------------------
-- CLICK HANDLER (Priority-based)
---------------------------------------------
function handlers.handleMonitorTouch(eventType, side, x, y)
-- This is called by the event dispatcher for monitor_touch events
-- Returns nil to allow lower priority handlers to process if needed
return nil
end
---------------------------------------------
-- PASSWORD INPUT HANDLER (Highest Priority)
---------------------------------------------
function handlers.handlePasswordInput()
display.showPasswordPrompt()
local password = ""
state.enteringPassword = true
-- Register high-priority click handler for password input
local function passwordClickHandler(eventType, side, x, y)
if not state.enteringPassword then
return nil -- No longer active, let other handlers process
end
-- Check number buttons (1-9)
if y >= 7 and y <= 15 then
local row = math.floor((y - 7) / 3)
local col = math.floor((x - 8) / 5)
if col >= 0 and col <= 2 and row >= 0 and row <= 2 then
local num = row * 3 + col + 1
if num >= 1 and num <= 9 then
password = password .. tostring(num)
display.updatePasswordDisplay(password)
return true -- Event consumed
end
end
end
-- Check bottom row buttons
if y >= 16 and y <= 18 then
if x >= 8 and x <= 11 then
-- Clear button
password = ""
display.updatePasswordDisplay(password)
return true
elseif x >= 13 and x <= 16 then
-- Zero button
password = password .. "0"
display.updatePasswordDisplay(password)
return true
elseif x >= 18 and x <= 21 then
-- OK button - submit password
state.enteringPassword = false
return "submit"
end
end
return true -- Consume all clicks during password entry
end
-- Register the password handler with highest priority
events.registerHandler("monitor_touch", passwordClickHandler, events.PRIORITY.PASSWORD_INPUT)
-- Wait for password submission
while state.enteringPassword do
local result = events.pullEvent("monitor_touch")
if result == "submit" then
break
end
end
-- Unregister the password handler
events.clearHandlers("monitor_touch")
-- Send password attempt
utils.sendPasswordAttempt(password)
return password
end
---------------------------------------------
-- DISCONNECT BUTTON HANDLER
---------------------------------------------
function handlers.handleDisconnectButton(eventType, side, x, y)
-- Only process if not entering password (password handler has higher priority)
if state.enteringPassword then
return nil
end
-- Check if clicking disconnect button (bottom-right corner)
if y >= 17 and y <= 19 and x >= 20 and x <= 28 then
gate.disconnectStargate()
redstone.setOutput("top", false)
utils.log("Manual disconnect triggered")
return "disconnect"
end
return nil -- Not a disconnect button click
end
---------------------------------------------
-- ACTIVATION HANDLER
---------------------------------------------
function handlers.handleActivation(eventType, side, address)
state.incomingAddress = address
utils.log("Incoming wormhole: " .. gate.addressToString(address))
return "activation"
end
---------------------------------------------
-- ENTITY READ HANDLER
---------------------------------------------
function handlers.handleEntityRead(eventType, side, entityType, entityName, ...)
sleep(0.1)
state.incomingEntityType = entityType
state.incomingEntityName = entityName
utils.log("Entity reconstructed: " .. entityName .. " (" .. entityType .. ")")
return "entity"
end
---------------------------------------------
-- DISCONNECT CHECK HANDLER
---------------------------------------------
function handlers.handleDisconnect(eventType, side, disCode)
redstone.setOutput("top", false)
utils.log("Stargate disconnected (code: " .. tostring(disCode) .. ")")
if config.autoOpenIrisAfterDisconnect then
utils.openIris()
end
return "disconnected"
end
---------------------------------------------
-- MESSAGE HANDLER
---------------------------------------------
function handlers.handleMessage(eventType, side, message)
state.lastReceivedMessage = message
return "message"
end
---------------------------------------------
-- SETUP EVENT HANDLERS
---------------------------------------------
function handlers.setupConnectionHandlers()
-- Clear any existing handlers
events.clearHandlers()
-- Register all handlers with their priorities
events.registerHandler("monitor_touch", handlers.handleDisconnectButton, events.PRIORITY.DISCONNECT_BUTTON)
events.registerHandler("stargate_incoming_wormhole", handlers.handleActivation, events.PRIORITY.ACTIVATION)
events.registerHandler("stargate_reconstructing_entity", handlers.handleEntityRead, events.PRIORITY.ENTITY_READ)
events.registerHandler("stargate_disconnected", handlers.handleDisconnect, events.PRIORITY.DISCONNECT_CHECK)
events.registerHandler("stargate_message_received", handlers.handleMessage, events.PRIORITY.MESSAGE)
end
return handlers