-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create ControllerAPI class to decouple transport from Controller
- Loading branch information
Showing
25 changed files
with
810 additions
and
529 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
from collections.abc import Iterator | ||
from dataclasses import dataclass, field | ||
|
||
from fastcs.attributes import Attribute | ||
from fastcs.controller import BaseController, Controller | ||
from fastcs.cs_methods import Command, Put, Scan | ||
|
||
|
||
@dataclass | ||
class ControllerAPI: | ||
"""Attributes, bound methods and sub APIs of a `Controller` / `SubController`""" | ||
|
||
path: list[str] = field(default_factory=list) | ||
"""Path within controller tree (empty if this is the root)""" | ||
attributes: dict[str, Attribute] = field(default_factory=dict) | ||
command_methods: dict[str, Command] = field(default_factory=dict) | ||
put_methods: dict[str, Put] = field(default_factory=dict) | ||
scan_methods: dict[str, Scan] = field(default_factory=dict) | ||
sub_apis: dict[str, "ControllerAPI"] = field(default_factory=dict) | ||
"""APIs of the sub controllers of the `Controller` this API was built from""" | ||
|
||
def walk_api(self) -> Iterator["ControllerAPI"]: | ||
"""Walk through all the nested `ControllerAPIs` of this `ControllerAPI` | ||
yields: `ControllerAPI`s from a depth-first traversal of the tree, including | ||
self. | ||
""" | ||
yield self | ||
for api in self.sub_apis.values(): | ||
yield from api.walk_api() | ||
|
||
|
||
def build_controller_api(controller: Controller) -> ControllerAPI: | ||
return _build_controller_api(controller, []) | ||
|
||
|
||
def _build_controller_api(controller: BaseController, path: list[str]) -> ControllerAPI: | ||
"""Build a `ControllerAPI` for a `BaseController` and its sub controllers""" | ||
scan_methods: dict[str, Scan] = {} | ||
put_methods: dict[str, Put] = {} | ||
command_methods: dict[str, Command] = {} | ||
for attr_name in dir(controller): | ||
attr = getattr(controller, attr_name) | ||
match attr: | ||
case Put(enabled=True): | ||
put_methods[attr_name] = attr | ||
case Scan(enabled=True): | ||
scan_methods[attr_name] = attr | ||
case Command(enabled=True): | ||
command_methods[attr_name] = attr | ||
case _: | ||
pass | ||
|
||
return ControllerAPI( | ||
path=path, | ||
attributes=controller.attributes, | ||
command_methods=command_methods, | ||
put_methods=put_methods, | ||
scan_methods=scan_methods, | ||
sub_apis={ | ||
name: _build_controller_api(sub_controller, path + [name]) | ||
for name, sub_controller in controller.get_sub_controllers().items() | ||
}, | ||
) |
Oops, something went wrong.