Added/updated docs
This commit is contained in:
parent
cb441201c6
commit
363094170e
3 changed files with 45 additions and 15 deletions
|
|
@ -87,7 +87,7 @@ class BaseCamera(object):
|
||||||
self.thread = None #: Background thread reading frames from camera
|
self.thread = None #: Background thread reading frames from camera
|
||||||
self.camera = None #: Camera object
|
self.camera = None #: Camera object
|
||||||
|
|
||||||
self.lock = StrictLock(timeout=1) #: Strict lock controlling thread access to camera hardware
|
self.lock = StrictLock(timeout=1) #: :py:class:`openflexure_microscope.lock.StrictLock`: Strict lock controlling thread access to camera hardware
|
||||||
|
|
||||||
self.frame = None #: bytes: Current frame is stored here by background thread
|
self.frame = None #: bytes: Current frame is stored here by background thread
|
||||||
self.last_access = 0 #: time: Time of last client access to the camera
|
self.last_access = 0 #: time: Time of last client access to the camera
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,17 @@ from openflexure_microscope.lock import StrictLock
|
||||||
# TODO: Implement lock on movement
|
# TODO: Implement lock on movement
|
||||||
class Stage(OpenFlexureStage):
|
class Stage(OpenFlexureStage):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.lock = StrictLock(timeout=2) #: Strict lock controlling thread access to camera hardware
|
"""
|
||||||
|
Subclass of :py:class:`openflexure_stage.stage.OpenFlexureStage`,
|
||||||
|
adding an instance of :py:class:`openflexure_microscope.lock.StrictLock` to regulate access.
|
||||||
|
"""
|
||||||
|
self.lock = StrictLock(timeout=2) #: :py:class:`openflexure_microscope.lock.StrictLock`: Strict lock controlling thread access to camera hardware
|
||||||
|
|
||||||
OpenFlexureStage.__init__(self, *args, **kwargs)
|
OpenFlexureStage.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
def _move_rel_nobacklash(self, *args, **kwargs):
|
def _move_rel_nobacklash(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Overrides `OpenFlexureStage._move_rel_nobacklash` to acquire lock first.
|
Overrides :py:function:`openflexure_stage.stage.OpenFlexureStage._move_rel_nobacklash` to acquire lock first.
|
||||||
"""
|
"""
|
||||||
with self.lock:
|
with self.lock:
|
||||||
OpenFlexureStage._move_rel_nobacklash(self, *args, **kwargs)
|
OpenFlexureStage._move_rel_nobacklash(self, *args, **kwargs)
|
||||||
|
|
@ -9,19 +9,34 @@ from openflexure_microscope.utilities import entry_by_id
|
||||||
|
|
||||||
class TaskOrchestrator:
|
class TaskOrchestrator:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# List of tasks in the orchestrator
|
"""
|
||||||
self.tasks = []
|
Class responsible for spawning threaded tasks, and storing their returns.
|
||||||
|
A microscope should contain exactly one instance of `TaskOrchestrator`.
|
||||||
|
"""
|
||||||
|
self.tasks = [] #: list: List of `Task` objects
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
|
"""
|
||||||
|
Returns a list of dictionary representations of all tasks in the session.
|
||||||
|
"""
|
||||||
return [task.state for task in self.tasks]
|
return [task.state for task in self.tasks]
|
||||||
|
|
||||||
def task_from_id(self, task_id):
|
def task_from_id(self, task_id: str):
|
||||||
|
"""
|
||||||
|
Returns a particular task object with the specified `task_id`.
|
||||||
|
"""
|
||||||
return entry_by_id(task_id, self.tasks)
|
return entry_by_id(task_id, self.tasks)
|
||||||
|
|
||||||
def start(self, function, *args, **kwargs):
|
def start(self, function: function, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Attach and start a new long-running task, if allowed by `start_condition()`.
|
Attach and start a new long-running task, if allowed by `start_condition()`.
|
||||||
|
Returns an instance of :py:class:`openflexure_microscope.task.Task`, which can be used to check the state
|
||||||
|
or eventual return of the task.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
function (function): The target function to run in the background
|
||||||
|
*args, **kwargs: Arguments that will be passed to `function` at runtime.
|
||||||
"""
|
"""
|
||||||
# Create a task object
|
# Create a task object
|
||||||
task = Task(function, *args, **kwargs)
|
task = Task(function, *args, **kwargs)
|
||||||
|
|
@ -65,16 +80,18 @@ class TaskOrchestrator:
|
||||||
|
|
||||||
class Task:
|
class Task:
|
||||||
def __init__(self, task, *args, **kwargs):
|
def __init__(self, task, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Class responsible for running a task function in a thread, and handling return or errors.
|
||||||
|
Tasks should be created by an instance of :py:class:`openflexure_microscope.task.TaskOrchestrator`.
|
||||||
|
"""
|
||||||
# The task long-running method
|
# The task long-running method
|
||||||
self.task = task
|
self.task = task #: function: Function to be called in the task thread.
|
||||||
self.args = args
|
self.args = args #: Positional arguments to be passed to the task function.
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs #: Keyword arguments to be passed to the task function.
|
||||||
|
|
||||||
# If task is currently running
|
self._running = False #: bool: If task is currently running
|
||||||
self._running = False
|
|
||||||
|
|
||||||
self.id = uuid.uuid4().hex
|
self.id = uuid.uuid4().hex #: str: Unique ID for the task
|
||||||
|
|
||||||
self.state = {
|
self.state = {
|
||||||
'id': self.id,
|
'id': self.id,
|
||||||
|
|
@ -82,9 +99,12 @@ class Task:
|
||||||
'return': None,
|
'return': None,
|
||||||
'start_time': None,
|
'start_time': None,
|
||||||
'end_time': None,
|
'end_time': None,
|
||||||
}
|
} #: dict: Dictionary describing the full state of the task. `status` will be one of 'idle'', 'running', 'error', or 'success'. `return` eventually holds the return value of the task function.
|
||||||
|
|
||||||
def process(self, f):
|
def process(self, f):
|
||||||
|
"""
|
||||||
|
Wraps the target function to handle recording `status` and `return` to `state`.
|
||||||
|
"""
|
||||||
def wrapped(*args, **kwargs):
|
def wrapped(*args, **kwargs):
|
||||||
self.state['status'] = 'running'
|
self.state['status'] = 'running'
|
||||||
try:
|
try:
|
||||||
|
|
@ -98,12 +118,18 @@ class Task:
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
"""
|
||||||
|
Records the task start and end times to `state`, and runs the task wrapped in `process`.
|
||||||
|
"""
|
||||||
self.state['start_time'] = datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S")
|
self.state['start_time'] = datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S")
|
||||||
self.process(self.task)(*self.args, **self.kwargs)
|
self.process(self.task)(*self.args, **self.kwargs)
|
||||||
self._running = False
|
self._running = False
|
||||||
self.state['end_time'] = datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S")
|
self.state['end_time'] = datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S")
|
||||||
|
|
||||||
def start(self): # Start and draw
|
def start(self): # Start and draw
|
||||||
|
"""
|
||||||
|
Spawns a thread, and starts `run()` in that thread.
|
||||||
|
"""
|
||||||
# If not already running
|
# If not already running
|
||||||
if not self._running:
|
if not self._running:
|
||||||
self._running = True # Set start command
|
self._running = True # Set start command
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue