Skip to content

Commit

Permalink
Add XML support for events in SwcInternalBehavior
Browse files Browse the repository at this point in the history
- SwcInternalBehavior can read/write events
- Change version to v0.5.4a3
  • Loading branch information
cogu committed Aug 13, 2024
1 parent ba0d945 commit 8523c7c
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 45 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ Non-collectable elements are various sub-elements to collectable elements.
* DataWriteCompletedEvent | DATA-WRITE-COMPLETED-EVENT
* ExternalTriggerOccurredEvent | EXTERNAL-TRIGGER-OCCURRED-EVENT
* InitEvent | INIT-EVENT
* InternalBehavior | SWC-INTERNAL-BEHAVIOR (Partly implemented)
* runnables
* InternalTriggerOccurredEvent | INTERNAL-TRIGGER-OCCURRED-EVENT
* ModeSwitchedAckEvent | MODE-SWITCHED-ACK-EVENT
* OperationInvokedEvent | OPERATION-INVOKED-EVENT
* RunnableEntity | RUNNABLE-ENTITY
* SwcInternalBehavior | SWC-INTERNAL-BEHAVIOR (Partly implemented)
* events
* runnables
* SwcModeManagerErrorEvent | SWC-MODE-MANAGER-ERROR-EVENT
* SwcModeSwitchEvent | SWC-MODE-SWITCH-EVENT
* TimingEvent | TIMING-EVENT
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ Below is a rough roadmap of planned releases.

* Fix some early design mistakes
* Harmonize some member names to better match "qualified name" from XSD (BREAKING CHANGE)
* This mostly means that lot of class member names ending with "_ref" will have its suffix removed
* For the most part this means that several class members will have its "_ref" suffix stripped from its name.
* Attempt to break apart large Python files into smaller ones.

**v0.5.7** Add some missing elements and functions that wasn't prioritized before.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "autosar"
version = "0.5.4a2"
version = "0.5.4a3"
description = "A set of Python modules for working with AUTOSAR XML files"
readme = "README.md"
requires-python = ">=3.10"
Expand Down
60 changes: 57 additions & 3 deletions src/autosar/xml/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -5682,6 +5682,14 @@ def __init__(self,
**kwargs) -> None:
super().__init__(name, **kwargs)

def ref(self) -> RunnableEntityRef | None:
"""
Returns a reference to this element or
None if the element is not yet part of a package
"""
ref_str = self._calc_ref_string()
return None if ref_str is None else RunnableEntityRef(ref_str)


class RteEvent(Identifiable):
"""
Expand Down Expand Up @@ -6103,10 +6111,13 @@ class SwcInternalBehavior(InternalBehavior):
def __init__(self,
name: str,
runnables: RunnableEntity | list[RunnableEntity] | None = None,
events: RteEvent | list[RteEvent] | None = None,
**kwargs) -> None:
super().__init__(name, **kwargs)

self.runnables: list[RunnableEntity] = [] # .RUNNABLES
# .RUNNABLES
self.runnables: list[RunnableEntity] = []
# .EVENTS
self.events: list[RteEvent] = []

if runnables is not None:
if isinstance(runnables, list):
Expand All @@ -6115,6 +6126,13 @@ def __init__(self,
else:
self.append_runnable(runnables)

if events is not None:
if isinstance(events, list):
for event in events:
self.append_event(event)
else:
self.append_event(events)

def ref(self) -> SwcInternalBehaviorRef | None:
"""
Returns a reference to this element or
Expand All @@ -6125,9 +6143,45 @@ def ref(self) -> SwcInternalBehaviorRef | None:

def append_runnable(self, runnable: RunnableEntity) -> None:
"""
Appends runnable to internal list of runnables
Adds runnable to internal list of runnables
"""
if isinstance(runnable, RunnableEntity):
runnable.parent = self
self.runnables.append(runnable)
else:
raise TypeError(f"runnable must be of type RunnableEntity. Got {str(type(runnable))}")

def append_event(self, event: RteEvent) -> None:
"""
Adds event to internal list of events
"""
if isinstance(event, RteEvent):
event.parent = self
self.events.append(event)
else:
raise TypeError(f"event must derive from RteEvent. Got {str(type(event))}")

def create_runnable(self,
name: str,
activation_reasons: ActivationReasonArgumentType = None,
can_enter_leave: CanEnterLeaveArgumentType = None,
exclusive_area_nesting_order: ExclusiveAreaNestingOrderArgumentType = None,
minimum_start_interval: int | float | None = None,
reentrancy_level: ar_enum.ReentrancyLevel | None = None,
runs_insides: RunsInsidesArgumentType = None,
sw_addr_method: str | SwAddrMethodRef | None = None,
**kwargs) -> RunnableEntity:
"""
Creates a new runnable in this SwcInternalBehavior object
"""
data = {"activation_reasons": activation_reasons,
"can_enter_leave": can_enter_leave,
"exclusive_area_nesting_order": exclusive_area_nesting_order,
"minimum_start_interval": minimum_start_interval,
"reentrancy_level": reentrancy_level,
"runs_insides": runs_insides,
"sw_addr_method": sw_addr_method}
data.update(kwargs)
runnable = RunnableEntity(name, **data)
self.append_runnable(runnable)
return runnable
90 changes: 69 additions & 21 deletions src/autosar/xml/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@
ar_element.ModeSwitchReceiverComSpec,
ar_element.ClientComSpec]

RteEventElement = Union[ar_element.AsynchronousServerCallReturnsEvent,
ar_element.BackgroundEvent,
ar_element.DataReceivedEvent,
ar_element.DataReceiveErrorEvent,
ar_element.DataSendCompletedEvent,
ar_element.DataWriteCompletedEvent,
ar_element.ExternalTriggerOccurredEvent,
ar_element.InitEvent,
ar_element.InternalTriggerOccurredEvent,
ar_element.ModeSwitchedAckEvent,
ar_element.OperationInvokedEvent,
ar_element.SwcModeManagerErrorEvent,
ar_element.SwcModeSwitchEvent,
ar_element.TimingEvent,
ar_element.TransformerHardErrorEvent]

# Helper classes


Expand Down Expand Up @@ -185,6 +201,23 @@ def __init__(self,
'MODE-SWITCH-RECEIVER-COM-SPEC': self._read_mode_switch_receiver_com_spec,
'CLIENT-COM-SPEC': self._read_client_com_spec,
}
self.switcher_rte_event = {
'ASYNCHRONOUS-SERVER-CALL-RETURNS-EVENT': self._read_async_server_call_returns_event,
'BACKGROUND-EVENT': self._read_background_event,
'DATA-RECEIVE-ERROR-EVENT': self._read_data_receive_error_event,
'DATA-RECEIVED-EVENT': self._read_data_received_event,
'DATA-SEND-COMPLETED-EVENT': self._read_data_send_completed_event,
'DATA-WRITE-COMPLETED-EVENT': self._read_data_write_completed_event,
'EXTERNAL-TRIGGER-OCCURRED-EVENT': self._read_external_trigger_occured_event,
'INIT-EVENT': self._read_init_event,
'INTERNAL-TRIGGER-OCCURRED-EVENT': self._read_internal_trigger_occured_event,
'MODE-SWITCHED-ACK-EVENT': self._read_mode_switched_ack_event,
'OPERATION-INVOKED-EVENT': self._read_operation_invoked_event,
'SWC-MODE-MANAGER-ERROR-EVENT': self._read_swc_mode_manager_error_event,
'SWC-MODE-SWITCH-EVENT': self._read_swc_mode_switch_event,
'TIMING-EVENT': self._read_timing_event,
'TRANSFORMER-HARD-ERROR-EVENT': self._read_transformer_hard_error_event,
}
self.switcher_non_collectable = { # Non-collectable, used only for unit testing
# Documentation elements
'ANNOTATION': self._read_annotation,
Expand Down Expand Up @@ -273,7 +306,7 @@ def __init__(self,
'BACKGROUND-EVENT': self._read_background_event,
'DATA-RECEIVE-ERROR-EVENT': self._read_data_receive_error_event,
'DATA-RECEIVED-EVENT': self._read_data_received_event,
'DATA-SEND-COMPLETED-EVENT': self._read_send_completed_event,
'DATA-SEND-COMPLETED-EVENT': self._read_data_send_completed_event,
'DATA-WRITE-COMPLETED-EVENT': self._read_data_write_completed_event,
'EXTERNAL-TRIGGER-OCCURRED-EVENT': self._read_external_trigger_occured_event,
'INIT-EVENT': self._read_init_event,
Expand Down Expand Up @@ -4713,7 +4746,7 @@ def _read_runnable_entity_group(self, child_elements: ChildElementMap, data: dic
child_elements.skip("WRITTEN-LOCAL-VARIABLES")
child_elements.skip("VARIATION-POINT")

def _read_rte_event(self, child_elements: ChildElementMap, data: dict) -> None:
def _read_rte_event_group(self, child_elements: ChildElementMap, data: dict) -> None:
"""
Reads group AR:RTE-EVENT
"""
Expand All @@ -4740,7 +4773,7 @@ def _read_async_server_call_returns_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
xml_child = child_elements.get("EVENT-SOURCE-REF")
if xml_child is not None:
data["event_source"] = self._read_async_server_call_result_point_ref(xml_child)
Expand All @@ -4759,7 +4792,7 @@ def _read_background_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
self._report_unprocessed_elements(child_elements)
return ar_element.BackgroundEvent(**data)

Expand All @@ -4775,7 +4808,7 @@ def _read_data_receive_error_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
xml_child = child_elements.get("DATA-IREF")
if xml_child is not None:
data["data"] = self._read_r_variable_in_atomic_swc_instance_ref(xml_child)
Expand All @@ -4794,16 +4827,16 @@ def _read_data_received_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
xml_child = child_elements.get("DATA-IREF")
if xml_child is not None:
data["data"] = self._read_r_variable_in_atomic_swc_instance_ref(xml_child)
self._report_unprocessed_elements(child_elements)
return ar_element.DataReceivedEvent(**data)

def _read_send_completed_event(self,
xml_element: ElementTree.Element
) -> ar_element.DataSendCompletedEvent:
def _read_data_send_completed_event(self,
xml_element: ElementTree.Element
) -> ar_element.DataSendCompletedEvent:
"""
Reads complex Type AR:DATA-SEND-COMPLETED-EVENT
Tag variants: 'DATA-SEND-COMPLETED-EVENT'
Expand All @@ -4813,7 +4846,7 @@ def _read_send_completed_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
xml_child = child_elements.get("EVENT-SOURCE-REF")
if xml_child is not None:
data["event_source"] = self._read_variable_access_ref(xml_child)
Expand All @@ -4832,7 +4865,7 @@ def _read_data_write_completed_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
xml_child = child_elements.get("EVENT-SOURCE-REF")
if xml_child is not None:
data["event_source"] = self._read_variable_access_ref(xml_child)
Expand All @@ -4851,7 +4884,7 @@ def _read_external_trigger_occured_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
xml_child = child_elements.get("TRIGGER-IREF")
if xml_child is not None:
data["trigger"] = self._read_r_trigger_in_atomic_swc_instance_ref(xml_child)
Expand All @@ -4870,7 +4903,7 @@ def _read_init_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
self._report_unprocessed_elements(child_elements)
return ar_element.InitEvent(**data)

Expand All @@ -4886,7 +4919,7 @@ def _read_internal_trigger_occured_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
xml_child = child_elements.get("EVENT-SOURCE-REF")
if xml_child is not None:
data["event_source"] = self._read_internal_triggering_point_ref(xml_child)
Expand All @@ -4905,7 +4938,7 @@ def _read_mode_switched_ack_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
xml_child = child_elements.get("EVENT-SOURCE-REF")
if xml_child is not None:
data["event_source"] = self._read_mode_switch_point_ref(xml_child)
Expand All @@ -4924,7 +4957,7 @@ def _read_operation_invoked_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
xml_child = child_elements.get("OPERATION-IREF")
if xml_child is not None:
data["operation"] = self._read_p_operation_in_atomic_swc_instance_ref(xml_child)
Expand All @@ -4943,7 +4976,7 @@ def _read_swc_mode_manager_error_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
xml_child = child_elements.get("MODE-GROUP-IREF")
if xml_child is not None:
data["mode_group"] = self._read_p_mode_group_in_atomic_swc_instance_ref(xml_child)
Expand All @@ -4962,7 +4995,7 @@ def _read_swc_mode_switch_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
self._read_swc_mode_switch_event_group(child_elements, data)
self._report_unprocessed_elements(child_elements)
return ar_element.SwcModeSwitchEvent(**data)
Expand Down Expand Up @@ -5000,7 +5033,7 @@ def _read_timing_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
xml_child = child_elements.get("OFFSET")
if xml_child is not None:
data["offset"] = self._read_number(xml_child.text)
Expand All @@ -5022,7 +5055,7 @@ def _read_transformer_hard_error_event(self,
self._read_referrable(child_elements, data)
self._read_multi_language_referrable(child_elements, data)
self._read_identifiable(child_elements, xml_element.attrib, data)
self._read_rte_event(child_elements, data)
self._read_rte_event_group(child_elements, data)
self._read_transformer_hard_error_event_group(child_elements, data)
self._report_unprocessed_elements(child_elements)
return ar_element.TransformerHardErrorEvent(**data)
Expand Down Expand Up @@ -5076,7 +5109,12 @@ def _read_swc_internal_behavior_group(self, child_elements: ChildElementMap, dat
Most of it will be implemented in a future version
"""
child_elements.skip("AR-TYPED-PER-INSTANCE-MEMORYS")
child_elements.skip("EVENTS")
xml_child = child_elements.get("EVENTS")
if xml_child is not None:
events = []
for xml_grand_child in xml_child.findall("./*"):
events.append(self._read_rte_event_element(xml_grand_child))
data["events"] = events
child_elements.skip("EXCLUSIVE-AREA-POLICYS")
child_elements.skip("EXPLICIT-INTER-RUNNABLE-VARIABLES")
child_elements.skip("HANDLE-TERMINATION-AND-RESTART")
Expand All @@ -5097,3 +5135,13 @@ def _read_swc_internal_behavior_group(self, child_elements: ChildElementMap, dat
child_elements.skip("SUPPORTS-MULTIPLE-INSTANTIATION")
child_elements.skip("VARIATION-POINT-PROXYS")
child_elements.skip("VARIATION-POINT")

def _read_rte_event_element(self, xml_element: ElementTree.Element) -> RteEventElement:
"""
Reads one RTE event element
"""
read_method = self.switcher_rte_event.get(xml_element.tag, None)
if read_method is not None:
return read_method(xml_element)
else:
raise KeyError(f"Found no reader for '{xml_element.tag}'")
Loading

0 comments on commit 8523c7c

Please sign in to comment.