309 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			309 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
-------------------------------------------------------------------------------
 | 
						|
---Class to build ModelDebug panel
 | 
						|
---@class ModelDebug
 | 
						|
ModelDebug = newclass(FormModel)
 | 
						|
 | 
						|
local display_panel = nil
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Initialization
 | 
						|
function ModelDebug:onInit()
 | 
						|
    self.panelCaption = "Model Debug"
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---On Style
 | 
						|
---@param styles table
 | 
						|
---@param width_main number
 | 
						|
---@param height_main number
 | 
						|
function ModelDebug:onStyle(styles, width_main, height_main)
 | 
						|
    styles.flow_panel = {
 | 
						|
        width = width_main,
 | 
						|
        minimal_height = 200,
 | 
						|
        maximal_height = height_main
 | 
						|
    }
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---On Bind Dispatcher
 | 
						|
function ModelDebug:onBind()
 | 
						|
    Dispatcher:bind("on_gui_refresh", self, self.update)
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Get or create info panel
 | 
						|
---@return LuaGuiElement
 | 
						|
function ModelDebug:getInfoPanel()
 | 
						|
    local flow_panel, content_panel, menu_panel = self:getPanel()
 | 
						|
    if content_panel["info-panel"] ~= nil and content_panel["info-panel"].valid then
 | 
						|
        return content_panel["info-panel"]
 | 
						|
    end
 | 
						|
    local panel = GuiElement.add(content_panel, GuiFrameV("info-panel"):style(helmod_frame_style.panel))
 | 
						|
    panel.style.horizontally_stretchable = true
 | 
						|
    return panel
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---On event
 | 
						|
---@param event LuaEvent
 | 
						|
function ModelDebug:onEvent(event)
 | 
						|
    local _, block = self:getParameterObjects()
 | 
						|
    if block ~= nil and block.runtimes ~= nil then
 | 
						|
        local runtimes = block.runtimes
 | 
						|
        if event.action == "change-stage" then
 | 
						|
            local stage = User.getParameter("model_stage") or 1
 | 
						|
            if event.item1 == "initial" then stage = 1 end
 | 
						|
            if event.item1 == "previous" and stage > 1 then stage = stage - 1 end
 | 
						|
            if event.item1 == "next" and stage < #runtimes then stage = stage + 1 end
 | 
						|
            if event.item1 == "final" then stage = #runtimes end
 | 
						|
            User.setParameter("model_stage", stage)
 | 
						|
        end
 | 
						|
        self:onUpdate(event)
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---On before open
 | 
						|
---@param event LuaEvent
 | 
						|
function ModelDebug:onBeforeOpen(event)
 | 
						|
    FormModel.onBeforeOpen(self, event)
 | 
						|
    local model, block = self:getParameterObjects()
 | 
						|
    ModelCompute.computeBlock(block)
 | 
						|
end
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---On update
 | 
						|
---@param event LuaEvent
 | 
						|
function ModelDebug:onUpdate(event)
 | 
						|
    self:updateHeader(event)
 | 
						|
    self:updateDebugPanel(event)
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Update information
 | 
						|
---@param event LuaEvent
 | 
						|
function ModelDebug:updateHeader(event)
 | 
						|
    local action_panel = self:getMenuPanel()
 | 
						|
    action_panel.clear()
 | 
						|
    local group1 = GuiElement.add(action_panel, GuiFlowH("group1"))
 | 
						|
    GuiElement.add(group1,
 | 
						|
        GuiButton(self.classname, "change-stage", "initial"):sprite("menu", defines.sprites.expand_left_group.black,
 | 
						|
            defines.sprites.expand_left_group.black):style("helmod_button_menu"):tooltip("Initial"))
 | 
						|
    GuiElement.add(group1,
 | 
						|
        GuiButton(self.classname, "change-stage", "previous"):sprite("menu", defines.sprites.expand_left.black,
 | 
						|
            defines.sprites.expand_left.black):style("helmod_button_menu"):tooltip("Previous Step"))
 | 
						|
    GuiElement.add(group1,
 | 
						|
        GuiButton(self.classname, "change-stage", "next"):sprite("menu", defines.sprites.expand_right.black,
 | 
						|
            defines.sprites.expand_right.black):style("helmod_button_menu"):tooltip("Next Step"))
 | 
						|
    GuiElement.add(group1,
 | 
						|
        GuiButton(self.classname, "change-stage", "final"):sprite("menu", defines.sprites.expand_right_group.black,
 | 
						|
            defines.sprites.expand_right_group.black):style("helmod_button_menu"):tooltip("Final"))
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Add cell header
 | 
						|
---@param guiTable LuaGuiElement
 | 
						|
---@param name string
 | 
						|
---@param caption string
 | 
						|
function ModelDebug:addCellHeader(guiTable, name, caption)
 | 
						|
    local cell = GuiElement.add(guiTable, GuiFlowH("header", name))
 | 
						|
    GuiElement.add(cell, GuiLabel("label"):caption(caption))
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Update debug panel
 | 
						|
---@param event LuaEvent
 | 
						|
function ModelDebug:updateDebugPanel(event)
 | 
						|
    local info_panel = self:getInfoPanel()
 | 
						|
    local model, block = self:getParameterObjects()
 | 
						|
 | 
						|
    if block ~= nil then
 | 
						|
        info_panel.clear()
 | 
						|
 | 
						|
        if block.runtimes ~= nil then
 | 
						|
            local scroll_panel = GuiElement.add(info_panel, GuiScroll("scroll_stage"))
 | 
						|
            scroll_panel.style.horizontally_squashable = true
 | 
						|
            scroll_panel.style.horizontally_stretchable = true
 | 
						|
            local stage = User.getParameter("model_stage") or 1
 | 
						|
            if block.runtimes[stage] == nil then
 | 
						|
                stage = 1
 | 
						|
                User.setParameter("model_stage", stage)
 | 
						|
            end
 | 
						|
            local runtime = block.runtimes[stage]
 | 
						|
            local ma_panel = GuiElement.add(scroll_panel,
 | 
						|
                GuiFrameV("stage_panel"):style(helmod_frame_style.hidden):caption(runtime.name))
 | 
						|
            local solver_selected = User.getParameter("solver_selected") or defines.constant.default_solver
 | 
						|
            if solver_selected == defines.constant.solvers.normal then
 | 
						|
                self:buildTableSolver(ma_panel, runtime.matrix, runtime.pivot)
 | 
						|
            else
 | 
						|
                self:buildTableSolverMatrix(ma_panel, runtime.matrix, runtime.pivot)
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Build matrix
 | 
						|
---@param matrix_panel LuaGuiElement
 | 
						|
---@param matrix table
 | 
						|
---@param pivot table
 | 
						|
function ModelDebug:buildTableSolver(matrix_panel, matrix, pivot)
 | 
						|
    if matrix ~= nil then
 | 
						|
        local num_col = #matrix[1]
 | 
						|
 | 
						|
        local matrix_table = GuiElement.add(matrix_panel,
 | 
						|
            GuiTable("matrix_data"):column(num_col):style("helmod_table-odd"))
 | 
						|
        matrix_table.vertical_centering = false
 | 
						|
 | 
						|
        for irow, row in pairs(matrix) do
 | 
						|
            for icol, value in pairs(row) do
 | 
						|
                local frame = GuiFlowH("cell", irow, icol):style("helmod_flow_horizontal")
 | 
						|
                if pivot ~= nil then
 | 
						|
                    if matrix[1][icol].name == "T" then frame = GuiFrameH("cell", irow, icol):style(
 | 
						|
                        "helmod_frame_colored", GuiElement.color_button_default_ingredient, 2) end
 | 
						|
                    if pivot.x == icol then frame = GuiFrameH("cell", irow, icol):style("helmod_frame_colored",
 | 
						|
                            GuiElement.color_button_edit, 2) end
 | 
						|
                    if pivot.y == irow then frame = GuiFrameH("cell", irow, icol):style("helmod_frame_colored",
 | 
						|
                            GuiElement.color_button_none, 2) end
 | 
						|
                    if pivot.x == icol and pivot.y == irow then frame = GuiFrameH("cell", irow, icol):style(
 | 
						|
                        "helmod_frame_colored", GuiElement.color_button_rest, 2) end
 | 
						|
                end
 | 
						|
                local cell = GuiElement.add(matrix_table, frame)
 | 
						|
                cell.style.horizontally_stretchable = true
 | 
						|
                cell.style.vertically_stretchable = true
 | 
						|
                if type(value) == "table" then
 | 
						|
                    if value.type == "none" then
 | 
						|
                        GuiElement.add(cell, GuiLabel("cell_value"):caption(value.name):tooltip(value.tooltip))
 | 
						|
                    elseif value.type == "contraint" then
 | 
						|
                        GuiElement.add(cell, GuiLabel("cell_value"):caption(value))
 | 
						|
                    else
 | 
						|
                        local tooltip = { "", value.name }
 | 
						|
                        table.insert(tooltip, { "", "\n", "column: ", value.icol })
 | 
						|
                        local button = GuiElement.add(cell,
 | 
						|
                            GuiButtonSprite("cell_value"):sprite(value.type, value.name):tooltip(tooltip))
 | 
						|
                        GuiElement.infoTemperature(button, value, "helmod_label_overlay_m")
 | 
						|
                    end
 | 
						|
                else
 | 
						|
                    local gui_label = GuiLabel("cell_value"):caption(Format.formatNumber(value, 4))
 | 
						|
                    if cell_value ~= 0 then
 | 
						|
                        gui_label:style("heading_2_label")
 | 
						|
                    end
 | 
						|
                    GuiElement.add(cell, gui_label)
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
function ModelDebug:getFrameColored(irow, icol, pivot)
 | 
						|
    local frame = GuiFlowH("cell", irow, icol):style("helmod_flow_horizontal")
 | 
						|
    if pivot ~= nil then
 | 
						|
        if pivot.x == icol then frame = GuiFrameH("cell", irow, icol):style("helmod_frame_colored",
 | 
						|
                GuiElement.color_button_edit, 2) end
 | 
						|
        if pivot.y == irow then frame = GuiFrameH("cell", irow, icol):style("helmod_frame_colored",
 | 
						|
                GuiElement.color_button_none, 2) end
 | 
						|
        if pivot.x == icol and pivot.y == irow then frame = GuiFrameH("cell", irow, icol):style(
 | 
						|
            "helmod_frame_colored", GuiElement.color_button_rest, 2) end
 | 
						|
    end
 | 
						|
    return frame
 | 
						|
end
 | 
						|
 | 
						|
function ModelDebug:getCellHeader(matrix_table, frame, header)
 | 
						|
    local cell = GuiElement.add(matrix_table, frame)
 | 
						|
    cell.style.horizontally_stretchable = true
 | 
						|
    cell.style.vertically_stretchable = true
 | 
						|
    if header.type == "none" then
 | 
						|
        GuiElement.add(cell, GuiLabel("cell_value"):caption(header.name):tooltip(header.tooltip))
 | 
						|
    elseif header.type == "contraint" then
 | 
						|
        GuiElement.add(cell, GuiLabel("cell_value"):caption(header))
 | 
						|
    elseif header.product ~= nil then
 | 
						|
        local tooltip = { "", header.product.name }
 | 
						|
        table.insert(tooltip, { "", "\n", "column: ", header.icol })
 | 
						|
        local button = GuiElement.add(cell,
 | 
						|
            GuiButtonSprite("cell_value"):sprite(header.product.type, header.product.name):tooltip(tooltip))
 | 
						|
        GuiElement.infoTemperature(button, header.product, "helmod_label_overlay_m")
 | 
						|
    else
 | 
						|
        local tooltip = { "", header.name }
 | 
						|
        local button = GuiElement.add(cell,
 | 
						|
            GuiButtonSprite("cell_value"):sprite(header.type, header.name):tooltip(tooltip))
 | 
						|
        GuiElement.infoTemperature(button, header, "helmod_label_overlay_m")
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
function ModelDebug:getCellValue(matrix_table, frame, cell_value)
 | 
						|
    local cell = GuiElement.add(matrix_table, frame)
 | 
						|
    cell.style.horizontally_stretchable = true
 | 
						|
    cell.style.vertically_stretchable = true
 | 
						|
    local gui_label = GuiLabel("cell_value"):caption(Format.formatNumber(cell_value, 4))
 | 
						|
    if cell_value ~= 0 then
 | 
						|
        gui_label:style("heading_2_label")
 | 
						|
    end
 | 
						|
    GuiElement.add(cell, gui_label)
 | 
						|
end
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Build matrix
 | 
						|
---@param matrix_panel LuaGuiElement
 | 
						|
---@param matrix table
 | 
						|
---@param pivot table
 | 
						|
function ModelDebug:buildTableSolverMatrix(matrix_panel, matrix, pivot)
 | 
						|
    if matrix ~= nil then
 | 
						|
        local parameter_columns = {}
 | 
						|
        table.insert(parameter_columns, {type="none", name="Cn", tooltip="Contraint", property="contraint"})
 | 
						|
        table.insert(parameter_columns, {type="none", name="FC", tooltip="Factory Count", property="factory_count"})
 | 
						|
        table.insert(parameter_columns, {type="none", name="FS", tooltip="Factory Speed", property="factory_speed"})
 | 
						|
        table.insert(parameter_columns, {type="none", name="RC", tooltip="Recipe Count", property="recipe_count"})
 | 
						|
        table.insert(parameter_columns, {type="none", name="RP", tooltip="Recipe Production", property="recipe_production"})
 | 
						|
        table.insert(parameter_columns, {type="none", name="RE", tooltip="Recipe Energy", property="recipe_energy"})
 | 
						|
        --table.insert(parameter_columns, {type="none", name="Coefficient", property="coefficient"})
 | 
						|
        local num_col = #matrix.columns + #parameter_columns + 1
 | 
						|
 | 
						|
        local matrix_table = GuiElement.add(matrix_panel, GuiTable("matrix_data"):column(num_col):style("helmod_table-odd"))
 | 
						|
        matrix_table.vertical_centering = false
 | 
						|
 | 
						|
        local frame = self:getFrameColored(0, 0, nil)
 | 
						|
        self:getCellHeader(matrix_table, frame, {type="none", name="Base"})
 | 
						|
 | 
						|
        for icol, parameter_column in pairs(parameter_columns) do
 | 
						|
            local frame = self:getFrameColored(0, -icol, nil)
 | 
						|
            self:getCellHeader(matrix_table, frame, parameter_column)
 | 
						|
        end
 | 
						|
 | 
						|
        for icol, column in pairs(matrix.columns) do
 | 
						|
            local frame = self:getFrameColored(0, icol, nil)
 | 
						|
            self:getCellHeader(matrix_table, frame, column)
 | 
						|
        end
 | 
						|
 | 
						|
        for irow, row in pairs(matrix.rows) do
 | 
						|
            local header = matrix.headers[irow]
 | 
						|
            if header == nil then
 | 
						|
                header = {type="none", name="z"}
 | 
						|
            end
 | 
						|
            local frame = self:getFrameColored(irow, 0, nil)
 | 
						|
            self:getCellHeader(matrix_table, frame, header)
 | 
						|
 | 
						|
            local parameters = matrix.parameters[irow] or {}
 | 
						|
            for icol, parameter_column in pairs(parameter_columns) do
 | 
						|
                local property_value = parameters[parameter_column.property] or 0
 | 
						|
                local frame = self:getFrameColored(irow, -icol, nil)
 | 
						|
                if type(property_value) == "number" then
 | 
						|
                    self:getCellValue(matrix_table, frame, property_value)
 | 
						|
                else
 | 
						|
                    self:getCellValue(matrix_table, frame, 0)              
 | 
						|
                end
 | 
						|
            end
 | 
						|
 | 
						|
            for icol, column in pairs(matrix.columns) do
 | 
						|
                local cell_value = row[icol] or 0
 | 
						|
                local frame = self:getFrameColored(irow, icol, pivot)
 | 
						|
                self:getCellValue(matrix_table, frame, cell_value)
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Update display
 | 
						|
function ModelDebug:updateDisplay()
 | 
						|
    local content_panel = self:getInfoPanel()
 | 
						|
    content_panel.clear()
 | 
						|
end
 |