diff --git a/Makefile.dev b/Makefile.dev index 3b4a042..489c670 100644 --- a/Makefile.dev +++ b/Makefile.dev @@ -216,3 +216,11 @@ rasp-force-rebuild: ## rm remote project/build .PHONY: rasp-import-logs rasp-import-logs: ## import remote logs cp -f $(RASP_PROJECT_PATH)/*.log . + +.PHONY: rasp-install-saves +rasp-install-saves: ## install local saves to remote + cp -f forge_default_save*.txt $(RASP_PROJECT_PATH) + +.PHONY: rasp-import-saves +rasp-import-saves: ## import remote saves + cp -f $(RASP_PROJECT_PATH)/forge_default_save*.txt* . diff --git a/resources/background.png b/resources/background.png index 2f5c6c9..5b76dcb 100644 Binary files a/resources/background.png and b/resources/background.png differ diff --git a/src/forge_invar/constants.py b/src/forge_invar/constants.py index 6faa1a9..1a7c9c4 100644 --- a/src/forge_invar/constants.py +++ b/src/forge_invar/constants.py @@ -7,7 +7,9 @@ RESOURCES_PATH = PROJECT_PATH / "resources" FORGE_SAVE_PATH = PROJECT_PATH / "forge_default_save.txt" FORGE_SAVE_BACKUP_PATH = PROJECT_PATH / "forge_default_save.txt.bck" -MOCK_SAVE_PATH = RESOURCES_PATH / "mock_data.txt" +FORGE_SAVE_STATE_PATH_FORMAT = "forge_default_save.{}.txt" +FORGE_SAVE_STATES_COUNT = 6 +FORGE_SAVE_MOCK_PATH = RESOURCES_PATH / "mock_data.txt" BACKUP_INTERVAL = 0.25 diff --git a/src/forge_invar/display.py b/src/forge_invar/display.py index 828a074..9b91b88 100644 --- a/src/forge_invar/display.py +++ b/src/forge_invar/display.py @@ -10,6 +10,7 @@ from .constants import ( ESTIMATED_LONG_BOOT_TIME_SECONDS, FONT_1_PATH, FONT_2_PATH, + FORGE_SAVE_STATES_COUNT, FX_GROUP, FXA_FRAG, FXB_FRAG, @@ -186,6 +187,19 @@ def __get_running_display(data: ForgeData) -> Image.Image: if draw_base: draw.rectangle((114, 34, 121, 36), fill="white") + # states + for i in range(FORGE_SAVE_STATES_COUNT): + if data.is_state(i): + draw.rectangle( + ( + 91 + (i % 3) * 5, + 53 + (i // 3) * 5, + 96 + (i % 3) * 5, + 58 + (i // 3) * 5, + ), + fill="white", + ) + return __xor(im, im_overlay) diff --git a/src/forge_invar/forge_data.py b/src/forge_invar/forge_data.py index 32c2d2c..7d59208 100644 --- a/src/forge_invar/forge_data.py +++ b/src/forge_invar/forge_data.py @@ -8,7 +8,10 @@ from .constants import ( BACKUP_INTERVAL, EXTRA_GROUP, FORGE_SAVE_BACKUP_PATH, + FORGE_SAVE_MOCK_PATH, FORGE_SAVE_PATH, + FORGE_SAVE_STATE_PATH_FORMAT, + FORGE_SAVE_STATES_COUNT, FX_GROUP, FXA_FRAG, FXB_FRAG, @@ -16,7 +19,7 @@ from .constants import ( GROUPS_SIZE, MFX_FRAG, MIX_FRAG, - MOCK_SAVE_PATH, + PROJECT_PATH, ) from .glsl_funcs import fract, magic, magic_trigger, rand_time @@ -48,28 +51,38 @@ class ForgeSave: def __contains__(self, key: str) -> bool: return key in self.__data + def __hash__(self) -> int: + return hash(tuple(self[key] for key in self.__data if key.startswith("value"))) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, ForgeSave): + return False + return hash(self) == hash(other) + class ForgeData: def __init__(self) -> None: self.__data = ForgeSave(FORGE_SAVE_PATH) self.__backup_data = ForgeSave(FORGE_SAVE_BACKUP_PATH) + self.__states = [ + ForgeSave(PROJECT_PATH / FORGE_SAVE_STATE_PATH_FORMAT.format(i + 1)) + for i in range(FORGE_SAVE_STATES_COUNT) + ] self.running = False self.__last_backup: float = time.time() self.__start_time = 0 def __enter__(self) -> typing.Self: - if self.__backup_data.read(): + if not self.__data.read() and self.__backup_data.read(): self.__data.update(self.__backup_data) log.info("restored data from backup") - else: - self.__data.read() self.__start_time = self.time return self def __exit__(self, *_) -> None: pass - def __update_state(self) -> None: + def __check_running(self) -> None: if self.running: return if self.time > 0 and self.time != self.__start_time: @@ -79,10 +92,16 @@ class ForgeData: now = time.time() if now - self.__last_backup > BACKUP_INTERVAL: self.__backup_data.update(self.__data) + self.__last_backup = now + + def __read_states(self) -> None: + for state in self.__states: + state.read() def update(self) -> bool: if self.__data.read(): - self.__update_state() + self.__check_running() + self.__read_states() self.__backup() return True return False @@ -240,9 +259,15 @@ class ForgeData: def output_blank(self) -> bool: return self.group_value(EXTRA_GROUP, 1, 0)[1] > 0 + def is_state(self, i: int) -> bool: + if i < 0 or i >= FORGE_SAVE_STATES_COUNT: + return False + return self.__states[i] == self.__data + def mock(self) -> typing.Self: - mock_data = ForgeSave(MOCK_SAVE_PATH) + mock_data = ForgeSave(FORGE_SAVE_MOCK_PATH) if mock_data.read(): self.__data.update(mock_data) + self.__states[1].update(mock_data) self.running = True return self diff --git a/src/forge_invar/tools/gen_img.py b/src/forge_invar/tools/gen_img.py index 6348525..47061c7 100644 --- a/src/forge_invar/tools/gen_img.py +++ b/src/forge_invar/tools/gen_img.py @@ -56,6 +56,12 @@ def generate_background_image() -> None: draw.circle((63, 61), 2, outline="white", fill="black") draw.circle((71, 61), 2, outline="white", fill="black") + # save states + draw.rectangle((91, 53, 106, 63), outline="white", fill="black") + draw.rectangle((91, 53, 106, 58), outline="white", fill=None) + draw.rectangle((91, 53, 96, 63), outline="white", fill=None) + draw.rectangle((91, 53, 101, 63), outline="white", fill=None) + im.save(BACKGROUND_IMG_PATH) log.info(f"Generated {BACKGROUND_IMG_PATH}")