Module:BuildingDataProxy

From Against the Storm Official Wiki
Revision as of 03:17, 29 October 2024 by Aeredor (talk | contribs) (Creating to lazily load and federate queries out to building data models)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Documentation for this module may be created at Module:BuildingDataProxy/doc

---@module BuildingDataProxy
local BuildingDataProxy = {}



--region Dependencies

-- Just store the strings, and we'll load lazily at runtime as needed. The order of this array controls the load order of data models.
local DATA_MODELS_NAMES_ARRAY = {
    "Module:WorkshopsData2",
    "Module:InstitutionsData2",
    "Module:FarmsData2",
    "Module:GatheringData",
    "Module:FishingData",
    "Module:RainCollectorsData",
    "Module:CampsData2",
    "Module:HearthsData",
    "Module:WarehousesData",
    "Module:FarmFieldsData",
}

local DataModelsCache = {}
for _, moduleName in pairs(DATA_MODELS_NAMES_ARRAY) do
    DataModelsCache[moduleName] = nil
end

--endregion



--region Private constants

local LOOKUP_DATA_MODEL_FUNCTIONAL_TYPES = {
    ["Module:CampsData2"] = "Gathering Camp",
    ["Module:FarmFieldsData"] = "Farm",
    ["Module:FarmsData2"] = "Farm",
    ["Module:FishingData"] = "Fishing Hut",
    ["Module:GatheringData"] = "Gathering Camp",
    ["Module:HearthsData"] = "Hearth",
    ["Module:InstitutionsData2"] = "Service Building",
    ["Module:RainCollectorsData"] = "Extraction Building",
    ["Module:WarehousesData"] = "Storage Building",
    ["Module:WorkshopsData2"] = "Production Building",
}

--endregion



--region Private member variables

--endregion



--region Private methods

local function cacheModel(modelName)

    if DataModelsCache[modelName] == nil then
        DataModelsCache[modelName] = require(modelName)
    end

    return DataModelsCache[modelName]
end

---fetchFromFunction
---Loops through the data models, calling the provided function on each in turn using the specified parameter (name or ID) until one of them returns a result. Returns nil if no data models found the specified name or ID.
---
---@param functionName string the name of the function to call
---@param parameter string name or ID
---@return ? whatever the function returns
local function federateFunction(functionName, parameter)

    for _, modelName in ipairs(DATA_MODELS_NAMES_ARRAY) do
        local DataModel = cacheModel(modelName)
        local result = DataModel[functionName](DataModel, parameter)
        -- If we found it, return, otherwise keep going
        if result then
            return result
        end
    end
    -- nil if not found
    return nil
end

--endregion



--region Public building interface

-- getID(displayName)
-- getCategory(id)
-- getCityScore(id)
-- getConstructionCosts(id) -- returns { [goodName] = stack size }
-- getConstructionTime(id)
-- getDescription(id)
-- getIcon(id)
-- isMovable(id)
-- getName(id)
-- getNumberOfWorkplaces(id)
-- getSize(id) -- returns string "X x Y"
-- getStorage(id)

function BuildingDataProxy.getID(displayName)
    return federateFunction("getID", displayName)
end

function BuildingDataProxy.getCategory(id)
    return federateFunction("getCategory", id)
end

function BuildingDataProxy.getCityScore(id)
    return federateFunction("getCityScore", id)
end

function BuildingDataProxy.getConstructionCosts(id)
    return federateFunction("getConstructionCosts", id)
end

function BuildingDataProxy.getConstructionTime(id)
    return federateFunction("getConstructionTime", id)
end

function BuildingDataProxy.getDescription(id)
    return federateFunction("getDescription", id)
end

function BuildingDataProxy.getIcon(id)
    return federateFunction("getIcon", id)
end

function BuildingDataProxy.isMovable(id)
    return federateFunction("isMovable", id)
end

function BuildingDataProxy.getName(id)
    return federateFunction("getName", id)
end

function BuildingDataProxy.getNumberOfWorkplaces(id)
    return federateFunction("getNumberOfWorkplaces", id)
end

function BuildingDataProxy.getSize(id)
    return federateFunction("getSize", id)
end

function BuildingDataProxy.getStorage(id)
    return federateFunction("getStorage", id)
end

--endregion



--region Public methods

---getFunctionalType
---Looks up a descriptive "functional type" for the specified building, based on the data model in which it was found. Used to augment the category with more information. Returns nil if the building is not found.
---
---@param id string the ID of the building
---@return string describing the functional type of the building
function BuildingDataProxy.getFunctionalType(id)

    for _, modelName in ipairs(DATA_MODELS_NAMES_ARRAY) do
        local DataModel = cacheModel(modelName)
        local validName = DataModel:getName(id)
        if validName then
            return LOOKUP_DATA_MODEL_FUNCTIONAL_TYPES[modelName]
        end
    end

    return nil
end

--endregion

return BuildingDataProxy