Skip to content

Commit

Permalink
Check type of BtTickChild id
Browse files Browse the repository at this point in the history
Signed-off-by: Marco Lampacrescia <[email protected]>
  • Loading branch information
MarcoLm993 committed Oct 14, 2024
1 parent f11c651 commit dab8efe
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
5 changes: 5 additions & 0 deletions src/as2fm/scxml_converter/scxml_entries/bt_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ def str_to_int(resp_str: str) -> int:
raise ValueError(f"Error: {resp_str} is an invalid BT Status type.")


def generate_bt_tick_event(instance_id: str) -> str:
"""Generate the BT tick event name for a given BT node instance."""
return f"bt_{instance_id}_tick"


def is_bt_event(event_name: str) -> bool:
"""Given an event name, returns whether it is related to a BT event or not."""
bt_events = [f"bt_{suffix}" for suffix in ["tick", "running", "success", "failure"]]
Expand Down
36 changes: 34 additions & 2 deletions src/as2fm/scxml_converter/scxml_entries/scxml_bt_ticks.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,20 @@
SCXML entries related to Behavior Tree Ticks and related responses.
"""

from typing import Optional, Union
from typing import List, Optional, Union

from lxml import etree as ET

from as2fm.scxml_converter.scxml_entries import (
ScxmlExecutionBody,
ScxmlIf,
ScxmlSend,
ScxmlTransition,
execution_body_from_xml,
instantiate_exec_body_bt_events,
)
from as2fm.scxml_converter.scxml_entries.bt_utils import BtResponse
from as2fm.scxml_converter.scxml_entries.bt_utils import BtResponse, generate_bt_tick_event
from as2fm.scxml_converter.scxml_entries.utils import is_non_empty_string
from as2fm.scxml_converter.scxml_entries.xml_utils import assert_xml_tag_ok, get_xml_argument


Expand Down Expand Up @@ -56,6 +59,14 @@ def __init__(
):
super().__init__(target, ["bt_tick"], condition, body)

def check_validity(self) -> bool:
return super().check_validity()

def instantiate_bt_events(self, instance_id: int, children_ids: List[int]) -> ScxmlTransition:
self._events = [generate_bt_tick_event(instance_id)]
instantiate_exec_body_bt_events(self._body, instance_id, children_ids)
return ScxmlTransition(self._target, self._events, self._condition, self._body)

def as_xml(self) -> ET.Element:
xml_bt_tick = ET.Element(BtTick.get_tag_name(), {"target": self._target})
if self._condition is not None:
Expand Down Expand Up @@ -84,6 +95,27 @@ def __init__(self, child_id: Union[str, int]):
child_id, (str, int)
), f"Error: SCXML BT Tick Child: invalid child id type {type(child_id)}."
self._child = child_id
if isinstance(child_id, str):
child_id = child_id.strip()
try:
self._child = int(child_id)
except ValueError:
self._child = child_id
assert is_non_empty_string(BtTickChild, "id", self._child)
assert (
self._child.isidentifier()
), f"Error: SCXML BT Tick Child: invalid child id '{self._child}'."

def check_validity(self) -> bool:
return True

def instantiate_bt_events(
self, instance_id: int, children_ids: List[int]
) -> Union[ScxmlIf, ScxmlSend]:
"""
Convert the BtTickChild to ScxmlSend if the child id is constant and an ScxmlIf otherwise.
"""
raise NotImplementedError("Error: SCXML BT Tick Child: instantiation not implemented.")

def as_xml(self) -> ET.Element:
xml_bt_tick_child = ET.Element(BtTickChild.get_tag_name(), {"id": str(self._child)})
Expand Down
18 changes: 9 additions & 9 deletions src/as2fm/scxml_converter/scxml_entries/scxml_transition.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@
valid_execution_body,
valid_execution_body_entry_types,
)
from as2fm.scxml_converter.scxml_entries.utils import CallbackType, get_plain_expression
from as2fm.scxml_converter.scxml_entries.utils import (
CallbackType,
get_plain_expression,
is_non_empty_string,
)


class ScxmlTransition(ScxmlBase):
Expand Down Expand Up @@ -145,22 +149,18 @@ def append_body_executable_entry(self, exec_entry: ScxmlExecutableEntry):
), "Error SCXML transition: invalid body entry found after extension."

def check_validity(self) -> bool:
valid_target = isinstance(self._target, str) and len(self._target) > 0
valid_target = is_non_empty_string(type(self), "target", self._target)
valid_condition = self._condition is None or (
is_non_empty_string(type(self), "condition", self._condition)
)
valid_events = self._events is None or (
isinstance(self._events, list) and all(isinstance(ev, str) for ev in self._events)
)
valid_condition = self._condition is None or (
isinstance(self._condition, str) and len(self._condition) > 0
)
valid_body = self._body is None or valid_execution_body(self._body)
if not valid_target:
print("Error: SCXML transition: target is not valid.")
if not valid_events:
print("Error: SCXML transition: events are not valid.\nList of events:")
for event in self._events:
print(f"\t-'{event}'.")
if not valid_condition:
print("Error: SCXML transition: condition is not valid.")
if not valid_body:
print("Error: SCXML transition: executable content is not valid.")
return valid_target and valid_events and valid_condition and valid_body
Expand Down

0 comments on commit dab8efe

Please sign in to comment.