summaryrefslogtreecommitdiff
path: root/lsfg_vk/plugin.py
blob: 000830f18dfd772249924cdc87fd959fbf310d81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
"""
Main plugin class for the lsfg-vk Decky Loader plugin.

This plugin provides services for installing and managing the lsfg-vk 
Vulkan layer for Lossless Scaling frame generation on Steam Deck.
"""

import os
from typing import Dict, Any

from .installation import InstallationService
from .dll_detection import DllDetectionService
from .configuration import ConfigurationService


class Plugin:
    """
    Main plugin class for lsfg-vk management.
    
    This class provides a unified interface for installation, configuration,
    and DLL detection services. It implements the Decky Loader plugin lifecycle
    methods (_main, _unload, _uninstall, _migration).
    """
    
    def __init__(self):
        """Initialize the plugin with all necessary services"""
        # Initialize services - they will use decky.logger by default
        self.installation_service = InstallationService()
        self.dll_detection_service = DllDetectionService()
        self.configuration_service = ConfigurationService()

    # Installation methods
    async def install_lsfg_vk(self) -> Dict[str, Any]:
        """Install lsfg-vk by extracting the zip file to ~/.local
        
        Returns:
            InstallationResponse dict with success status and message/error
        """
        return self.installation_service.install()

    async def check_lsfg_vk_installed(self) -> Dict[str, Any]:
        """Check if lsfg-vk is already installed
        
        Returns:
            InstallationCheckResponse dict with installation status and paths
        """
        return self.installation_service.check_installation()

    async def uninstall_lsfg_vk(self) -> Dict[str, Any]:
        """Uninstall lsfg-vk by removing the installed files
        
        Returns:
            UninstallationResponse dict with success status and removed files
        """
        return self.installation_service.uninstall()

    # DLL detection methods
    async def check_lossless_scaling_dll(self) -> Dict[str, Any]:
        """Check if Lossless Scaling DLL is available at the expected paths
        
        Returns:
            DllDetectionResponse dict with detection status and path info
        """
        return self.dll_detection_service.check_lossless_scaling_dll()

    # Configuration methods
    async def get_lsfg_config(self) -> Dict[str, Any]:
        """Read current lsfg script configuration
        
        Returns:
            ConfigurationResponse dict with current configuration or error
        """
        return self.configuration_service.get_config()

    async def update_lsfg_config(self, enable_lsfg: bool, multiplier: int, flow_scale: float, 
                          hdr: bool, perf_mode: bool, immediate_mode: bool) -> Dict[str, Any]:
        """Update lsfg script configuration
        
        Args:
            enable_lsfg: Whether to enable LSFG
            multiplier: LSFG multiplier value (typically 2-4)
            flow_scale: LSFG flow scale value (typically 0.5-2.0)
            hdr: Whether to enable HDR
            perf_mode: Whether to enable performance mode
            immediate_mode: Whether to enable immediate present mode (disable vsync)
            
        Returns:
            ConfigurationResponse dict with success status
        """
        return self.configuration_service.update_config(
            enable_lsfg, multiplier, flow_scale, hdr, perf_mode, immediate_mode
        )

    # Plugin lifecycle methods
    async def _main(self):
        """
        Asyncio-compatible long-running code, executed in a task when the plugin is loaded.
        
        This method is called by Decky Loader when the plugin starts up.
        Currently just logs that the plugin has loaded successfully.
        """
        import decky
        decky.logger.info("Lossless Scaling VK plugin loaded!")

    async def _unload(self):
        """
        Function called first during the unload process.
        
        This method is called by Decky Loader when the plugin is being unloaded.
        Use this for cleanup that should happen when the plugin stops.
        """
        import decky
        decky.logger.info("Lossless Scaling VK plugin unloading")

    async def _uninstall(self):
        """
        Function called after `_unload` during uninstall.
        
        This method is called by Decky Loader when the plugin is being uninstalled.
        It automatically cleans up any lsfg-vk files that were installed.
        """
        import decky
        decky.logger.info("Lossless Scaling VK plugin uninstalled - starting cleanup")
        
        # Clean up lsfg-vk files when the plugin is uninstalled
        self.installation_service.cleanup_on_uninstall()
        
        decky.logger.info("Lossless Scaling VK plugin uninstall cleanup completed")

    async def _migration(self):
        """
        Migrations that should be performed before entering `_main()`.
        
        This method is called by Decky Loader for plugin migrations.
        Currently migrates logs, settings, and runtime data from old locations.
        """
        import decky
        decky.logger.info("Running Lossless Scaling VK plugin migrations")
        
        # Migrate logs from old location
        # ~/.config/decky-lossless-scaling-vk/lossless-scaling-vk.log -> decky.DECKY_LOG_DIR/lossless-scaling-vk.log
        decky.migrate_logs(os.path.join(decky.DECKY_USER_HOME,
                                       ".config", "decky-lossless-scaling-vk", "lossless-scaling-vk.log"))
        
        # Migrate settings from old locations
        # ~/homebrew/settings/lossless-scaling-vk.json -> decky.DECKY_SETTINGS_DIR/lossless-scaling-vk.json
        # ~/.config/decky-lossless-scaling-vk/ -> decky.DECKY_SETTINGS_DIR/
        decky.migrate_settings(
            os.path.join(decky.DECKY_HOME, "settings", "lossless-scaling-vk.json"),
            os.path.join(decky.DECKY_USER_HOME, ".config", "decky-lossless-scaling-vk"))
        
        # Migrate runtime data from old locations
        # ~/homebrew/lossless-scaling-vk/ -> decky.DECKY_RUNTIME_DIR/
        # ~/.local/share/decky-lossless-scaling-vk/ -> decky.DECKY_RUNTIME_DIR/
        decky.migrate_runtime(
            os.path.join(decky.DECKY_HOME, "lossless-scaling-vk"),
            os.path.join(decky.DECKY_USER_HOME, ".local", "share", "decky-lossless-scaling-vk"))
        
        decky.logger.info("Lossless Scaling VK plugin migrations completed")