Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/fastcs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@
"""

from ._version import __version__
from .launch import FastCS as FastCS
from .launch import launch as launch

__all__ = ["__version__"]
30 changes: 10 additions & 20 deletions src/fastcs/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@
from softioc.asyncio_dispatcher import AsyncioDispatcher

from .attributes import AttrR, AttrW, Sender, Updater
from .controller import Controller
from .controller import Controller, SingleMapping
from .exceptions import FastCSException
from .mapping import Mapping, SingleMapping


class Backend:
def __init__(
self, controller: Controller, loop: asyncio.AbstractEventLoop | None = None
self,
controller: Controller,
loop: asyncio.AbstractEventLoop | None = None,
):
self._dispatcher = AsyncioDispatcher(loop)
self._loop = self._dispatcher.loop
self.dispatcher = AsyncioDispatcher(loop)
self._loop = self.dispatcher.loop
self._controller = controller

self._initial_coros = [controller.connect]
Expand All @@ -27,17 +28,10 @@ def __init__(
self._controller.initialise(), self._loop
).result()

self._mapping = Mapping(self._controller)
self._link_process_tasks()

self._context = {
"dispatcher": self._dispatcher,
"controller": self._controller,
"mapping": self._mapping,
}

def _link_process_tasks(self):
for single_mapping in self._mapping.get_controller_mappings():
for single_mapping in self._controller.get_controller_mappings():
_link_single_controller_put_tasks(single_mapping)
_link_attribute_sender_class(single_mapping)

Expand All @@ -47,7 +41,6 @@ def __del__(self):
def run(self):
self._run_initial_futures()
self.start_scan_futures()
self._run()

def _run_initial_futures(self):
for coro in self._initial_coros:
Expand All @@ -57,7 +50,7 @@ def _run_initial_futures(self):
def start_scan_futures(self):
self._scan_futures = {
asyncio.run_coroutine_threadsafe(coro(), self._loop)
for coro in _get_scan_coros(self._mapping)
for coro in _get_scan_coros(self._controller)
}

def stop_scan_futures(self):
Expand All @@ -68,9 +61,6 @@ def stop_scan_futures(self):
except asyncio.CancelledError:
pass

def _run(self):
raise NotImplementedError("Specific Backend must implement _run")


def _link_single_controller_put_tasks(single_mapping: SingleMapping) -> None:
for name, method in single_mapping.put_methods.items():
Expand Down Expand Up @@ -108,10 +98,10 @@ async def callback(value):
return callback


def _get_scan_coros(mapping: Mapping) -> list[Callable]:
def _get_scan_coros(controller: Controller) -> list[Callable]:
scan_dict: dict[float, list[Callable]] = defaultdict(list)

for single_mapping in mapping.get_controller_mappings():
for single_mapping in controller.get_controller_mappings():
_add_scan_method_tasks(scan_dict, single_mapping)
_add_attribute_updater_tasks(scan_dict, single_mapping)

Expand Down
5 changes: 0 additions & 5 deletions src/fastcs/backends/__init__.py

This file was deleted.

13 changes: 0 additions & 13 deletions src/fastcs/backends/asyncio_backend.py

This file was deleted.

28 changes: 0 additions & 28 deletions src/fastcs/backends/epics/backend.py

This file was deleted.

19 changes: 0 additions & 19 deletions src/fastcs/backends/epics/docs.py

This file was deleted.

14 changes: 0 additions & 14 deletions src/fastcs/backends/rest/backend.py

This file was deleted.

14 changes: 0 additions & 14 deletions src/fastcs/backends/tango/backend.py

This file was deleted.

4 changes: 4 additions & 0 deletions src/fastcs/connections/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from .ip_connection import IPConnection
from .ip_connection import IPConnectionSettings as IPConnectionSettings
from .ip_connection import StreamConnection as StreamConnection
from .serial_connection import SerialConnection as SerialConnection
from .serial_connection import SerialConnectionSettings as SerialConnectionSettings

__all__ = ["IPConnection"]
44 changes: 44 additions & 0 deletions src/fastcs/controller.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
from __future__ import annotations

from collections.abc import Iterator
from copy import copy
from dataclasses import dataclass

from .attributes import Attribute
from .cs_methods import Command, Put, Scan
from .wrappers import WrappedMethod


@dataclass
class SingleMapping:
controller: BaseController
scan_methods: dict[str, Scan]
put_methods: dict[str, Put]
command_methods: dict[str, Command]
attributes: dict[str, Attribute]


class BaseController:
Expand Down Expand Up @@ -42,6 +55,37 @@
def get_sub_controllers(self) -> dict[str, BaseController]:
return self.__sub_controller_tree

def get_controller_mappings(self) -> list[SingleMapping]:
return list(_walk_mappings(self))


def _walk_mappings(controller: BaseController) -> Iterator[SingleMapping]:
yield _get_single_mapping(controller)
for sub_controller in controller.get_sub_controllers().values():
yield from _walk_mappings(sub_controller)


def _get_single_mapping(controller: BaseController) -> SingleMapping:
scan_methods: dict[str, Scan] = {}
put_methods: dict[str, Put] = {}
command_methods: dict[str, Command] = {}
attributes: dict[str, Attribute] = {}
for attr_name in dir(controller):
attr = getattr(controller, attr_name)
match attr:
case WrappedMethod(fastcs_method=Put(enabled=True) as put_method):
put_methods[attr_name] = put_method

Check warning on line 77 in src/fastcs/controller.py

View check run for this annotation

Codecov / codecov/patch

src/fastcs/controller.py#L77

Added line #L77 was not covered by tests
case WrappedMethod(fastcs_method=Scan(enabled=True) as scan_method):
scan_methods[attr_name] = scan_method
case WrappedMethod(fastcs_method=Command(enabled=True) as command_method):
command_methods[attr_name] = command_method
case Attribute(enabled=True):
attributes[attr_name] = attr

return SingleMapping(
controller, scan_methods, put_methods, command_methods, attributes
)


class Controller(BaseController):
"""Top-level controller for a device.
Expand Down
4 changes: 4 additions & 0 deletions src/fastcs/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
class FastCSException(Exception):
pass


class LaunchError(FastCSException):
pass
Loading
Loading