diff options
Diffstat (limited to 'py_modules/lsfg_vk/configuration.py')
| -rw-r--r-- | py_modules/lsfg_vk/configuration.py | 197 |
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) + } |
