Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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.

8 changes: 5 additions & 3 deletions src/fastcs/connections/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from .ip_connection import IPConnection

__all__ = ["IPConnection"]
from .ip_connection import IPConnection as 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
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