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
|