diff --git a/controls/device.py b/controls/device.py index c47e9ef..76ddd65 100644 --- a/controls/device.py +++ b/controls/device.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from typing import Optional, Collection, Any from abc import ABC, abstractmethod -from enum import Enum, auto +from enum import Enum class DeviceLifecycleState(Enum): INIT = "init" @@ -85,7 +85,4 @@ class SynchronyDevice(Device): @abstractmethod def invalidate(self, trait_name: str): """Invalidate logical state of trait `trait_name`""" - pass - - def close(self): - return super().close() \ No newline at end of file + pass \ No newline at end of file diff --git a/equipment/turtle_device.py b/equipment/turtle_device.py index 4b6cec9..32d973f 100644 --- a/equipment/turtle_device.py +++ b/equipment/turtle_device.py @@ -1,22 +1,16 @@ from turtle import Turtle from typing import Any, Collection, Optional -from controls.device import ActionDescriptor, SynchronyDevice, TraitDescriptor +from controls.device import SynchronyDevice, TraitDescriptor, DeviceLifecycleState class TurtleDevice(SynchronyDevice): - def open(self, name, **kwargs): - self.turtle = Turtle(kwargs) + def open(self): + self.state == DeviceLifecycleState.OPEN + self.turtle = Turtle() super().open() def close(self): - del self.turtle - super().close() - - # @property - # def trait_descriptors(self): - # traits = [attribute for attribute in vars(self.turtle).items() - # if (attribute[0].startswith('_') == False)] - - # return Collection[[TraitDescriptor(*tr) for tr in traits]] + del self.turtle + super().close() @property def trait_descriptors(self): @@ -26,13 +20,6 @@ class TurtleDevice(SynchronyDevice): self.traits = [TraitDescriptor(*tr) for tr in traits] return self.traits - # @property - # def action_descriptors(self): - # actions = [(attribute, getattr(t, attribute)) for attribute in dir(t) - # if (attribute.startswith('_') == False)] - - # return Collection[[TraitDescriptor(*ac) for ac in actions]] - @property def action_descriptors(self): actions = [(attribute, getattr(self.turtle, attribute)) for attribute in dir(self.turtle) @@ -53,7 +40,11 @@ class TurtleDevice(SynchronyDevice): collection[i].info=value def execute(self, action_name: str, *args, **kwargs): - self.turtle.action_name(args, *kwargs) + if self.state == DeviceLifecycleState.INIT: + self.open() + execution = getattr(self.turtle, action_name) + execution(int(*args), **kwargs) + def invalidate(self, trait_name: str): return super().invalidate(trait_name) diff --git a/noblocking_turtle_shell.py b/noblocking_turtle_shell.py index 7d71211..011050a 100644 --- a/noblocking_turtle_shell.py +++ b/noblocking_turtle_shell.py @@ -1,13 +1,12 @@ import cmd -import threading -from threading import Thread - -from queue import Empty, Queue +from threading import Thread, Event +from turtle import bye +from queue import Queue, Empty from equipment.turtle_device import TurtleDevice -class TurtleDeviceThread(threading.Thread): +class TurtleDeviceThread(Thread): def __init__(self): super().__init__() self.device = TurtleDevice() @@ -24,7 +23,7 @@ class TurtleDeviceThread(threading.Thread): break self.device.execute(*item) self.queue.task_done() - + class NoBlockingTurtleShell(cmd.Cmd): intro = 'Welcome to the turtle shell. Type help or ? to list commands.\n' @@ -33,15 +32,27 @@ class NoBlockingTurtleShell(cmd.Cmd): def __init__(self, turtle_thread: TurtleDeviceThread): super(NoBlockingTurtleShell, self).__init__() - self.turtle_thread = TurtleDeviceThread() + self.turtle_thread = turtle_thread def do_execute(self, arg): - self.turtle_thread.queue.put(arg) + self.turtle_thread.queue.put(parse(arg)) def do_exit(self, arg): - self.turtle_thread.queue.put('exit') + self.close() + self.turtle_thread.queue.put("exit") + print('Thank you for using Turtle') + return True + + + def close(self): + if self.file: + self.file.close() + self.file = None +def parse(arg): + 'Convert a series of zero or more numbers to an argument tuple' + return tuple(arg.split()) if __name__ == '__main__': turtle_thread = TurtleDeviceThread()