Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ that repo.
# Future

## New Scripts
- `devel/eventful-client`: useful for testing eventful events

## Removed

Expand Down
145 changes: 145 additions & 0 deletions devel/eventful-client.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
-- Testing script for eventful events

--[====[
devel/eventful-client
=====================
Usage::
devel/eventful-client help
devel/eventful-client add <event type> <frequency>
devel/eventful-client add all <frequency>
devel/eventful-client list
devel/eventful-client clear
:help: shows this help text and a list of valid event types
:add: add a handler for the named event type at the requested tick frequency
:list: lists active handlers and their frequencies
:clear: unregisters all handlers
Note this script does not handle the eventful reaction or workshop events.
]====]

local eventful = require('plugins.eventful')

local utils = require('utils')

rng = rng or dfhack.random.new()

handlers = handlers or {}

local function get_event_fn_name(event_type_name)
local fn_name = 'on'
for word in event_type_name:gmatch('[^_]+') do
fn_name = fn_name .. word:sub(1,1) .. word:sub(2):lower()
end
if eventful[fn_name] then return fn_name end
fn_name = fn_name .. 'CreatedDestroyed'
if eventful[fn_name] then return fn_name end
return nil
end

local function get_event_registry()
local registry = {}
local event_list = utils.invert(eventful.eventType)
for i=0,#event_list do
local event_type_name = event_list[i]
if event_type_name == 'EVENT_MAX' then
return registry
end
registry[i+1] = {etype=event_type_name,
fn=get_event_fn_name(event_type_name)}
end
end

local function help()
print(dfhack.script_help())
print()
print('Event types (and the eventful event functions they map to):')
for _,v in ipairs(get_event_registry()) do
print((' %s -> %s'):format(v.etype, v.fn))
end
end

local function make_handler_fn(registry_entry, freq)
return function()
print(('eventful-client: %s received %s event (freq=%d)')
:format(os.date("%X"), registry_entry.etype, freq))
end
end

-- adds a new handler for the specified event type. uses a unique handler name
-- each time so multiple handlers can be registered for the same event.
local function add_one(registry_entry, freq)
if not registry_entry.fn then
print(('no eventful event function for %s events; skipping')
:format(registry_entry.etype))
return
end
eventful.enableEvent(eventful.eventType[registry_entry.etype], freq)
local handler_name = 'eventful-client.'..tostring(rng:random())
local handler = make_handler_fn(registry_entry, freq)
print(('eventful-client registering new %s handler at freq %d: %s')
:format(registry_entry.etype, freq, handler_name))
eventful[registry_entry.fn][handler_name] = handler
handlers[handler_name] = freq
end

local function add(spec, freq)
for _,v in ipairs(get_event_registry()) do
if spec == 'all' or spec == v.etype then
add_one(v, freq)
end
end
end

local function iterate_handlers(fn)
local count = 0
for _,v in ipairs(get_event_registry()) do
if not eventful[v.fn] then goto continue end
for k in pairs(eventful[v.fn]) do
if k:startswith('eventful-client.') then
count = count + 1
fn(v, k)
end
end
::continue::
end
return count
end

local function list_fn(registry_entry, handler_name)
print((' %s -> %s (freq=%s)')
:format(registry_entry.etype, handler_name,
handlers[handler_name] or 'unknown'))
end

local function list()
print('Active handlers:')
if 0 == iterate_handlers(list_fn) then
print(' None')
end
end

local function clear_fn(registry_entry, handler_name)
list_fn(registry_entry, handler_name)
eventful[registry_entry.fn][handler_name] = nil
handlers[handler_name] = nil
end

local function clear()
print('Clearing handlers:')
iterate_handlers(clear_fn)
end

local action_switch = {
add=add,
list=list,
clear=clear,
}
setmetatable(action_switch, {__index=function() return help end})

local args = {...}
local action = table.remove(args, 1) or 'help'

action_switch[action](table.unpack(args))