summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxXJSONDeruloXx <danielhimebauch@gmail.com>2025-07-22 12:11:53 -0400
committerxXJSONDeruloXx <danielhimebauch@gmail.com>2025-07-22 12:11:53 -0400
commitf8139896f2077a95a78a54c818637f78dd102de8 (patch)
tree1ae4b236c66e0160c363c5ab8e7bafb84fb1fdb1
parentdfe4c033dd1922a63c8393ab467e9aa58fa757e4 (diff)
downloaddecky-lsfg-vk-f8139896f2077a95a78a54c818637f78dd102de8.tar.gz
decky-lsfg-vk-f8139896f2077a95a78a54c818637f78dd102de8.zip
consolidate toml and script values
-rw-r--r--py_modules/lsfg_vk/config_schema.py54
-rw-r--r--py_modules/lsfg_vk/configuration.py55
-rw-r--r--py_modules/lsfg_vk/plugin.py17
-rw-r--r--shared_config.py49
-rw-r--r--src/components/ConfigurationSection.tsx32
-rw-r--r--src/config/generatedConfigSchema.ts18
-rw-r--r--tests/test_configuration.py0
7 files changed, 161 insertions, 64 deletions
diff --git a/py_modules/lsfg_vk/config_schema.py b/py_modules/lsfg_vk/config_schema.py
index 6a68db1..eac5a91 100644
--- a/py_modules/lsfg_vk/config_schema.py
+++ b/py_modules/lsfg_vk/config_schema.py
@@ -52,42 +52,16 @@ CONFIG_SCHEMA["dll"] = ConfigField(
description="specify where Lossless.dll is stored"
)
-# Fields that should ONLY be in the lsfg script, not in TOML config
+# Get script-only fields dynamically from shared config
SCRIPT_ONLY_FIELDS = {
- "dxvk_frame_rate": ConfigField(
- name="dxvk_frame_rate",
- field_type=ConfigFieldType.INTEGER,
- default=0,
- description="base framerate cap for DirectX games, before frame multiplier (0 = disabled, requires game re-launch)"
- ),
-
- "enable_wow64": ConfigField(
- name="enable_wow64",
- field_type=ConfigFieldType.BOOLEAN,
- default=False,
- description="enable PROTON_USE_WOW64=1 for 32-bit games (use with ProtonGE to fix crashing)"
- ),
-
- "disable_steamdeck_mode": ConfigField(
- name="disable_steamdeck_mode",
- field_type=ConfigFieldType.BOOLEAN,
- default=False,
- description="disable Steam Deck mode (unlocks hidden settings in some games)"
- ),
-
- "mangohud_workaround": ConfigField(
- name="mangohud_workaround",
- field_type=ConfigFieldType.BOOLEAN,
- default=False,
- description="Enables a transparent mangohud overlay, sometimes fixes issues with 2X multiplier in game mode"
- ),
-
- "disable_vkbasalt": ConfigField(
- name="disable_vkbasalt",
- field_type=ConfigFieldType.BOOLEAN,
- default=False,
- description="Disables vkBasalt layer which can conflict with LSFG (Reshade, some Decky plugins)"
+ field_name: ConfigField(
+ name=field_def["name"],
+ field_type=ConfigFieldType(field_def["fieldType"]),
+ default=field_def["default"],
+ description=field_def["description"]
)
+ for field_name, field_def in CONFIG_SCHEMA_DEF.items()
+ if field_def.get("location") == "script"
}
# Complete configuration schema (TOML + script-only fields)
@@ -107,6 +81,8 @@ class ConfigurationData(TypedDict):
disable_steamdeck_mode: bool
mangohud_workaround: bool
disable_vkbasalt: bool
+ foobar_toggle: bool
+ test_config_only: str
class ConfigurationManager:
@@ -355,6 +331,8 @@ class ConfigurationManager:
script_values["mangohud_workaround"] = value == "1"
elif key == "DISABLE_VKBASALT":
script_values["disable_vkbasalt"] = value == "1"
+ elif key == "FOOBAR":
+ script_values["foobar_toggle"] = value == "1"
except (ValueError, KeyError, IndexError) as e:
# If parsing fails, log the error and return empty dict (will use defaults)
@@ -390,7 +368,9 @@ class ConfigurationManager:
enable_wow64: bool = False,
disable_steamdeck_mode: bool = False,
mangohud_workaround: bool = False,
- disable_vkbasalt: bool = False) -> ConfigurationData:
+ disable_vkbasalt: bool = False,
+ foobar_toggle: bool = False,
+ test_config_only: str = "default_value") -> ConfigurationData:
"""Create configuration from individual arguments"""
return cast(ConfigurationData, {
"dll": dll,
@@ -403,5 +383,7 @@ class ConfigurationManager:
"enable_wow64": enable_wow64,
"disable_steamdeck_mode": disable_steamdeck_mode,
"mangohud_workaround": mangohud_workaround,
- "disable_vkbasalt": disable_vkbasalt
+ "disable_vkbasalt": disable_vkbasalt,
+ "foobar_toggle": foobar_toggle,
+ "test_config_only": test_config_only
})
diff --git a/py_modules/lsfg_vk/configuration.py b/py_modules/lsfg_vk/configuration.py
index 68ff577..b4c7994 100644
--- a/py_modules/lsfg_vk/configuration.py
+++ b/py_modules/lsfg_vk/configuration.py
@@ -60,6 +60,47 @@ class ConfigurationService(BaseService):
f"Using default configuration due to parse error: {str(e)}",
config=config)
+ def update_config_from_dict(self, config: ConfigurationData) -> ConfigurationResponse:
+ """Update TOML configuration from configuration dictionary (eliminates parameter duplication)
+
+ Args:
+ config: Complete configuration data dictionary
+
+ Returns:
+ ConfigurationResponse with success status
+ """
+ try:
+ # Generate TOML content using centralized manager
+ toml_content = ConfigurationManager.generate_toml_content(config)
+
+ # Ensure config directory exists
+ self.config_dir.mkdir(parents=True, exist_ok=True)
+
+ # Write the updated config directly to preserve inode for file watchers
+ self._write_file(self.config_file_path, toml_content, 0o644)
+
+ # Update the launch script with the new configuration
+ script_result = self.update_lsfg_script(config)
+ if not script_result["success"]:
+ self.log.warning(f"Failed to update launch script: {script_result['error']}")
+
+ # Log with dynamic field listing
+ field_values = ", ".join(f"{k}={repr(v)}" for k, v in config.items())
+ self.log.info(f"Updated lsfg configuration: {field_values}")
+
+ return self._success_response(ConfigurationResponse,
+ "lsfg configuration updated successfully",
+ config=config)
+
+ except (OSError, IOError) as e:
+ error_msg = f"Error updating lsfg config: {str(e)}"
+ self.log.error(error_msg)
+ return self._error_response(ConfigurationResponse, str(e), config=None)
+ except ValueError as e:
+ error_msg = f"Invalid configuration arguments: {str(e)}"
+ self.log.error(error_msg)
+ return self._error_response(ConfigurationResponse, str(e), config=None)
+
def update_config(self, dll: str, multiplier: int, flow_scale: float,
performance_mode: bool, hdr_mode: bool,
experimental_present_mode: str = "fifo",
@@ -67,7 +108,9 @@ class ConfigurationService(BaseService):
enable_wow64: bool = False,
disable_steamdeck_mode: bool = False,
mangohud_workaround: bool = False,
- disable_vkbasalt: bool = False) -> ConfigurationResponse:
+ disable_vkbasalt: bool = False,
+ foobar_toggle: bool = False,
+ test_config_only: str = "default_value") -> ConfigurationResponse:
"""Update TOML configuration
Args:
@@ -82,6 +125,8 @@ class ConfigurationService(BaseService):
disable_steamdeck_mode: Whether to disable Steam Deck mode
mangohud_workaround: Whether to enable MangoHud workaround with transparent overlay
disable_vkbasalt: Whether to disable vkBasalt layer
+ foobar_toggle: Test script-only toggle that exports FOOBAR=1
+ test_config_only: Test TOML-only configuration field
Returns:
ConfigurationResponse with success status
@@ -91,7 +136,7 @@ class ConfigurationService(BaseService):
config = ConfigurationManager.create_config_from_args(
dll, multiplier, flow_scale, performance_mode, hdr_mode,
experimental_present_mode, dxvk_frame_rate, enable_wow64, disable_steamdeck_mode,
- mangohud_workaround, disable_vkbasalt
+ mangohud_workaround, disable_vkbasalt, foobar_toggle, test_config_only
)
# Generate TOML content using centralized manager
@@ -114,7 +159,8 @@ class ConfigurationService(BaseService):
f"experimental_present_mode='{experimental_present_mode}', "
f"dxvk_frame_rate={dxvk_frame_rate}, "
f"enable_wow64={enable_wow64}, disable_steamdeck_mode={disable_steamdeck_mode}, "
- f"mangohud_workaround={mangohud_workaround}, disable_vkbasalt={disable_vkbasalt}")
+ f"mangohud_workaround={mangohud_workaround}, disable_vkbasalt={disable_vkbasalt}, "
+ f"foobar_toggle={foobar_toggle}, test_config_only='{test_config_only}'")
return self._success_response(ConfigurationResponse,
"lsfg configuration updated successfully",
@@ -227,6 +273,9 @@ class ConfigurationService(BaseService):
if config.get("disable_vkbasalt", False):
lines.append("export DISABLE_VKBASALT=1")
+ if config.get("foobar_toggle", False):
+ lines.append("export FOOBAR=1")
+
# Add DXVK_FRAME_RATE if dxvk_frame_rate is set
dxvk_frame_rate = config.get("dxvk_frame_rate", 0)
if dxvk_frame_rate > 0:
diff --git a/py_modules/lsfg_vk/plugin.py b/py_modules/lsfg_vk/plugin.py
index d126d84..8fa2435 100644
--- a/py_modules/lsfg_vk/plugin.py
+++ b/py_modules/lsfg_vk/plugin.py
@@ -185,7 +185,7 @@ class Plugin:
}
async def update_lsfg_config(self, config: Dict[str, Any]) -> Dict[str, Any]:
- """Update lsfg TOML configuration using object-based API
+ """Update lsfg TOML configuration using object-based API (single source of truth)
Args:
config: Configuration data dictionary containing all settings
@@ -196,19 +196,8 @@ class Plugin:
# Validate and extract configuration from the config dict
validated_config = ConfigurationManager.validate_config(config)
- return self.configuration_service.update_config(
- dll=validated_config["dll"],
- multiplier=validated_config["multiplier"],
- flow_scale=validated_config["flow_scale"],
- performance_mode=validated_config["performance_mode"],
- hdr_mode=validated_config["hdr_mode"],
- experimental_present_mode=validated_config["experimental_present_mode"],
- dxvk_frame_rate=validated_config["dxvk_frame_rate"],
- enable_wow64=validated_config["enable_wow64"],
- disable_steamdeck_mode=validated_config["disable_steamdeck_mode"],
- mangohud_workaround=validated_config["mangohud_workaround"],
- disable_vkbasalt=validated_config["disable_vkbasalt"]
- )
+ # Use dynamic parameter passing based on schema
+ return self.configuration_service.update_config_from_dict(validated_config)
async def update_dll_path(self, dll_path: str) -> Dict[str, Any]:
"""Update the DLL path in the configuration when detected
diff --git a/shared_config.py b/shared_config.py
index 518294d..ca9172f 100644
--- a/shared_config.py
+++ b/shared_config.py
@@ -24,77 +24,104 @@ CONFIG_SCHEMA_DEF = {
"name": "dll",
"fieldType": ConfigFieldType.STRING,
"default": "/games/Lossless Scaling/Lossless.dll",
- "description": "specify where Lossless.dll is stored"
+ "description": "specify where Lossless.dll is stored",
+ "location": "toml" # where this field is stored/used
},
"multiplier": {
"name": "multiplier",
"fieldType": ConfigFieldType.INTEGER,
"default": 1,
- "description": "change the fps multiplier"
+ "description": "change the fps multiplier",
+ "location": "toml"
},
"flow_scale": {
"name": "flow_scale",
"fieldType": ConfigFieldType.FLOAT,
"default": 0.8,
- "description": "change the flow scale"
+ "description": "change the flow scale",
+ "location": "toml"
},
"performance_mode": {
"name": "performance_mode",
"fieldType": ConfigFieldType.BOOLEAN,
"default": True,
- "description": "use a lighter model for FG (recommended for most games)"
+ "description": "use a lighter model for FG (recommended for most games)",
+ "location": "toml"
},
"hdr_mode": {
"name": "hdr_mode",
"fieldType": ConfigFieldType.BOOLEAN,
"default": False,
- "description": "enable HDR mode (only for games that support HDR)"
+ "description": "enable HDR mode (only for games that support HDR)",
+ "location": "toml"
},
"experimental_present_mode": {
"name": "experimental_present_mode",
"fieldType": ConfigFieldType.STRING,
"default": "fifo",
- "description": "override Vulkan present mode (may cause crashes)"
+ "description": "override Vulkan present mode (may cause crashes)",
+ "location": "toml"
},
"dxvk_frame_rate": {
"name": "dxvk_frame_rate",
"fieldType": ConfigFieldType.INTEGER,
"default": 0,
- "description": "base framerate cap for DirectX games before frame multiplier"
+ "description": "base framerate cap for DirectX games before frame multiplier",
+ "location": "script" # script-only field
},
"enable_wow64": {
"name": "enable_wow64",
"fieldType": ConfigFieldType.BOOLEAN,
"default": False,
- "description": "enable PROTON_USE_WOW64=1 for 32-bit games (use with ProtonGE to fix crashing)"
+ "description": "enable PROTON_USE_WOW64=1 for 32-bit games (use with ProtonGE to fix crashing)",
+ "location": "script"
},
"disable_steamdeck_mode": {
"name": "disable_steamdeck_mode",
"fieldType": ConfigFieldType.BOOLEAN,
"default": False,
- "description": "disable Steam Deck mode (unlocks hidden settings in some games)"
+ "description": "disable Steam Deck mode (unlocks hidden settings in some games)",
+ "location": "script"
},
"mangohud_workaround": {
"name": "mangohud_workaround",
"fieldType": ConfigFieldType.BOOLEAN,
"default": False,
- "description": "Enables a transparent mangohud overlay, sometimes fixes issues with 2X multiplier in game mode"
+ "description": "Enables a transparent mangohud overlay, sometimes fixes issues with 2X multiplier in game mode",
+ "location": "script"
},
"disable_vkbasalt": {
"name": "disable_vkbasalt",
"fieldType": ConfigFieldType.BOOLEAN,
"default": False,
- "description": "Disables vkBasalt layer which can conflict with LSFG (Reshade, some Decky plugins)"
+ "description": "Disables vkBasalt layer which can conflict with LSFG (Reshade, some Decky plugins)",
+ "location": "script"
+ },
+
+ "foobar_toggle": {
+ "name": "foobar_toggle",
+ "fieldType": ConfigFieldType.BOOLEAN,
+ "default": False,
+ "description": "Test script-only toggle that exports FOOBAR=1 (for testing purposes)",
+ "location": "script"
+ },
+
+ "test_config_only": {
+ "name": "test_config_only",
+ "fieldType": ConfigFieldType.STRING,
+ "default": "default_value",
+ "description": "Test TOML-only configuration field (not in script)",
+ "location": "toml"
}
}
diff --git a/src/components/ConfigurationSection.tsx b/src/components/ConfigurationSection.tsx
index 1c0d2b2..3f15bac 100644
--- a/src/components/ConfigurationSection.tsx
+++ b/src/components/ConfigurationSection.tsx
@@ -182,6 +182,38 @@ export function ConfigurationSection({
onChange={(value) => onConfigChange('disable_vkbasalt', value)}
/>
</PanelSectionRow>
+
+ <PanelSectionRow>
+ <ToggleField
+ label="Foobar Toggle (Test)"
+ description="Test script-only toggle that exports FOOBAR=1 (for testing purposes)"
+ checked={config.foobar_toggle}
+ onChange={(value) => onConfigChange('foobar_toggle', value)}
+ />
+ </PanelSectionRow>
+
+ <PanelSectionRow>
+ <div>
+ <div style={{ marginBottom: "8px", fontSize: "14px" }}>Test Config Only Field</div>
+ <input
+ type="text"
+ value={config.test_config_only}
+ onChange={(e) => onConfigChange('test_config_only', e.target.value)}
+ placeholder="Enter test value"
+ style={{
+ width: "100%",
+ padding: "8px",
+ borderRadius: "4px",
+ border: "1px solid #4c4c4c",
+ backgroundColor: "#2d2d2d",
+ color: "#ffffff"
+ }}
+ />
+ <div style={{ fontSize: "12px", color: "#999", marginTop: "4px" }}>
+ Test TOML-only configuration field (not in script)
+ </div>
+ </div>
+ </PanelSectionRow>
</>
);
}
diff --git a/src/config/generatedConfigSchema.ts b/src/config/generatedConfigSchema.ts
index cb08252..b7487bd 100644
--- a/src/config/generatedConfigSchema.ts
+++ b/src/config/generatedConfigSchema.ts
@@ -83,6 +83,18 @@ export const CONFIG_SCHEMA: Record<string, ConfigField> = {
default: false,
description: "Disables vkBasalt layer which can conflict with LSFG (Reshade, some Decky plugins)"
},
+ foobar_toggle: {
+ name: "foobar_toggle",
+ fieldType: ConfigFieldType.BOOLEAN,
+ default: false,
+ description: "Test script-only toggle that exports FOOBAR=1 (for testing purposes)"
+ },
+ test_config_only: {
+ name: "test_config_only",
+ fieldType: ConfigFieldType.STRING,
+ default: "default_value",
+ description: "Test TOML-only configuration field (not in script)"
+ },
};
// Type-safe configuration data structure
@@ -98,6 +110,8 @@ export interface ConfigurationData {
disable_steamdeck_mode: boolean;
mangohud_workaround: boolean;
disable_vkbasalt: boolean;
+ foobar_toggle: boolean;
+ test_config_only: string;
}
// Helper functions
@@ -118,6 +132,8 @@ export function getDefaults(): ConfigurationData {
disable_steamdeck_mode: false,
mangohud_workaround: false,
disable_vkbasalt: false,
+ foobar_toggle: false,
+ test_config_only: "default_value",
};
}
@@ -134,6 +150,8 @@ export function getFieldTypes(): Record<string, ConfigFieldType> {
disable_steamdeck_mode: ConfigFieldType.BOOLEAN,
mangohud_workaround: ConfigFieldType.BOOLEAN,
disable_vkbasalt: ConfigFieldType.BOOLEAN,
+ foobar_toggle: ConfigFieldType.BOOLEAN,
+ test_config_only: ConfigFieldType.STRING,
};
}
diff --git a/tests/test_configuration.py b/tests/test_configuration.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/test_configuration.py