Skip to content

Commit

Permalink
Redo global init and migration
Browse files Browse the repository at this point in the history
  • Loading branch information
ClaudeMetz committed Jun 11, 2019
1 parent 0a21e39 commit edc57d4
Show file tree
Hide file tree
Showing 28 changed files with 377 additions and 323 deletions.
8 changes: 2 additions & 6 deletions Notes/TODO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,12 @@ TODO Bug Fixes:

TODO Quick List:
- make discussion post asking about module+beacon features
- redo player_table structure regarding preferences and in general
Redo it from the ground up to make it more readable
- add 'util' functions for setting/getting ui_state, settings, preferences
- add appropriate player_table migration + check migration correctness
- add preference to not show barreling recipes
- improve %-textfield selection (+enlarge textbox? dynamically?)
- add round-up indication stuff
- improve number formatting
- add search field to recipe selection
- (machines rework? (+ingredient limit)) (develop general structure for these prototypes)
- burner fuel consumption calculation
- check whether pyanodon correction is still needed
- add way to set height of GUI
- add way to set height of GUI
-- RENAME MIGRATION STUFF
2 changes: 1 addition & 1 deletion Scripts/code/build_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
init_file_path = new_mod_folder_path / "data" / "init.lua"
with tmp_path.open("w") as new_file, init_file_path.open("r") as old_file:
for line in old_file:
line = re.sub(r"global\.devmode = true", "--global.devmode = true", line)
line = re.sub(r"devmode = true", "--devmode = true", line)
new_file.write(line)
init_file_path.unlink()
tmp_path.rename(init_file_path)
Expand Down
3 changes: 2 additions & 1 deletion factoryplanner_0.17.9/data-final-fixes.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
-- Fixing Py Raw Ores duplicate item_group ordering
-- If any other mods have this issue, it won't be fixed automatically
if mods["pyrawores"] then
data.raw["item-group"]["py-rawores"].order = "x"
data.raw["item-group"]["py-rawores"].order = "y"
data.raw["item-group"]["py-petroleum-handling"].order = "x"
end
1 change: 0 additions & 1 deletion factoryplanner_0.17.9/data/classes/Factory.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ function Factory.init()
return {
Subfactory = Collection.init(),
valid = true,
mod_version = global.mod_version,
class = "Factory"
}
end
Expand Down
164 changes: 96 additions & 68 deletions factoryplanner_0.17.9/data/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,66 +9,96 @@ require("data.generator")
require("data.calc")
require("migrations.handler")

-- Margin of error for floating poing calculations
margin_of_error = 1e-10
devmode = true

-- Initiates all factorio-global variables
function global_init()
global.mod_version = game.active_mods["factoryplanner"]

global.players = {}
run_generators(false)
end

-- Runs through all updates that need to be made after the config changed
function handle_configuration_change()
-- Migrate global and reset generator tables
attempt_global_migration()
run_generators(true)

-- Runs through all players, even new ones (those with no player_table)
for index, player in pairs(game.players) do
attempt_player_table_migration(player)

update_player_table(player)

player_gui_reset(player) -- Destroys all existing GUI's
player_gui_init(player) -- Initializes some parts of the GUI

local factory = global.players[player.index].factory
Factory.update_validity(factory, player)

-- Update calculations in case some recipes changed
for _, subfactory in ipairs(Factory.get_in_order(factory, "Subfactory")) do
if subfactory.valid then update_calculations(player, subfactory) end
end

-- Update custom space science recipe state
local space_tech = player.force.technologies["space-science-pack"].researched
if space_tech then global.all_recipes[player.force.name]["fp-space-science-pack"].enabled = true end
end
end

-- Updates all generator variables
function run_generators(include_recipes)
global.all_items = generator.all_items()
-- Recipes are generated on player init because they depend on their force
global.all_machines = generator.all_machines()
global.all_belts = generator.all_belts()

global.devmode = true
global.margin_of_error = 1e-10
if include_recipes then
global.all_recipes = generator.all_recipes(true)
end
end

-- Creates and initiates a new player in the database if he doesn't exist yet
function player_init(player)
if global.players[player.index] == nil then
-- Makes sure that the given player has a player_table and a reset gui state
function update_player_table(player)
local function reload_data()
reload_settings(player) -- reloads the settings of the player
reload_preferences(player) -- reloads and adjusts the player's preferences
reset_ui_state(player) -- Resets the player's UI state
end

local player_table = global.players[player.index]
if player_table == nil then -- new player
global.players[player.index] = {}
local player_table = global.players[player.index]
player_table.mod_version = global.mod_version

player_table.factory = Factory.init()
player_table.main_dialog_dimensions = {width = nil, height = 1000}

player_table.settings = {}
reload_settings(player)
player_table.preferences = {}
player_table.ui_state = {}

player_table.default_machines = {}
data_util.machines.update_default(player)
player_table.preferred_belt_name = nil
data_util.update_preferred_belt(player)
reload_data()

-- Creates recipes if there are none for the force of this player
global.all_recipes = generator.all_recipes(false)

reset_gui_state(player)
queue_message(player, {"label.hint_tutorial"}, "hint")
end
end
queue_message(player, {"label.hint_tutorial"}, "hint")

-- Resets the GUI state of the given player, if he exists
function player_reset(player)
local player_table = global.players[player.index]
if player_table ~= nil then
reset_gui_state(player)
else -- existing player, only need to update
reload_data()

-- If any subfactories exist, select the first one
local subfactories = Factory.get_in_order(player_table.factory, "Subfactory")
if #subfactories > 0 then data_util.context.set_subfactory(player, subfactories[1]) end
end
end

-- Removes given player irreversibly from the database
function player_remove(player)
global.players[player.index] = nil
end

-- Writes the current user mod settings to their player_table
function reload_settings(player)
-- Delete the whole table first in case a setting got removed
global.players[player.index].settings = {}
local settings_table = global.players[player.index].settings

Expand All @@ -79,53 +109,51 @@ function reload_settings(player)
settings_table.belts_or_lanes = settings["fp_view_belts_or_lanes"].value
end

-- (Re)sets the GUI state of the given player
function reset_gui_state(player)
local player_table = global.players[player.index]
-- Reloads the user preferences, incorporating previous preferences if possible
-- preferences members: {default_machines, preferred_belt_name}
function reload_preferences(player)
-- These functions handle initializing their preferences attribute themselves
data_util.machines.update_default(player)
data_util.update_preferred_belt(player)
end

player_table.modal_dialog_type = nil -- The internal modal dialog type
player_table.selected_object = nil -- The object relevant for a modal dialog
player_table.modal_data = nil -- Data that can be set for a modal dialog to use
player_table.current_activity = nil -- The current unique main dialog activity
player_table.view_state = nil -- The state of the production views
player_table.queued_message = nil -- The next general message to be displayed
player_table.recipe_filter_preferences =
-- (Re)sets the UI state of the given player
function reset_ui_state(player)
-- Delete the whole table first in case ui_state parameter got removed
global.players[player.index].ui_state = {}
local ui_state_table = global.players[player.index].ui_state

ui_util.recalculate_main_dialog_dimensions(player)

ui_state_table.modal_dialog_type = nil -- The internal modal dialog type
ui_state_table.selected_object = nil -- The object relevant for a modal dialog
ui_state_table.modal_data = nil -- Data that can be set for a modal dialog to use
ui_state_table.current_activity = nil -- The current unique main dialog activity
ui_state_table.view_state = nil -- The state of the production views
ui_state_table.queued_message = nil -- The next general message to be displayed
ui_state_table.recipe_filter_preferences =
{disabled = false, hidden = false} -- The preferred state of both recipe filters
player_table.context = data_util.context.create(player) -- The currently displayed set of data
ui_state_table.context = data_util.context.create(player) -- The currently displayed set of data
end

-- Runs through all updates that need to be made after the config changed
function handle_configuration_change()
global.mod_version = game.active_mods["factoryplanner"]

global.all_items = generator.all_items()
global.all_recipes = generator.all_recipes(true)
global.all_machines = generator.all_machines()
global.all_belts = generator.all_belts()

-- Runs through all players, even new ones (those with no player_table etc)
for index, player in pairs(game.players) do
local space_tech = player.force.technologies["space-science-pack"].researched
if space_tech then global.all_recipes[player.force.name]["fp-space-science-pack"].enabled = true end

-- These two make sure that after them, the player exists for sure
player_reset(player) -- only runs if player exists already
player_init(player) -- only runs if player doesn't exist yet

reload_settings(player) -- reloads settings for players, old and new
-- Returns the player table for the given player
function get_table(player)
return global.players[player.index]
end

player_gui_reset(player) -- Destroys all existing GUI's
player_gui_init(player) -- Initializes some parts of the GUI
function get_settings(player)
return global.players[player.index].settings
end

local factory = global.players[player.index].factory
attempt_factory_migration(factory)
Factory.update_validity(factory, player)
function get_preferences(player)
return global.players[player.index].preferences
end

data_util.machines.update_default(player)
data_util.update_preferred_belt(player)
function get_ui_state(player)
return global.players[player.index].ui_state
end

for _, subfactory in ipairs(Factory.get_in_order(factory, "Subfactory")) do
if subfactory.valid then update_calculations(player, subfactory) end
end
end
-- The context is part of the ui state, but used frequently enough to warrant a getter
function get_context(player)
return global.players[player.index].ui_state.context
end
41 changes: 20 additions & 21 deletions factoryplanner_0.17.9/data/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ data_util = {
-- Creates a blank context referencing which part of the Factory is currently displayed
function data_util.context.create(player)
return {
factory = global.players[player.index].factory,
subfactory = nil,
floor = nil,
line = nil
Expand All @@ -15,15 +16,15 @@ end

-- Updates the context to match the newly selected subfactory
function data_util.context.set_subfactory(player, subfactory)
local context = global.players[player.index].context
local context = get_context(player)
context.subfactory = subfactory
context.floor = (subfactory ~= nil) and subfactory.selected_floor or nil
context.line = nil
end

-- Updates the context to match the newly selected floor
function data_util.context.set_floor(player, floor)
local context = global.players[player.index].context
local context = get_context(player)
context.subfactory.selected_floor = floor
context.floor = floor
context.line = nil
Expand All @@ -33,28 +34,28 @@ end
-- **** MACHINES ****
-- Updates default machines for the given player, restoring previous settings
function data_util.machines.update_default(player)
local old_defaults = global.players[player.index].default_machines
local old_defaults = get_preferences(player).default_machines
local new_defaults = {}

for category, data in pairs(global.all_machines) do
if old_defaults[category] ~= nil and data.machines[old_defaults[category]] ~= nil then
if old_defaults and old_defaults[category] ~= nil and data.machines[old_defaults[category]] ~= nil then
new_defaults[category] = old_defaults[category]
else
new_defaults[category] = data.machines[data.order[1]].name
end
end

global.players[player.index].default_machines = new_defaults
get_preferences(player).default_machines = new_defaults
end

-- Changes the preferred machine for the given category
function data_util.machines.set_default(player, category, name)
global.players[player.index].default_machines[category] = name
get_preferences(player).default_machines[category] = name
end

-- Returns the default machine for the given category
function data_util.machines.get_default(player, category)
local defaults = global.players[player.index].default_machines
local defaults = get_preferences(player).default_machines
return global.all_machines[category].machines[defaults[category]]
end

Expand All @@ -80,13 +81,10 @@ end

-- Updates the preferred belt, preventing it from being invalid
function data_util.update_preferred_belt(player)
local player_table = global.players[player.index]
if global.all_belts[player_table.preferred_belt_name] == nil then
-- Select the first available belt as the new preferred one
for name, _ in pairs(global.all_belts) do
player_table.preferred_belt_name = name
break
end
local preferences = get_preferences(player)
if preferences.preferred_belt_name == nil or
global.all_belts[preferences.preferred_belt_name] == nil then
preferences.preferred_belt_name = next(global.all_belts)
end
end

Expand Down Expand Up @@ -129,9 +127,9 @@ end

-- Initiates the data table with some values for development purposes
function data_util.run_dev_config(player)
if global.devmode then
local player_table = global.players[player.index]
local factory = player_table.factory
if devmode then
local context = get_context(player)
local factory = context.factory

-- Subfactories
local subfactory = Factory.add(factory, Subfactory.init("", {type="item", name="iron-plate"}))
Expand Down Expand Up @@ -172,14 +170,15 @@ function data_util.run_dev_config(player)
local recipes = {
{recipe="electronic-circuit", machine=1}
}
construct_floor(player, player_table.context.floor, recipes)
construct_floor(player, context.floor, recipes)
end
end

-- Adds an example subfactory for new users to explore (returns that subfactory)
function data_util.add_example_subfactory(player)
local player_table = global.players[player.index]
local factory = player_table.factory
local context = get_context(player)
local factory = context.factory

local subfactory = Factory.add(factory, Subfactory.init("Example", {type="item", name="automation-science-pack"}))
data_util.context.set_subfactory(player, subfactory)

Expand Down Expand Up @@ -233,7 +232,7 @@ function data_util.add_example_subfactory(player)
{recipe="impostor-stone", machine=2},
{recipe="impostor-coal", machine=2}
}
construct_floor(player, player_table.context.floor, recipes)
construct_floor(player, context.floor, recipes)

return subfactory
end
Loading

0 comments on commit edc57d4

Please sign in to comment.