import time class StateSingleton: _instance = None def __new__(cls): if not cls._instance: cls._instance = super(StateSingleton, cls).__new__(cls) return cls._instance def __init__(self): self.states = { 0: "open", 1: "blink", 2: "owo", 3: "angry" } self.matrix = False self.current_expression = self.states[0] self.desired_expression = self.states[0] self.new_desired_expression = self.states[0] self.transition_steps = 10 # Number of steps to transition between states self.transition_count = 0 # Counter to keep track of transition progress self.animations_ready = False self.blink_animation_FrameCanvases = [] self.angry_animation_FrameCanvases = [] def set_blink_animation_frames(self, blink_animation_FrameCanvases): self.blink_animation_FrameCanvases = blink_animation_FrameCanvases def set_angry_animation_frames(self, angry_animation_FrameCanvases): self.angry_animation_FrameCanvases = angry_animation_FrameCanvases def set_desired_expression(self, state): if state in self.states: 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 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]) # 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) + " from default in 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, state): self.animations_ready = state 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)