mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-05-05 10:59:45 +00:00
feat: Enhance JSON configuration writer and add heartbeat recording to crash recovery service
- Updated JsonConfigWriterService to structure the JSON output with new sections for scripts, window settings, input bindings, paths, rendering, and GUI configurations. - Introduced a new method in ICrashRecoveryService to record frame heartbeats, allowing for better tracking of long-running operations. - Refactored existing code to improve readability and maintainability, including the addition of helper functions for adding string members to JSON objects.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
local resolver = {}
|
||||
|
||||
local function as_table(value)
|
||||
if type(value) == "table" then
|
||||
return value
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function resolver.resolve_materialx(config)
|
||||
local root = as_table(config)
|
||||
if not root then
|
||||
return nil
|
||||
end
|
||||
local rendering = as_table(root.rendering)
|
||||
if rendering then
|
||||
local materialx = as_table(rendering.materialx)
|
||||
if materialx then
|
||||
return materialx
|
||||
end
|
||||
end
|
||||
return as_table(root.materialx)
|
||||
end
|
||||
|
||||
function resolver.resolve_materialx_materials(config)
|
||||
local materialx = resolver.resolve_materialx(config)
|
||||
if materialx then
|
||||
local materials = as_table(materialx.materials)
|
||||
if materials then
|
||||
return materials
|
||||
end
|
||||
end
|
||||
local root = as_table(config)
|
||||
if root then
|
||||
return as_table(root.materialx_materials)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function resolver.resolve_input_bindings(config)
|
||||
local root = as_table(config)
|
||||
if not root then
|
||||
return nil
|
||||
end
|
||||
local input = as_table(root.input)
|
||||
if input then
|
||||
local bindings = as_table(input.bindings)
|
||||
if bindings then
|
||||
return bindings
|
||||
end
|
||||
end
|
||||
return as_table(root.input_bindings)
|
||||
end
|
||||
|
||||
function resolver.resolve_gui_font(config)
|
||||
local root = as_table(config)
|
||||
if not root then
|
||||
return nil
|
||||
end
|
||||
local gui = as_table(root.gui)
|
||||
if gui then
|
||||
local font = as_table(gui.font)
|
||||
if font then
|
||||
return font
|
||||
end
|
||||
end
|
||||
return as_table(root.gui_font)
|
||||
end
|
||||
|
||||
function resolver.resolve_gui_opacity(config)
|
||||
local root = as_table(config)
|
||||
if not root then
|
||||
return nil
|
||||
end
|
||||
local gui = as_table(root.gui)
|
||||
if gui and type(gui.opacity) == "number" then
|
||||
return gui.opacity
|
||||
end
|
||||
if type(root.gui_opacity) == "number" then
|
||||
return root.gui_opacity
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
return resolver
|
||||
@@ -1,5 +1,6 @@
|
||||
local scene_framework = require("scene_framework")
|
||||
local math3d = require("math3d")
|
||||
local config_resolver = require("config_resolver")
|
||||
|
||||
local cube_mesh_info = {
|
||||
path = "models/cube.stl",
|
||||
@@ -709,19 +710,19 @@ local function resolve_material_shader()
|
||||
if type(config) ~= "table" then
|
||||
error("Missing config table for MaterialX shader selection")
|
||||
end
|
||||
local materialx = config.materialx
|
||||
local materialx = config_resolver.resolve_materialx(config)
|
||||
if type(materialx) ~= "table" or not materialx.enabled then
|
||||
error("MaterialX config missing or disabled; shader selection cannot proceed")
|
||||
end
|
||||
local materials = config.materialx_materials
|
||||
local materials = config_resolver.resolve_materialx_materials(config)
|
||||
if type(materials) == "table" and type(materials[1]) == "table" then
|
||||
local first_key = materials[1].shader_key
|
||||
if type(first_key) == "string" and first_key ~= "" then
|
||||
log_debug("Using first materialx_materials shader_key=%s", first_key)
|
||||
log_debug("Using first materialx materials shader_key=%s", first_key)
|
||||
return first_key
|
||||
end
|
||||
end
|
||||
error("MaterialX enabled but no materialx_materials shader_key found")
|
||||
error("MaterialX enabled but no materials shader_key found")
|
||||
end
|
||||
|
||||
-- Delegate to framework
|
||||
|
||||
+42
-23
@@ -1250,30 +1250,45 @@ def gui(args: argparse.Namespace) -> None:
|
||||
"description": f"3D {name} project based on cube demo template",
|
||||
"enabled": True
|
||||
},
|
||||
"window_width": 1024,
|
||||
"window_height": 768,
|
||||
"lua_script": f"scripts/{project_id}_logic.lua",
|
||||
"scripts_directory": "scripts",
|
||||
"mouse_grab": {
|
||||
"enabled": True,
|
||||
"grab_on_click": True,
|
||||
"release_on_escape": True,
|
||||
"start_grabbed": False,
|
||||
"hide_cursor": True,
|
||||
"relative_mode": True,
|
||||
"grab_mouse_button": "left",
|
||||
"release_key": "escape"
|
||||
"schema_version": 2,
|
||||
"window": {
|
||||
"title": name,
|
||||
"size": {
|
||||
"width": 1024,
|
||||
"height": 768
|
||||
},
|
||||
"mouse_grab": {
|
||||
"enabled": True,
|
||||
"grab_on_click": True,
|
||||
"release_on_escape": True,
|
||||
"start_grabbed": False,
|
||||
"hide_cursor": True,
|
||||
"relative_mode": True,
|
||||
"grab_mouse_button": "left",
|
||||
"release_key": "escape"
|
||||
}
|
||||
},
|
||||
"input_bindings": {
|
||||
"move_forward": "W",
|
||||
"move_back": "S",
|
||||
"move_left": "A",
|
||||
"move_right": "D",
|
||||
"fly_up": "Q",
|
||||
"fly_down": "Z",
|
||||
"jump": "Space",
|
||||
"noclip_toggle": "N",
|
||||
"music_toggle": "M"
|
||||
"scripts": {
|
||||
"entry": f"scripts/{project_id}_logic.lua",
|
||||
"lua_debug": False
|
||||
},
|
||||
"paths": {
|
||||
"project_root": "../",
|
||||
"scripts": "scripts",
|
||||
"shaders": "shaders"
|
||||
},
|
||||
"input": {
|
||||
"bindings": {
|
||||
"move_forward": "W",
|
||||
"move_back": "S",
|
||||
"move_left": "A",
|
||||
"move_right": "D",
|
||||
"fly_up": "Q",
|
||||
"fly_down": "Z",
|
||||
"jump": "Space",
|
||||
"noclip_toggle": "N",
|
||||
"music_toggle": "M"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lua_script": f"""-- {name} Logic Script
|
||||
@@ -1512,6 +1527,10 @@ return {{
|
||||
config_data = json.load(f)
|
||||
|
||||
lua_script_path = config_data.get("lua_script", "")
|
||||
if not lua_script_path:
|
||||
scripts_config = config_data.get("scripts", {})
|
||||
if isinstance(scripts_config, dict):
|
||||
lua_script_path = scripts_config.get("entry", "")
|
||||
if not lua_script_path:
|
||||
self.lua_editor.setPlainText("# No Lua script specified in config")
|
||||
self.lua_file_label.setText("No Lua script found")
|
||||
|
||||
+5
-3
@@ -1,5 +1,6 @@
|
||||
-- Lightweight Lua-based 2D GUI framework that emits draw commands
|
||||
-- and handles interaction for buttons, textboxes, and list views.
|
||||
local config_resolver = require("config_resolver")
|
||||
local Gui = {}
|
||||
|
||||
-- {r,g,b,a} colors
|
||||
@@ -126,14 +127,15 @@ function Context:new(options)
|
||||
options = options or {}
|
||||
local style = options.style or DEFAULT_STYLE
|
||||
if options.style == nil and type(config) == "table" then
|
||||
local guiFont = config.gui_font
|
||||
local guiFont = config_resolver.resolve_gui_font(config)
|
||||
if type(guiFont) == "table" and type(guiFont.font_size) == "number" then
|
||||
style.fontSize = guiFont.font_size
|
||||
end
|
||||
end
|
||||
local opacity = 1.0
|
||||
if type(config) == "table" and type(config.gui_opacity) == "number" then
|
||||
opacity = config.gui_opacity
|
||||
local resolvedOpacity = config_resolver.resolve_gui_opacity(config)
|
||||
if type(resolvedOpacity) == "number" then
|
||||
opacity = resolvedOpacity
|
||||
end
|
||||
local instance = {
|
||||
commands = {},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
local Gui = require('gui')
|
||||
local math3d = require('math3d')
|
||||
local config_resolver = require('config_resolver')
|
||||
|
||||
local ctx = Gui.newContext()
|
||||
local input = Gui.newInputState()
|
||||
@@ -24,7 +25,7 @@ local fpsMode = false
|
||||
local fpsToggleWasDown = false
|
||||
local fpsToggleKey = "F1"
|
||||
if type(config) == "table" then
|
||||
local bindings = config.input_bindings
|
||||
local bindings = config_resolver.resolve_input_bindings(config)
|
||||
if type(bindings) == "table" then
|
||||
local key = bindings.fps_toggle or bindings.fps_toggle_key
|
||||
if type(key) == "string" or type(key) == "number" then
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
local math3d = require("math3d")
|
||||
local config_resolver = require("config_resolver")
|
||||
|
||||
local function log_debug(fmt, ...)
|
||||
if not lua_debug or not fmt then
|
||||
@@ -59,15 +60,20 @@ local map_offset = resolve_vec3(quake3_config.offset, {0.0, 0.0, 0.0})
|
||||
local map_shader_key = nil
|
||||
if type(quake3_config.shader_key) == "string" and quake3_config.shader_key ~= "" then
|
||||
map_shader_key = quake3_config.shader_key
|
||||
elseif type(config) == "table"
|
||||
and type(config.materialx_materials) == "table"
|
||||
and type(config.materialx_materials[1]) == "table"
|
||||
and type(config.materialx_materials[1].shader_key) == "string"
|
||||
and config.materialx_materials[1].shader_key ~= "" then
|
||||
map_shader_key = config.materialx_materials[1].shader_key
|
||||
log_debug("Using MaterialX shader_key for Quake3 map=%s", map_shader_key)
|
||||
else
|
||||
error("Quake3 config requires a shader_key or materialx_materials[1].shader_key")
|
||||
local materials = config_resolver.resolve_materialx_materials(config)
|
||||
if type(materials) == "table"
|
||||
and type(materials[1]) == "table"
|
||||
and type(materials[1].shader_key) == "string"
|
||||
and materials[1].shader_key ~= "" then
|
||||
map_shader_key = materials[1].shader_key
|
||||
end
|
||||
end
|
||||
|
||||
if map_shader_key then
|
||||
log_debug("Using shader_key for Quake3 map=%s", map_shader_key)
|
||||
else
|
||||
error("Quake3 config requires a shader_key or a MaterialX materials shader_key")
|
||||
end
|
||||
|
||||
local function scale_matrix(x, y, z)
|
||||
@@ -218,7 +224,7 @@ local fallback_bindings = {
|
||||
noclip_toggle = "N",
|
||||
}
|
||||
|
||||
local input_bindings = resolve_table(type(config) == "table" and config.input_bindings)
|
||||
local input_bindings = resolve_table(config_resolver.resolve_input_bindings(config))
|
||||
local function get_binding(action_name)
|
||||
if type(input_bindings[action_name]) == "string" then
|
||||
return input_bindings[action_name]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
-- Provides mesh generation, object builders, and utility functions
|
||||
|
||||
local math3d = require("math3d")
|
||||
local config_resolver = require("config_resolver")
|
||||
|
||||
local framework = {}
|
||||
|
||||
@@ -328,8 +329,9 @@ function framework.MaterialRegistry.new(config)
|
||||
self.materials = {}
|
||||
self.default_key = nil
|
||||
|
||||
if config and config.materialx_materials then
|
||||
for i, mat in ipairs(config.materialx_materials) do
|
||||
local materials = config_resolver.resolve_materialx_materials(config)
|
||||
if type(materials) == "table" then
|
||||
for i, mat in ipairs(materials) do
|
||||
if mat.shader_key then
|
||||
self.materials[mat.shader_key] = mat
|
||||
if i == 1 then
|
||||
|
||||
+18
-7
@@ -1,10 +1,18 @@
|
||||
local Gui = require("gui")
|
||||
local math3d = require("math3d")
|
||||
local config_resolver = require("config_resolver")
|
||||
|
||||
local ctx = Gui.newContext()
|
||||
local input = Gui.newInputState()
|
||||
local statusMessage = "Select a clip to play"
|
||||
|
||||
local function log_debug(fmt, ...)
|
||||
if not lua_debug or not fmt then
|
||||
return
|
||||
end
|
||||
print(string.format(fmt, ...))
|
||||
end
|
||||
|
||||
local function findScriptDirectory()
|
||||
local info = debug.getinfo(1, "S")
|
||||
local source = info.source or ""
|
||||
@@ -247,17 +255,20 @@ local function createCube(position)
|
||||
local offset = math3d.translation(position[1], position[2], position[3])
|
||||
return math3d.multiply(offset, base)
|
||||
end
|
||||
local materials = config_resolver.resolve_materialx_materials(config)
|
||||
if type(materials) ~= "table"
|
||||
or type(materials[1]) ~= "table"
|
||||
or type(materials[1].shader_key) ~= "string"
|
||||
or materials[1].shader_key == "" then
|
||||
error("Soundboard requires rendering.materialx.materials[1].shader_key or materialx_materials[1].shader_key")
|
||||
end
|
||||
local shader_key = materials[1].shader_key
|
||||
log_debug("Soundboard using material shader_key=%s", shader_key)
|
||||
return {
|
||||
vertices = cubeVertices,
|
||||
indices = cubeIndices,
|
||||
compute_model_matrix = computeModel,
|
||||
if type(config) ~= "table" or type(config.materialx_materials) ~= "table" or
|
||||
type(config.materialx_materials[1]) ~= "table" or
|
||||
type(config.materialx_materials[1].shader_key) ~= "string" or
|
||||
config.materialx_materials[1].shader_key == "" then
|
||||
error("Soundboard requires materialx_materials[1].shader_key")
|
||||
end
|
||||
shader_keys = {config.materialx_materials[1].shader_key},
|
||||
shader_keys = {shader_key},
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -214,10 +214,14 @@ assert_equal(time_value, 42, "dynamic compute function receives time")
|
||||
print("Testing material registry...")
|
||||
|
||||
local test_config = {
|
||||
materialx_materials = {
|
||||
{shader_key = "floor", document = "floor.mtlx", material = "Floor"},
|
||||
{shader_key = "wall", document = "wall.mtlx", material = "Wall"},
|
||||
{shader_key = "ceiling", document = "ceiling.mtlx", material = "Ceiling"},
|
||||
rendering = {
|
||||
materialx = {
|
||||
materials = {
|
||||
{shader_key = "floor", document = "floor.mtlx", material = "Floor"},
|
||||
{shader_key = "wall", document = "wall.mtlx", material = "Wall"},
|
||||
{shader_key = "ceiling", document = "ceiling.mtlx", material = "Ceiling"},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user