import time class StateSingleton: _instance = None def __new__(cls): if not cls._instance: cls._instance = super(StateSingleton, cls).__new__(cls) cls._instance.states = { 0: "open", 1: "blink", 2: "owo", 3: "angry"} cls._instance.matrix = False cls._instance.current_expression = cls._instance.states[0] cls._instance.desired_expression = cls._instance.states[0] cls._instance.new_desired_expression = cls._instance.states[0] cls._instance.transition_steps = 10 # Number of steps to transition between states cls._instance.transition_count = 0 # Counter to keep track of transition progress cls._instance.animations_ready = False cls._instance.blink_animation_FrameCanvases = [] cls._instance.angry_animation_FrameCanvases = [] cls._instance.stun_animation_FrameCanvases = [] return cls._instance def set_blink_animation_frames(self, blink_animation_FrameCanvases): self.blink_animation_FrameCanvases = blink_animation_FrameCanvases print("blink animations set") def set_angry_animation_frames(self, angry_animation_FrameCanvases): self.angry_animation_FrameCanvases = angry_animation_FrameCanvases print("angry animations set") def set_stun_animation_frames(self, stun_animation_FrameCanvases): self.stun_animation_FrameCanvases = stun_animation_FrameCanvases print("angry animations set") def set_desired_expression(self, state): if state in self.states: print("Set desired state to: " + self.states[state]) self.desired_expression = self.states[state] self.new_desired_expression = state else: print("Invalid state.") def update_step(self): if self.current_expression == self.desired_expression: # already at desire expression if self.current_expression == self.states[0]: self.transition_count = 0 return if self.current_expression == self.states[0]: # Transition from "open" state to another state if self.transition_count < self.transition_steps: # still transitioning self.transition_count += 1 return self.current_expression = self.desired_expression self.transition_count = 10 return else: # Transition from another state to "open" state if 0 < self.transition_count: # still transitioning self.transition_count -= 1 return self.current_expression = self.states[0] # Complete transition to "open" state self.transition_count = 0 def draw_face(self): #default face if self.current_expression == self.desired_expression == self.states[0]: self.matrix.SwapOnVSync(self.blink_animation_FrameCanvases[0]) # blinky faces elif self.current_expression == self.desired_expression == self.states[1]: self.matrix.SwapOnVSync(self.blink_animation_FrameCanvases[10]) elif self.current_expression == self.states[1] or self.desired_expression == self.states[1]: self.matrix.SwapOnVSync(self.blink_animation_FrameCanvases[self.transition_count]) # stun faces elif self.current_expression == self.desired_expression == self.states[2]: self.matrix.SwapOnVSync(self.stun_animation_FrameCanvases[10]) elif self.current_expression == self.states[3] or self.desired_expression == self.states[3]: self.matrix.SwapOnVSync(self.stun_animation_FrameCanvases[self.transition_count]) # angry faces elif self.current_expression == self.desired_expression == self.states[3]: self.matrix.SwapOnVSync(self.angry_animation_FrameCanvases[10]) elif self.current_expression == self.states[3] or self.desired_expression == self.states[3]: self.matrix.SwapOnVSync(self.angry_animation_FrameCanvases[self.transition_count]) def update(self): if not self.get_animations_ready(): print("animation not yet ready") return self.update_step() # print("at step: " + str(self.transition_count) + " current expression: " + str(self.desired_expression) + " desired expression: " + str(self.desired_expression)) self.draw_face() def get_current_state(self): for state, value in self.states.items(): if value == self.current_state: return state def get_animations_ready(self): return self.animations_ready def set_animations_ready(self): self.animations_ready = True print("animations set to ready") def set_matrix(self, matrix): self.matrix = matrix # Example usage: # singleton = StateSingleton() # singleton.set_desired_expression(3) #for _ in range(100): # singleton.update() # time.sleep(0.1)