from PIL import Image class ProotState: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) cls._instance.current_blink_state = 0 cls._instance.desired_blink_state = 0 cls._instance.blinks_frames_ready = False cls._instance.loading_screen = True cls._instance.loading_time = 0 cls._instance.frame_canvas_prootScreen_1 = False cls._instance.frame_canvas_prootScreen_2 = False cls._instance.frame_canvas_prootScreen_3 = False cls._instance.matrix = False return cls._instance def set_matrix(self, matrix): self.matrix = matrix def next_blink_frame_number(self) -> int: if self.current_blink_state == self.desired_blink_state == 10: self.desired_blink_state = 0 return self.current_blink_state if self.current_blink_state == self.desired_blink_state == 0: return self.current_blink_state if self.current_blink_state < self.desired_blink_state: self.current_blink_state += 1 else: self.current_blink_state -= 1 return self.current_blink_state def blink(self, state = 10): self.set_desired_blink_state(state) def set_desired_blink_state(self, state: int): self.desired_blink_state = state def set_blinks_frames_ready(self, ready: bool): self.blinks_frames_ready = ready def get_desired_blink_state(self) -> int: return self.desired_blink_state def get_blinks_frames_ready(self) -> bool: return self.blinks_frames_ready # This function animates the loading screen. It asumes that the function gets called frequently(every frame update) def set_ProotScreen(self, matrix): self.loading_time += 1 self.loading_time = self.loading_time % 75 if not self.frame_canvas_prootScreen_1: self.frame_canvas_prootScreen_1 = matrix.CreateFrameCanvas() image_proot_screen_1 = Image.open("faces/ProotScreen1.png").convert('RGB') self.frame_canvas_prootScreen_1.SetImage(image_proot_screen_1, unsafe=False) matrix.SwapOnVSync(self.frame_canvas_prootScreen_1) if not self.frame_canvas_prootScreen_2: self.frame_canvas_prootScreen_2 = matrix.CreateFrameCanvas() image_proot_screen_2 = Image.open("faces/ProotScreen2.png").convert('RGB') self.frame_canvas_prootScreen_2.SetImage(image_proot_screen_2, unsafe=False) matrix.SwapOnVSync(self.frame_canvas_prootScreen_2) if not self.frame_canvas_prootScreen_3: self.frame_canvas_prootScreen_3 = matrix.CreateFrameCanvas() image_proot_screen_3 = Image.open("faces/ProotScreen3.png").convert('RGB') self.frame_canvas_prootScreen_3.SetImage(image_proot_screen_3, unsafe=False) matrix.SwapOnVSync(self.frame_canvas_prootScreen_3) if self.loading_time < 25: matrix.SwapOnVSync(self.frame_canvas_prootScreen_1) elif self.loading_time < 50: matrix.SwapOnVSync(self.frame_canvas_prootScreen_2) else: matrix.SwapOnVSync(self.frame_canvas_prootScreen_3) def update_screen(blinkFrameCanvases, matrix): proot_state = ProotState() if proot_state.get_blinks_frames_ready(): # TODO move blinking animation writing logic to the ProotState class matrix.SwapOnVSync(blinkFrameCanvases[proot_state.next_blink_frame_number()]) else: proot_state.set_ProotScreen(matrix)