Skip to content

Commit

Permalink
implement migration
Browse files Browse the repository at this point in the history
  • Loading branch information
myk002 committed Dec 30, 2023
1 parent 38d1a18 commit 601da49
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 129 deletions.
46 changes: 27 additions & 19 deletions gui/control-panel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ function CommandTab:init_main_panel(panel)
view_id='list',
on_select=self:callback('on_select'),
on_double_click=self:callback('on_submit'),
on_double_click2=self:callback('launch_config'),
row_height=2,
},
}
Expand All @@ -188,14 +187,6 @@ function CommandTab:init_footer(panel)
},
widgets.HotkeyLabel{
frame={t=1, l=0},
label='Launch tool-specific config UI',
key='CUSTOM_CTRL_G',
auto_width=true,
enabled=self:callback('has_config'),
on_activate=self:callback('launch_config'),
},
widgets.HotkeyLabel{
frame={t=2, l=26},
label='Show full tool help or run custom command',
auto_width=true,
key='CUSTOM_CTRL_H',
Expand All @@ -215,12 +206,6 @@ function CommandTab:has_config()
return choice and choice.gui_config
end

function CommandTab:launch_config()
_,choice = self.subviews.list:getSelected()
if not choice or not choice.gui_config then return end
dfhack.run_command(choice.gui_config)
end


--
-- EnabledTab
Expand All @@ -239,9 +224,24 @@ function EnabledTab:init()
if not dfhack.world.isFortressMode() then
self.subpage = Subtabs.gameplay
end

self.subviews.list.list.on_double_click2=self:callback('launch_config')
end

function EnabledTab:init_footer(panel)
EnabledTab.super.init_footer(self, panel)
panel:addviews{
widgets.HotkeyLabel{
frame={t=2, l=26},
label='Launch tool-specific config UI',
key='CUSTOM_CTRL_G',
auto_width=true,
enabled=self:callback('has_config'),
on_activate=self:callback('launch_config'),
},
}
end

-- TODO
local function get_gui_config(command)
command = common.get_first_word(command)
local gui_config = 'gui/' .. command
Expand Down Expand Up @@ -327,6 +327,12 @@ function EnabledTab:onInput(keys)
return handled
end

function EnabledTab:launch_config()
_,choice = self.subviews.list:getSelected()
if not choice or not choice.gui_config then return end
dfhack.run_command(choice.gui_config)
end

function EnabledTab:on_submit()
_,choice = self.subviews.list:getSelected()
if not choice then return end
Expand All @@ -349,7 +355,8 @@ function EnabledTab:restore_defaults()
::continue::
end
self:refresh()
dialogs.showMessage('Success', 'Defaults restored.')
dialogs.showMessage('Success',
('Enabled defaults restored for %s tools.'):format(group))
end


Expand Down Expand Up @@ -442,7 +449,8 @@ function AutostartTab:restore_defaults()
end
common.config:write()
self:refresh()
dialogs.showMessage('Success', 'Defaults restored.')
dialogs.showMessage('Success',
('Autostart defaults restored for %s tools.'):format(group))
end


Expand Down Expand Up @@ -774,7 +782,7 @@ end
ControlPanel = defclass(ControlPanel, widgets.Window)
ControlPanel.ATTRS {
frame_title='DFHack Control Panel',
frame={w=78, h=44},
frame={w=68, h=44},
resizable=true,
resize_min={h=39},
autoarrange_subviews=true,
Expand Down
8 changes: 4 additions & 4 deletions internal/control-panel/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ REPEATS_GLOBAL_KEY = 'control-panel-repeats'
local function get_config()
local f = json.open(CONFIG_FILE)
local updated = false
-- ensure proper structure
ensure_key(f.data, 'commands')
ensure_key(f.data, 'preferences')
if f.exists then
-- ensure proper structure
ensure_key(f.data, 'commands')
ensure_key(f.data, 'preferences')
-- remove unknown or out of date entries from the loaded config
for k, v in pairs(f.data) do
for k in pairs(f.data) do
if k ~= 'commands' and k ~= 'preferences' then
updated = true
f.data[k] = nil
Expand Down
184 changes: 85 additions & 99 deletions internal/control-panel/migration.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
-- migrate configuration from 50.11-r4 and prior to new format
--@module = true

-- read old files, add converted data to config_data, overwrite old files with
-- a message that says they are deprecated and can be deleted with the proper
-- procedure. we can't delete them outright since steam may just restore them due to
-- Steam Cloud. We *could* delete them, though, if we know that we've been started
-- from Steam as DFHack and not as DF

local argparse = require('argparse')
local registry = reqscript('internal/control-panel/registry')

-- init files
local SYSTEM_INIT_FILE = 'dfhack-config/init/dfhack.control-panel-system.init'
local PREFERENCES_INIT_FILE = 'dfhack-config/init/dfhack.control-panel-preferences.init'
local AUTOSTART_FILE = 'dfhack-config/init/onMapLoad.control-panel-new-fort.init'
local REPEATS_FILE = 'dfhack-config/init/onMapLoad.control-panel-repeats.init'
local PREFERENCES_INIT_FILE = 'dfhack-config/init/dfhack.control-panel-preferences.init'

local function save_tombstone_file(path)
local ok, f = pcall(io.open, path, 'w')
Expand All @@ -23,123 +32,100 @@ local function save_tombstone_file(path)
f:write('# If you\'re not on Steam, you can delete this file at any time.\n')
f:close()
end
--[[
function SystemServices:on_submit()
SystemServices.super.on_submit(self)

local enabled_map = self:get_enabled_map()
local save_fn = function(f)
for _,service in ipairs(SYSTEM_USER_SERVICES) do
if enabled_map[service] then
f:write(('enable %s\n'):format(service))
end
end
local function add_autostart(config_data, name)
if not registry.COMMANDS_BY_NAME[name].default then
config_data.commands[name] = {autostart=true}
end
save_file(SYSTEM_INIT_FILE, save_fn)
end

function FortServicesAutostart:on_submit()
_,choice = self.subviews.list:getSelected()
if not choice then return end
self.enabled_map[choice.target] = not choice.enabled
local save_fn = function(f)
for service,enabled in pairs(self.enabled_map) do
if enabled then
if service:match(' ') then
f:write(('on-new-fortress %s\n'):format(service))
else
f:write(('on-new-fortress enable %s\n'):format(service))
end
end
end
local function add_preference(config_data, name, val)
local data = registry.PREFERENCES_BY_NAME[name]
if type(data.default) == 'boolean' then
ok, val = pcall(argparse.boolean, val)
if not ok then return end
elseif type(data.default) == 'number' then
val = tonumber(val)
if not val then return end
end
if data.default ~= val then
config_data.preferences[name] = {val=val}
end
save_file(AUTOSTART_FILE, save_fn)
self:refresh()
end

function FortServicesAutostart:init()
local enabled_map = {}
local ok, f = pcall(io.open, AUTOSTART_FILE)
if ok and f then
local services_set = utils.invert(FORT_AUTOSTART)
for line in f:lines() do
line = line:trim()
if #line == 0 or line:startswith('#') then goto continue end
local service = line:match('^on%-new%-fortress enable ([%S]+)$')
or line:match('^on%-new%-fortress (.+)')
if service and services_set[service] then
enabled_map[service] = true
end
::continue::
local function parse_lines(fname, line_fn)
local ok, f = pcall(io.open, fname)
if not ok or not f then return end
for line in f:lines() do
line = line:trim()
if #line > 0 and not line:startswith('#') then
line_fn(line)
end
end
self.enabled_map = enabled_map
end

function Preferences:do_save()
local save_fn = function(f)
for ctx_name,settings in pairs(PREFERENCES) do
local ctx_env = require(ctx_name)
for id in pairs(settings) do
f:write((':lua require("%s").%s=%s\n'):format(
ctx_name, id, tostring(ctx_env[id])))
end
local function migrate_system(config_data)
parse_lines(SYSTEM_INIT_FILE, function(line)
local service = line:match('^enable ([%S]+)$')
if not service then return end
local data = registry.COMMANDS_BY_NAME[service]
if data and (data.mode == 'system_enable' or data.command == 'work-now') then
add_autostart(config_data, service)
end
for _,spec in ipairs(CPP_PREFERENCES) do
local line = spec.init_fmt:format(spec.get_fn())
f:write(('%s\n'):format(line))
end
end
save_file(PREFERENCES_INIT_FILE, save_fn)
end)
save_tombstone_file(SYSTEM_INIT_FILE)
end

function RepeatAutostart:init()
self.subviews.show_help_label.visible = false
self.subviews.launch.visible = false
local enabled_map = {}
local ok, f = pcall(io.open, REPEATS_FILE)
if ok and f then
for line in f:lines() do
line = line:trim()
if #line == 0 or line:startswith('#') then goto continue end
local service = line:match('^repeat %-%-name ([%S]+)')
if service then
enabled_map[service] = true
end
::continue::
local function migrate_autostart(config_data)
parse_lines(AUTOSTART_FILE, function(line)
local service = line:match('^on%-new%-fortress enable ([%S]+)$')
or line:match('^on%-new%-fortress (.+)')
if not service then return end
local data = registry.COMMANDS_BY_NAME[service]
if data and (data.mode == 'enable' or data.mode == 'run') then
add_autostart(config_data, service)
end
end
self.enabled_map = enabled_map
end)
save_tombstone_file(AUTOSTART_FILE)
end

function RepeatAutostart:on_submit()
_,choice = self.subviews.list:getSelected()
if not choice then return end
self.enabled_map[choice.name] = not choice.enabled
local run_commands = dfhack.isMapLoaded()
local REPEAT_MAP = {
autoMilkCreature='automilk',
autoShearCreature='autoshear',
['dead-units-burrow']='fix/dead-units',
['empty-wheelbarrows']='fix/empty-wheelbarrows',
['general-strike']='fix/general-strike',
['stuck-instruments']='fix/stuck-instruments',
}

local save_fn = function(f)
for name,enabled in pairs(self.enabled_map) do
if enabled then
local command_str = ('repeat --name %s %s\n'):
format(name, table.concat(REPEATS[name].command, ' '))
f:write(command_str)
if run_commands then
dfhack.run_command(command_str) -- actually start it up too
end
elseif run_commands then
repeatUtil.cancel(name)
end
local function migrate_repeats(config_data)
parse_lines(REPEATS_FILE, function(line)
local service = line:match('^repeat %-%-name ([%S]+)')
if not service then return end
service = REPEAT_MAP[service] or service
local data = registry.COMMANDS_BY_NAME[service]
if data and data.mode == 'repeat' then
add_autostart(config_data, service)
end
end
save_file(REPEATS_FILE, save_fn)
self:refresh()
end)
save_tombstone_file(REPEATS_FILE)
end
]]

local function migrate_preferences(config_data)
parse_lines(PREFERENCES_INIT_FILE, function(line)
local name, val = line:match('^:lua .+%.([^=]+)=(.+)')
if not name or not val then return end
local data = registry.PREFERENCES_BY_NAME[name]
if data then
add_preference(config_data, name, val)
end
end)
save_tombstone_file(PREFERENCES_INIT_FILE)
end

function migrate(config_data)
-- read old files, add converted data to config_data, overwrite old files with
-- a message that says they are deprecated and can be deleted with the proper procedure
-- we can't delete them outright since steam may just restore them due to Steam Cloud
-- we *could* delete them if we know that we've been started from Steam as DFHack and not as DF
migrate_system(config_data)
migrate_autostart(config_data)
migrate_repeats(config_data)
migrate_preferences(config_data)
end
14 changes: 7 additions & 7 deletions internal/control-panel/registry.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ COMMANDS_BY_IDX = {
-- automation tools
{command='autobutcher', group='automation', mode='enable'},
{command='autobutcher target 10 10 14 2 BIRD_GOOSE', group='automation', mode='run',
desc='Set to autostart if you usually want to raise geese.'},
desc='Enable if you usually want to raise geese.'},
{command='autobutcher target 10 10 14 2 BIRD_TURKEY', group='automation', mode='run',
desc='Set to autostart if you usually want to raise turkeys.'},
desc='Enable if you usually want to raise turkeys.'},
{command='autobutcher target 10 10 14 2 BIRD_CHICKEN', group='automation', mode='run',
desc='Set to autostart if you usually want to raise chickens.'},
desc='Enable if you usually want to raise chickens.'},
{command='autochop', group='automation', mode='enable'},
{command='autoclothing', group='automation', mode='enable'},
{command='autofarm', group='automation', mode='enable'},
{command='autofarm threshold 150 grass_tail_pig', group='automation', mode='run',
desc='Set to autostart if you usually farm pig tails for the clothing industry.'},
desc='Enable if you usually farm pig tails for the clothing industry.'},
{command='autofish', group='automation', mode='enable'},
--{command='autolabor', group='automation', mode='enable'}, -- hide until it works better
{command='automilk', group='automation', mode='repeat',
Expand All @@ -32,9 +32,9 @@ COMMANDS_BY_IDX = {
{command='autoslab', group='automation', mode='enable'},
{command='ban-cooking all', group='automation', mode='run'},
{command='buildingplan set boulders false', group='automation', mode='run',
desc='Set to autostart if you usually don\'t want to use boulders for construction.'},
desc='Enable if you usually don\'t want to use boulders for construction.'},
{command='buildingplan set logs false', group='automation', mode='run',
desc='Set to autostart if you usually don\'t want to use logs for construction.'},
desc='Enable if you usually don\'t want to use logs for construction.'},
{command='cleanowned', group='automation', mode='repeat',
desc='Encourage dwarves to drop tattered clothing and grab new ones.',
params={'--time', '1', '--timeUnits', 'months', '--command', '[', 'cleanowned', 'X', ']'}},
Expand Down Expand Up @@ -70,7 +70,7 @@ COMMANDS_BY_IDX = {
desc='Combine partial stacks in stockpiles into full stacks.',
params={'--time', '7', '--timeUnits', 'days', '--command', '[', 'combine', 'all', '-q', ']'}},
{command='drain-aquifer --top 2', group='gameplay', mode='run',
desc='Set to autostart to ensure that your maps have no more than 2 layers of aquifer.'},
desc='Ensure that your maps have no more than 2 layers of aquifer.'},
{command='dwarfvet', group='gameplay', mode='enable'},
{command='emigration', group='gameplay', mode='enable'},
{command='fastdwarf', group='gameplay', mode='enable'},
Expand Down

0 comments on commit 601da49

Please sign in to comment.