import cmd import threading from queue import Queue from turtle import forward from equipment.turtle_device import TurtleDevice class TurtleDeviceThread(threading.Thread): def __init__(self): super().__init__() self.device = TurtleDevice() self.queue = Queue[tuple]() self.device.open() self.device.execute("speed", 1) def run(self): while True: action, args, kwargs = self.queue.get() if action == "exit": self.queue.task_done() break self.device.execute(action, *args, **kwargs) self.queue.task_done() def add_task(self, action, *args, **kwargs): self.queue.put((action, args, kwargs)) class NoBlockingTurtleShell(cmd.Cmd): intro = "Welcome to the turtle shell. Type help or ? to list commands.\n" prompt = "(turtle) " file = None def __init__(self, turtle_thread: TurtleDeviceThread): super().__init__() self.turtle_thread = turtle_thread @property def turtle_device(self): return self.turtle_thread.device def do_execute(self, arg): command_and_args = arg.split() if len(command_and_args) == 1: self.turtle_thread.add_task(command) return command = command_and_args[0] args = tuple(int(c) if c.isdecimal() else c for c in command_and_args[1:]) self.turtle_thread.add_task(command, *args) def do_forward(self, arg): 'Move the turtle forward by the specified distance: FORWARD 10' self.do_execute("forward 100") def do_right(self, arg): 'Turn turtle right by given number of degrees: RIGHT 20' self.do_execute("right 100") def do_left(self, arg): 'Turn turtle left by given number of degrees: LEFT 90' self.do_execute("left 100") def do_bye(self, arg): 'Stop recording, close the turtle window, and exit: BYE' print('Thank you for using Turtle') self.turtle_thread.add_task("exit") return True if __name__ == "__main__": turtle_thread = TurtleDeviceThread() turtle_thread.daemon = True thread_shell = threading.Thread(target=NoBlockingTurtleShell(turtle_thread).cmdloop) thread_shell.start() turtle_thread.run() thread_shell.join()