entirely rework event handling take 2
This commit is contained in:
109
events.lua
Normal file
109
events.lua
Normal 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
202
handlers.lua
Normal 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
|
||||
Reference in New Issue
Block a user