summaryrefslogtreecommitdiff
path: root/py_modules/lsfg_vk/configuration.py
diff options
context:
space:
mode:
Diffstat (limited to 'py_modules/lsfg_vk/configuration.py')
-rw-r--r--py_modules/lsfg_vk/configuration.py197
1 files changed, 104 insertions, 93 deletions
diff --git a/py_modules/lsfg_vk/configuration.py b/py_modules/lsfg_vk/configuration.py
index 8be7b47..255092a 100644
--- a/py_modules/lsfg_vk/configuration.py
+++ b/py_modules/lsfg_vk/configuration.py
@@ -1,8 +1,7 @@
"""
-Configuration service for lsfg script management.
+Configuration service for TOML-based lsfg configuration management.
"""
-import re
from pathlib import Path
from typing import Dict, Any
@@ -12,25 +11,29 @@ from .types import ConfigurationResponse
class ConfigurationService(BaseService):
- """Service for managing lsfg script configuration"""
+ """Service for managing TOML-based lsfg configuration"""
def get_config(self) -> ConfigurationResponse:
- """Read current lsfg script configuration
+ """Read current TOML configuration
Returns:
ConfigurationResponse with current configuration or error
"""
try:
- if not self.lsfg_script_path.exists():
+ if not self.config_file_path.exists():
+ # Return default configuration with DLL detection if file doesn't exist
+ from .dll_detection import DllDetectionService
+ dll_service = DllDetectionService(self.log)
+ config = ConfigurationManager.get_defaults_with_dll_detection(dll_service)
return {
- "success": False,
- "config": None,
- "message": None,
- "error": "lsfg script not found"
+ "success": True,
+ "config": config,
+ "message": "Using default configuration (config file not found)",
+ "error": None
}
- content = self.lsfg_script_path.read_text()
- config = self._parse_script_content(content)
+ content = self.config_file_path.read_text(encoding='utf-8')
+ config = ConfigurationManager.parse_toml_content(content)
return {
"success": True,
@@ -48,83 +51,35 @@ class ConfigurationService(BaseService):
"message": None,
"error": str(e)
}
+ except Exception as e:
+ error_msg = f"Error parsing config file: {str(e)}"
+ self.log.error(error_msg)
+ # Return defaults with DLL detection if parsing fails
+ from .dll_detection import DllDetectionService
+ dll_service = DllDetectionService(self.log)
+ config = ConfigurationManager.get_defaults_with_dll_detection(dll_service)
+ return {
+ "success": True,
+ "config": config,
+ "message": f"Using default configuration due to parse error: {str(e)}",
+ "error": None
+ }
- def _parse_script_content(self, content: str) -> ConfigurationData:
- """Parse script content to extract configuration values
-
- Args:
- content: Script file content
-
- Returns:
- ConfigurationData with parsed values
- """
- # Start with defaults
- config = ConfigurationManager.get_defaults()
-
- lines = content.split('\n')
- for line in lines:
- line = line.strip()
-
- # Parse ENABLE_LSFG
- if match := re.match(r'^(#\s*)?export\s+ENABLE_LSFG=(\d+)', line):
- config["enable_lsfg"] = not bool(match.group(1)) and match.group(2) == '1'
-
- # Parse LSFG_MULTIPLIER
- elif match := re.match(r'^export\s+LSFG_MULTIPLIER=(\d+)', line):
- try:
- config["multiplier"] = int(match.group(1))
- except ValueError:
- pass
-
- # Parse LSFG_FLOW_SCALE
- elif match := re.match(r'^export\s+LSFG_FLOW_SCALE=([0-9]*\.?[0-9]+)', line):
- try:
- config["flow_scale"] = float(match.group(1))
- except ValueError:
- pass
-
- # Parse LSFG_HDR
- elif match := re.match(r'^(#\s*)?export\s+LSFG_HDR=(\d+)', line):
- config["hdr"] = not bool(match.group(1)) and match.group(2) == '1'
-
- # Parse LSFG_PERF_MODE
- elif match := re.match(r'^(#\s*)?export\s+LSFG_PERF_MODE=(\d+)', line):
- config["perf_mode"] = not bool(match.group(1)) and match.group(2) == '1'
-
- # Parse MESA_VK_WSI_PRESENT_MODE
- elif match := re.match(r'^(#\s*)?export\s+MESA_VK_WSI_PRESENT_MODE=([^\s#]+)', line):
- config["immediate_mode"] = not bool(match.group(1)) and match.group(2) == 'immediate'
-
- # Parse DISABLE_VKBASALT
- elif match := re.match(r'^(#\s*)?export\s+DISABLE_VKBASALT=(\d+)', line):
- config["disable_vkbasalt"] = not bool(match.group(1)) and match.group(2) == '1'
-
- # Parse DXVK_FRAME_RATE
- elif match := re.match(r'^(#\s*)?export\s+DXVK_FRAME_RATE=(\d+)', line):
- if not bool(match.group(1)): # Not commented out
- try:
- config["frame_cap"] = int(match.group(2))
- except ValueError:
- pass
- else:
- # If it's commented out, frame cap is disabled (0)
- config["frame_cap"] = 0
-
- return config
-
- def update_config(self, enable_lsfg: bool, multiplier: int, flow_scale: float,
- hdr: bool, perf_mode: bool, immediate_mode: bool, disable_vkbasalt: bool, frame_cap: int) -> ConfigurationResponse:
- """Update lsfg script configuration
+ def update_config(self, enable: bool, dll: str, multiplier: int, flow_scale: float,
+ performance_mode: bool, hdr_mode: bool,
+ experimental_present_mode: str = "",
+ experimental_fps_limit: int = 0) -> ConfigurationResponse:
+ """Update TOML configuration
Args:
- enable_lsfg: Whether to enable LSFG
+ enable: Whether to enable LSFG
+ dll: Path to Lossless.dll
multiplier: LSFG multiplier value
flow_scale: LSFG flow scale value
- hdr: Whether to enable HDR
- perf_mode: Whether to enable performance mode
- immediate_mode: Whether to enable immediate present mode (disable vsync)
- disable_vkbasalt: Whether to disable vkbasalt layer
- frame_cap: Frame rate cap value (0-60, 0 = disabled)
+ performance_mode: Whether to enable performance mode
+ hdr_mode: Whether to enable HDR mode
+ experimental_present_mode: Experimental Vulkan present mode override
+ experimental_fps_limit: Experimental FPS limit for DXVK games
Returns:
ConfigurationResponse with success status
@@ -132,23 +87,28 @@ class ConfigurationService(BaseService):
try:
# Create configuration from individual arguments
config = ConfigurationManager.create_config_from_args(
- enable_lsfg, multiplier, flow_scale, hdr, perf_mode, immediate_mode, disable_vkbasalt, frame_cap
+ enable, dll, multiplier, flow_scale, performance_mode, hdr_mode,
+ experimental_present_mode, experimental_fps_limit
)
- # Generate script content using centralized manager
- script_content = ConfigurationManager.generate_script_content(config)
+ # Generate TOML content using centralized manager
+ toml_content = ConfigurationManager.generate_toml_content(config)
- # Write the updated script atomically
- self._atomic_write(self.lsfg_script_path, script_content, 0o755)
+ # Ensure config directory exists
+ self.config_dir.mkdir(parents=True, exist_ok=True)
- self.log.info(f"Updated lsfg script configuration: enable_lsfg={enable_lsfg}, "
- f"multiplier={multiplier}, flow_scale={flow_scale}, hdr={hdr}, "
- f"perf_mode={perf_mode}, immediate_mode={immediate_mode}, "
- f"disable_vkbasalt={disable_vkbasalt}, frame_cap={frame_cap}")
+ # Write the updated config directly to preserve inode for file watchers
+ self._write_file(self.config_file_path, toml_content, 0o644)
+
+ self.log.info(f"Updated lsfg TOML configuration: enable={enable}, "
+ f"dll='{dll}', multiplier={multiplier}, flow_scale={flow_scale}, "
+ f"performance_mode={performance_mode}, hdr_mode={hdr_mode}, "
+ f"experimental_present_mode='{experimental_present_mode}', "
+ f"experimental_fps_limit={experimental_fps_limit}")
return {
"success": True,
- "config": None,
+ "config": config,
"message": "lsfg configuration updated successfully",
"error": None
}
@@ -171,3 +131,54 @@ class ConfigurationService(BaseService):
"message": None,
"error": str(e)
}
+
+ def update_dll_path(self, dll_path: str) -> ConfigurationResponse:
+ """Update just the DLL path in the configuration
+
+ Args:
+ dll_path: Path to the Lossless.dll file
+
+ Returns:
+ ConfigurationResponse with success status
+ """
+ try:
+ # Get current config
+ current_response = self.get_config()
+ if not current_response["success"] or current_response["config"] is None:
+ # If we can't read current config, use defaults with DLL detection
+ from .dll_detection import DllDetectionService
+ dll_service = DllDetectionService(self.log)
+ config = ConfigurationManager.get_defaults_with_dll_detection(dll_service)
+ else:
+ config = current_response["config"]
+
+ # Update just the DLL path
+ config["dll"] = dll_path
+
+ # Generate TOML content and write it
+ 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)
+
+ self.log.info(f"Updated DLL path in lsfg configuration: '{dll_path}'")
+
+ return {
+ "success": True,
+ "config": config,
+ "message": f"DLL path updated to: {dll_path}",
+ "error": None
+ }
+
+ except Exception as e:
+ error_msg = f"Error updating DLL path: {str(e)}"
+ self.log.error(error_msg)
+ return {
+ "success": False,
+ "config": None,
+ "message": None,
+ "error": str(e)
+ }