Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Very WIP: Refactor flight log recover #5775

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
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
233 changes: 106 additions & 127 deletions data/modules/FlightLog/FlightLog.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ local Character = require 'Character'

local FlightLogEntry = require 'modules.FlightLog.FlightLogEntries'

local function logInfo( msg )
logWarning( "FlightLog: " .. msg )
end

-- default values (private)
---@type integer
local MaxTotalNonCustomElements = 3000
Expand Down Expand Up @@ -209,91 +213,6 @@ function FlightLog.MakeCustomEntry(text)
FlightLog.AddEntry( FlightLogEntry.Custom.New( path, Game.time, Game.player:GetMoney(), location, text ) )
end

--
-- Method: InsertCustomEntry
--
-- Insert an element into custom flight log with all required fields
--
-- > FlightLog.InsertCustomEntry(entry)
--
-- Parameters:
--
-- entry - table
--
-- Entry:
--
-- path - System path
-- time - Game date
-- money - Financial balance at time of record creation
-- location - Array, with two strings: flight state, and relevant additional string
-- text - Free text string
--
---@param entry table
function FlightLog.InsertCustomEntry(entry)
if entry.path and entry.time and entry.money and entry.location and entry.text then
FlightLog.AddEntry( FlightLogEntry.Custom.New( entry.path, entry.time, entry.money, entry.location, entry.text ) )
return true
else
return false
end
end

--
-- Method: InsertSystemEntry
--
-- Insert an element into system flight log with all required fields
--
-- > FlightLog.InsertSystemEntry(entry)
--
-- Parameters:
--
-- entry - table
--
-- Entry:
--
-- path - System path, pointing to player's current system
-- arrtime - Game date, arrival
-- deptime - Game date, departure (optional)
-- text - Free text string (optional)
--
---@param entry table
function FlightLog.InsertSystemEntry(entry)
if entry.path and (entry.arrtime or entry.deptime) then
FlightLog.AddEntry( FlightLogEntry.System.New( entry.path, entry.arrtime, entry.deptime, entry.text or "" ) )
return true
else
return false
end
end

--
-- Method: InsertStationEntry
--
-- Insert an element into station flight log with all required fields
--
-- > FlightLog.InsertStationEntry(entry)
--
-- Parameters:
--
-- entry - table
--
-- Entry:
--
-- path - System path
-- arrtime - Game date, arrival
-- money - Financial balance at time of record creation
-- text - Free text string (optional)
--
---@param entry table
function FlightLog.InsertStationEntry(entry)
if entry.path and entry.time and entry.money then
FlightLog.AddEntry( FlightLogEntry.Station.New( entry.path, entry.time, entry.money, entry.text or "" ) )
return true
else
return false
end
end

-- Method: GetLogEntries
--
-- Example:
Expand Down Expand Up @@ -341,51 +260,43 @@ function FlightLog:GetLogEntries(types, maximum, earliest_first)
end
end

-- LOGGING

-- onLeaveSystem
local AddSystemDepartureToLog = function (ship)
if not ship:IsPlayer() then return end

FlightLog.AddEntry( FlightLogEntry.System.New( Game.system.path, nil, Game.time, nil ) )
end

-- onEnterSystem
local AddSystemArrivalToLog = function (ship)
if not ship:IsPlayer() then return end

FlightLog.AddEntry( FlightLogEntry.System.New( Game.system.path, Game.time, nil, nil ) )
end

-- onShipDocked
local AddStationToLog = function (ship, station)
if not ship:IsPlayer() then return end

FlightLog.AddEntry( FlightLogEntry.Station.New( station.path, Game.time, Game.player:GetMoney(), nil ) )
end

function FlightLog.OrganizeEntries()

local function sortf( a, b )
return a.sort_date > b.sort_date
local entryRecoveryLookup = {
["FlightLogEntry.Custom"] = FlightLogEntry.Custom.Unserialize,
["FlightLogEntry.System"] = FlightLogEntry.System.Unserialize,
["FlightLogEntry.Station"] = FlightLogEntry.Station.Unserialize
}

local function recoverEntry( entry, pathFixup, classLookup )
local class = classLookup( entry );
local unserializer = entryRecoveryLookup[class]
if unserializer == nil then
logWarning( "Flightlig unserialozer for " .. class .. " not found" )
else
logInfo( "Found unserializer for " .. class )
end

table.sort( FlightLogData, sortf )

CollapseSystemEvents()
if unserializer == nil then return nil end
return unserializer( entry, pathFixup )
end

-- LOADING AND SAVING
--- @param loaded_data table The data to load
--- @param pathFixup func(table):SystemPath Optional function to fixup invalid system paths
--- @param classLookup func(table):string Lookup for classname.
--- @return boolean Did we succesfully read the data?
function FlightLog.ParseSavedData(loaded_data, pathFixup, classLookup)

local loaded_data

local onGameStart = function ()
if loaded_data == nil then return false end

if loaded_data.Version == 1 then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mentioned this on IRC as well, but since we've done a savebump to v90, saves containing the version 1 flight log data structures are incompatible and thus this entire if-branch is redundant. Instead, the save recovery function for the flight log data will be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think this and the below comment are kind of what I'm getting at.

There are two options I can see:

  1. The flight-log code owns the flight log serialization, including recovery, which can be generalized as any system own's it's own code and specific recovery logic
  2. The flight-log code only owns loading the latest** version of the code and recovery is separated into the new-game menu (or some other module), which handles recovery for everything.

I was also asking the same question of the UI rendering :-)

I'll comment more below as this ties into the next comment


if loaded_data and loaded_data.Version == 1 then
logInfo( "Parsing Save Data v1")
FlightLogData = {}

for _, v in pairs( loaded_data.System ) do

local data = { systemp = v[1], arrtime = v[2], deptime = nil, entry = v[4] }
local systempath = pathFixup ~= nil and pathFixup( v[1] ) or v[1]

local data = { systemp = systempath, arrtime = v[2], deptime = nil, entry = v[4] }
if ( data.arrtime ~= nil ) then
-- entry
table.insert(FlightLogData, FlightLogEntry.System.Unserialize( data ))
Expand All @@ -399,32 +310,100 @@ local onGameStart = function ()
end

for _, v in pairs( loaded_data.Station ) do
local data = { systemp = v[1], deptime = v[2], money = v[3], entry = v[4] }

local systempath = pathFixup ~= nil and pathFixup( v[1] ) or v[1]

local data = { systemp = systempath, deptime = v[2], money = v[3], entry = v[4] }
table.insert(FlightLogData, FlightLogEntry.Station.Unserialize(data))
end

for _, v in pairs( loaded_data.Custom ) do
local data = { systemp = v[1], time = v[2], money = v[3], location = v[4], entry = v[5] }

local systempath = pathFixup ~= nil and pathFixup( v[1] ) or v[1]

local data = { systemp = systempath, time = v[2], money = v[3], location = v[4], entry = v[5] }
table.insert(FlightLogData, FlightLogEntry.Custom.Unserialize(data))
end

FlightLog.OrganizeEntries()

elseif loaded_data and loaded_data.Version > 1 then
FlightLogData = loaded_data.Data
local function sortf( a, b )
return a.sort_date > b.sort_date
end

table.sort( FlightLogData, sortf )

CollapseSystemEvents()

elseif loaded_data.Version > 1 then
if classLookup == nil then
logInfo( "Parsing Save Data v2 - no recovery with " .. #loaded_data.Data .. " elements" )

--- simple path, it's loaded, we don't need to lookup classes and unserialize.
FlightLogData = loaded_data.Data
else
logInfo( "Parsing Save Data v2 - recovery with " .. #loaded_data.Data .. " elements" )
--- we're doing some recovery right now...
--- TODO: do we pass through the pathfixup here and do above too, right off the bat?
FlightLogData = {}
for _, e in pairs( loaded_data.Data ) do
local recovered = recoverEntry( e, pathFixup, classLookup )
if recovered ~= nil then
table.insert( FlightLogData, recovered )
end
end
end
end


NonCustomElementCount = 0
for _, e in pairs(FlightLogData) do
if not e:IsCustom() then
AdjustNonCustomElementCount( 1 )
end
end

logInfo( "Finished loading data with " .. #FlightLogData .. " elements and " .. NonCustomElementCount .. " non custom elements" )

end

-- LOGGING

-- onLeaveSystem
local AddSystemDepartureToLog = function (ship)
if not ship:IsPlayer() then return end

FlightLog.AddEntry( FlightLogEntry.System.New( Game.system.path, nil, Game.time, nil ) )
end

-- onEnterSystem
local AddSystemArrivalToLog = function (ship)
if not ship:IsPlayer() then return end

FlightLog.AddEntry( FlightLogEntry.System.New( Game.system.path, Game.time, nil, nil ) )
end

-- onShipDocked
local AddStationToLog = function (ship, station)
if not ship:IsPlayer() then return end

FlightLog.AddEntry( FlightLogEntry.Station.New( station.path, Game.time, Game.player:GetMoney(), nil ) )
end


-- LOADING AND SAVING

local loaded_data = nil

local onGameStart = function ()

if loaded_data then
FlightLog.ParseSavedData( loaded_data )
end
loaded_data = nil
end

local onGameEnd = function ()

logInfo( "Game end, clearing the logs" )
FlightLogData = {}
NonCustomElementCount = 0
end
Expand Down
Loading