Skip to content

Commit ab6dbdc

Browse files
committed
Important save detection + LiveSplit commands fixes
1 parent f3e3911 commit ab6dbdc

File tree

8 files changed

+25
-22
lines changed

8 files changed

+25
-22
lines changed

scripts/build.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ $arguments = @(
99
'--splash=res/splash.png',
1010
# The install script should ensure that these are not installed
1111
# But we'll still include unused dependencies that would be picked up by PyInstaller
12-
# if requirements.txt was used directly to help ensure consistency when buildign locally.
12+
# if requirements.txt was used directly to help ensure consistency when building locally.
1313
#
1414
# Installed by PyAutoGUI
1515
'--exclude=pyscreeze',

scripts/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Pillow>=10.0 # Python 3.12 support
1313
psutil>=5.9.6 # Python 3.12 fixes
1414
PyAutoGUI
1515
PyWinCtl>=0.0.42 # py.typed
16-
# When needed, dev builds can be found at https://download.qt.io/snapshots/ci/pyside/dev
16+
# When needed, dev builds can be found at https://download.qt.io/snapshots/ci/pyside/dev?C=M;O=D
1717
PySide6-Essentials>=6.6.0 # Python 3.12 support
1818
requests>=2.28.2 # charset_normalizer 3.x update
1919
toml

src/AutoSplit.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import signal
55
import sys
66
from collections.abc import Callable
7+
from copy import deepcopy
78
from time import time
89
from types import FunctionType
910
from typing import NoReturn
@@ -50,8 +51,6 @@
5051
open_file,
5152
)
5253

53-
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = 2
54-
5554
# Needed when compiled, along with the custom hook-requests PyInstaller hook
5655
os.environ["REQUESTS_CA_BUNDLE"] = certifi.where()
5756
myappid = f"Toufool.AutoSplit.v{AUTOSPLIT_VERSION}"
@@ -93,18 +92,16 @@ def __init__(self): # noqa: PLR0915
9392
# Initialize a few attributes
9493
self.hwnd = 0
9594
"""Window Handle used for Capture Region"""
96-
self.last_saved_settings = DEFAULT_PROFILE
95+
self.last_saved_settings = deepcopy(DEFAULT_PROFILE)
9796
self.similarity = 0.0
9897
self.split_image_number = 0
9998
self.split_images_and_loop_number: list[tuple[AutoSplitImage, int]] = []
10099
self.split_groups: list[list[int]] = []
101100
self.capture_method = CaptureMethodBase(self)
102101
self.is_running = False
103102

104-
# Last loaded settings empty and last successful loaded settings file path to None until we try to load them
105-
self.last_loaded_settings = DEFAULT_PROFILE
106-
self.last_successfully_loaded_settings_file_path: str | None = None
107-
"""For when a file has never loaded, but you successfully "Save File As"."""
103+
self.last_successfully_loaded_settings_file_path = ""
104+
"""Path of the settings file to default to. `None` until we try to load once."""
108105

109106
# Automatic timer start
110107
self.highest_similarity = 0.0

src/capture_method/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class CaptureMethodEnum(Enum, metaclass=CaptureMethodMeta):
4747
def __repr__(self):
4848
return self.value
4949

50+
# Allow direct comparison with strings
5051
@override
5152
def __eq__(self, other: object):
5253
if isinstance(other, str):

src/hotkeys.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def send_command(autosplit: "AutoSplit", command: Commands):
5252
# having the reset image check be active at all time would be a better, more organic solution,
5353
# but that is dependent on migrating to an observer pattern (#219) and being able to reload all images.
5454
match command:
55-
case _ if autosplit.settings_dict["start_also_resets"]:
55+
case _ if autosplit.is_auto_controlled:
5656
if command == "start" and autosplit.settings_dict["start_also_resets"]:
5757
print("reset", flush=True)
5858
print(command, flush=True)
@@ -164,7 +164,7 @@ def __get_hotkey_name(names: list[str]):
164164
Uses keyboard.get_hotkey_name but works with non-english modifiers and keypad
165165
See: https://github.com/boppreh/keyboard/issues/516 .
166166
"""
167-
if not names:
167+
if not names: # 0-length
168168
return ""
169169

170170
if len(names) == 1:

src/split_parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def __value_from_filename(
3131
raise ValueError("delimiters parameter must contain exactly 2 characters")
3232
try:
3333
string_value = filename.split(delimiters[0], 1)[1].split(delimiters[1])[0]
34-
value: T = type(default_value)(string_value)
34+
value = type(default_value)(string_value)
3535
except (IndexError, ValueError):
3636
return default_value
3737
else:

src/user_profile.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import os
2+
from copy import deepcopy
23
from typing import TYPE_CHECKING, TypedDict, cast
34

45
import toml
56
from PySide6 import QtCore, QtWidgets
7+
from typing_extensions import deprecated, override
68

79
import error_messages
810
from capture_method import CAPTURE_METHODS, CaptureMethodEnum, Region, change_capture_method
@@ -40,6 +42,10 @@ class UserProfileDict(TypedDict):
4042
captured_window_title: str
4143
capture_region: Region
4244

45+
@override # pyright: ignore
46+
@deprecated("Use `copy.deepcopy` instead")
47+
def copy(): return super().copy()
48+
4349

4450
DEFAULT_PROFILE = UserProfileDict(
4551
split_hotkey="",
@@ -70,10 +76,7 @@ class UserProfileDict(TypedDict):
7076

7177

7278
def have_settings_changed(autosplit: "AutoSplit"):
73-
return (
74-
autosplit.settings_dict != autosplit.last_saved_settings
75-
or autosplit.settings_dict != autosplit.last_loaded_settings
76-
)
79+
return autosplit.settings_dict != autosplit.last_saved_settings
7780

7881

7982
def save_settings(autosplit: "AutoSplit"):
@@ -95,6 +98,7 @@ def save_settings_as(autosplit: "AutoSplit"):
9598
or os.path.join(auto_split_directory, "settings.toml"),
9699
"TOML (*.toml)",
97100
)[0]
101+
98102
# If user cancels save destination window, don't save settings
99103
if not save_settings_file_path:
100104
return ""
@@ -103,10 +107,10 @@ def save_settings_as(autosplit: "AutoSplit"):
103107

104108

105109
def __save_settings_to_file(autosplit: "AutoSplit", save_settings_file_path: str):
106-
autosplit.last_saved_settings = autosplit.settings_dict
107110
# Save settings to a .toml file
108111
with open(save_settings_file_path, "w", encoding="utf-8") as file:
109-
toml.dump(autosplit.last_saved_settings, file)
112+
toml.dump(autosplit.settings_dict, file)
113+
autosplit.last_saved_settings = deepcopy(autosplit.settings_dict)
110114
autosplit.last_successfully_loaded_settings_file_path = save_settings_file_path
111115
return save_settings_file_path
112116

@@ -120,9 +124,10 @@ def __load_settings_from_file(autosplit: "AutoSplit", load_settings_file_path: s
120124
# Casting here just so we can build an actual UserProfileDict once we're done validating
121125
# Fallback to default settings if some are missing from the file. This happens when new settings are added.
122126
loaded_settings = DEFAULT_PROFILE | cast(UserProfileDict, toml.load(file))
127+
123128
# TODO: Data Validation / fallbacks ?
124129
autosplit.settings_dict = UserProfileDict(**loaded_settings)
125-
autosplit.last_loaded_settings = autosplit.settings_dict
130+
autosplit.last_saved_settings = deepcopy(autosplit.settings_dict)
126131

127132
autosplit.x_spinbox.setValue(autosplit.settings_dict["capture_region"]["x"])
128133
autosplit.y_spinbox.setValue(autosplit.settings_dict["capture_region"]["y"])

src/utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131
DWMWA_EXTENDED_FRAME_BOUNDS = 9
3232
MAXBYTE = 255
3333
BGR_CHANNEL_COUNT = 3
34-
"""How many channels in an RGB image"""
34+
"""How many channels in a BGR image"""
3535
BGRA_CHANNEL_COUNT = 4
36-
"""How many channels in an RGBA image"""
36+
"""How many channels in a BGRA image"""
3737

3838

3939
class ImageShape(IntEnum):
@@ -68,7 +68,7 @@ def is_valid_image(image: MatLike | None) -> TypeGuard[MatLike]:
6868
return image is not None and bool(image.size)
6969

7070

71-
def is_valid_hwnd(hwnd: int) -> bool:
71+
def is_valid_hwnd(hwnd: int):
7272
"""Validate the hwnd points to a valid window and not the desktop or whatever window obtained with `""`."""
7373
if not hwnd:
7474
return False

0 commit comments

Comments
 (0)