Skip to content

Commit 8523c7c

Browse files
committed
Add XML support for events in SwcInternalBehavior
- SwcInternalBehavior can read/write events - Change version to v0.5.4a3
1 parent ba0d945 commit 8523c7c

File tree

7 files changed

+256
-45
lines changed

7 files changed

+256
-45
lines changed

CHANGELOG.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@ Non-collectable elements are various sub-elements to collectable elements.
2828
* DataWriteCompletedEvent | DATA-WRITE-COMPLETED-EVENT
2929
* ExternalTriggerOccurredEvent | EXTERNAL-TRIGGER-OCCURRED-EVENT
3030
* InitEvent | INIT-EVENT
31-
* InternalBehavior | SWC-INTERNAL-BEHAVIOR (Partly implemented)
32-
* runnables
3331
* InternalTriggerOccurredEvent | INTERNAL-TRIGGER-OCCURRED-EVENT
3432
* ModeSwitchedAckEvent | MODE-SWITCHED-ACK-EVENT
3533
* OperationInvokedEvent | OPERATION-INVOKED-EVENT
3634
* RunnableEntity | RUNNABLE-ENTITY
35+
* SwcInternalBehavior | SWC-INTERNAL-BEHAVIOR (Partly implemented)
36+
* events
37+
* runnables
3738
* SwcModeManagerErrorEvent | SWC-MODE-MANAGER-ERROR-EVENT
3839
* SwcModeSwitchEvent | SWC-MODE-SWITCH-EVENT
3940
* TimingEvent | TIMING-EVENT

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ Below is a rough roadmap of planned releases.
258258

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

264264
**v0.5.7** Add some missing elements and functions that wasn't prioritized before.

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "autosar"
3-
version = "0.5.4a2"
3+
version = "0.5.4a3"
44
description = "A set of Python modules for working with AUTOSAR XML files"
55
readme = "README.md"
66
requires-python = ">=3.10"

src/autosar/xml/element.py

+57-3
Original file line numberDiff line numberDiff line change
@@ -5682,6 +5682,14 @@ def __init__(self,
56825682
**kwargs) -> None:
56835683
super().__init__(name, **kwargs)
56845684

5685+
def ref(self) -> RunnableEntityRef | None:
5686+
"""
5687+
Returns a reference to this element or
5688+
None if the element is not yet part of a package
5689+
"""
5690+
ref_str = self._calc_ref_string()
5691+
return None if ref_str is None else RunnableEntityRef(ref_str)
5692+
56855693

56865694
class RteEvent(Identifiable):
56875695
"""
@@ -6103,10 +6111,13 @@ class SwcInternalBehavior(InternalBehavior):
61036111
def __init__(self,
61046112
name: str,
61056113
runnables: RunnableEntity | list[RunnableEntity] | None = None,
6114+
events: RteEvent | list[RteEvent] | None = None,
61066115
**kwargs) -> None:
61076116
super().__init__(name, **kwargs)
6108-
6109-
self.runnables: list[RunnableEntity] = [] # .RUNNABLES
6117+
# .RUNNABLES
6118+
self.runnables: list[RunnableEntity] = []
6119+
# .EVENTS
6120+
self.events: list[RteEvent] = []
61106121

61116122
if runnables is not None:
61126123
if isinstance(runnables, list):
@@ -6115,6 +6126,13 @@ def __init__(self,
61156126
else:
61166127
self.append_runnable(runnables)
61176128

6129+
if events is not None:
6130+
if isinstance(events, list):
6131+
for event in events:
6132+
self.append_event(event)
6133+
else:
6134+
self.append_event(events)
6135+
61186136
def ref(self) -> SwcInternalBehaviorRef | None:
61196137
"""
61206138
Returns a reference to this element or
@@ -6125,9 +6143,45 @@ def ref(self) -> SwcInternalBehaviorRef | None:
61256143

61266144
def append_runnable(self, runnable: RunnableEntity) -> None:
61276145
"""
6128-
Appends runnable to internal list of runnables
6146+
Adds runnable to internal list of runnables
61296147
"""
61306148
if isinstance(runnable, RunnableEntity):
6149+
runnable.parent = self
61316150
self.runnables.append(runnable)
61326151
else:
61336152
raise TypeError(f"runnable must be of type RunnableEntity. Got {str(type(runnable))}")
6153+
6154+
def append_event(self, event: RteEvent) -> None:
6155+
"""
6156+
Adds event to internal list of events
6157+
"""
6158+
if isinstance(event, RteEvent):
6159+
event.parent = self
6160+
self.events.append(event)
6161+
else:
6162+
raise TypeError(f"event must derive from RteEvent. Got {str(type(event))}")
6163+
6164+
def create_runnable(self,
6165+
name: str,
6166+
activation_reasons: ActivationReasonArgumentType = None,
6167+
can_enter_leave: CanEnterLeaveArgumentType = None,
6168+
exclusive_area_nesting_order: ExclusiveAreaNestingOrderArgumentType = None,
6169+
minimum_start_interval: int | float | None = None,
6170+
reentrancy_level: ar_enum.ReentrancyLevel | None = None,
6171+
runs_insides: RunsInsidesArgumentType = None,
6172+
sw_addr_method: str | SwAddrMethodRef | None = None,
6173+
**kwargs) -> RunnableEntity:
6174+
"""
6175+
Creates a new runnable in this SwcInternalBehavior object
6176+
"""
6177+
data = {"activation_reasons": activation_reasons,
6178+
"can_enter_leave": can_enter_leave,
6179+
"exclusive_area_nesting_order": exclusive_area_nesting_order,
6180+
"minimum_start_interval": minimum_start_interval,
6181+
"reentrancy_level": reentrancy_level,
6182+
"runs_insides": runs_insides,
6183+
"sw_addr_method": sw_addr_method}
6184+
data.update(kwargs)
6185+
runnable = RunnableEntity(name, **data)
6186+
self.append_runnable(runnable)
6187+
return runnable

src/autosar/xml/reader.py

+69-21
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@
2929
ar_element.ModeSwitchReceiverComSpec,
3030
ar_element.ClientComSpec]
3131

32+
RteEventElement = Union[ar_element.AsynchronousServerCallReturnsEvent,
33+
ar_element.BackgroundEvent,
34+
ar_element.DataReceivedEvent,
35+
ar_element.DataReceiveErrorEvent,
36+
ar_element.DataSendCompletedEvent,
37+
ar_element.DataWriteCompletedEvent,
38+
ar_element.ExternalTriggerOccurredEvent,
39+
ar_element.InitEvent,
40+
ar_element.InternalTriggerOccurredEvent,
41+
ar_element.ModeSwitchedAckEvent,
42+
ar_element.OperationInvokedEvent,
43+
ar_element.SwcModeManagerErrorEvent,
44+
ar_element.SwcModeSwitchEvent,
45+
ar_element.TimingEvent,
46+
ar_element.TransformerHardErrorEvent]
47+
3248
# Helper classes
3349

3450

@@ -185,6 +201,23 @@ def __init__(self,
185201
'MODE-SWITCH-RECEIVER-COM-SPEC': self._read_mode_switch_receiver_com_spec,
186202
'CLIENT-COM-SPEC': self._read_client_com_spec,
187203
}
204+
self.switcher_rte_event = {
205+
'ASYNCHRONOUS-SERVER-CALL-RETURNS-EVENT': self._read_async_server_call_returns_event,
206+
'BACKGROUND-EVENT': self._read_background_event,
207+
'DATA-RECEIVE-ERROR-EVENT': self._read_data_receive_error_event,
208+
'DATA-RECEIVED-EVENT': self._read_data_received_event,
209+
'DATA-SEND-COMPLETED-EVENT': self._read_data_send_completed_event,
210+
'DATA-WRITE-COMPLETED-EVENT': self._read_data_write_completed_event,
211+
'EXTERNAL-TRIGGER-OCCURRED-EVENT': self._read_external_trigger_occured_event,
212+
'INIT-EVENT': self._read_init_event,
213+
'INTERNAL-TRIGGER-OCCURRED-EVENT': self._read_internal_trigger_occured_event,
214+
'MODE-SWITCHED-ACK-EVENT': self._read_mode_switched_ack_event,
215+
'OPERATION-INVOKED-EVENT': self._read_operation_invoked_event,
216+
'SWC-MODE-MANAGER-ERROR-EVENT': self._read_swc_mode_manager_error_event,
217+
'SWC-MODE-SWITCH-EVENT': self._read_swc_mode_switch_event,
218+
'TIMING-EVENT': self._read_timing_event,
219+
'TRANSFORMER-HARD-ERROR-EVENT': self._read_transformer_hard_error_event,
220+
}
188221
self.switcher_non_collectable = { # Non-collectable, used only for unit testing
189222
# Documentation elements
190223
'ANNOTATION': self._read_annotation,
@@ -273,7 +306,7 @@ def __init__(self,
273306
'BACKGROUND-EVENT': self._read_background_event,
274307
'DATA-RECEIVE-ERROR-EVENT': self._read_data_receive_error_event,
275308
'DATA-RECEIVED-EVENT': self._read_data_received_event,
276-
'DATA-SEND-COMPLETED-EVENT': self._read_send_completed_event,
309+
'DATA-SEND-COMPLETED-EVENT': self._read_data_send_completed_event,
277310
'DATA-WRITE-COMPLETED-EVENT': self._read_data_write_completed_event,
278311
'EXTERNAL-TRIGGER-OCCURRED-EVENT': self._read_external_trigger_occured_event,
279312
'INIT-EVENT': self._read_init_event,
@@ -4713,7 +4746,7 @@ def _read_runnable_entity_group(self, child_elements: ChildElementMap, data: dic
47134746
child_elements.skip("WRITTEN-LOCAL-VARIABLES")
47144747
child_elements.skip("VARIATION-POINT")
47154748

4716-
def _read_rte_event(self, child_elements: ChildElementMap, data: dict) -> None:
4749+
def _read_rte_event_group(self, child_elements: ChildElementMap, data: dict) -> None:
47174750
"""
47184751
Reads group AR:RTE-EVENT
47194752
"""
@@ -4740,7 +4773,7 @@ def _read_async_server_call_returns_event(self,
47404773
self._read_referrable(child_elements, data)
47414774
self._read_multi_language_referrable(child_elements, data)
47424775
self._read_identifiable(child_elements, xml_element.attrib, data)
4743-
self._read_rte_event(child_elements, data)
4776+
self._read_rte_event_group(child_elements, data)
47444777
xml_child = child_elements.get("EVENT-SOURCE-REF")
47454778
if xml_child is not None:
47464779
data["event_source"] = self._read_async_server_call_result_point_ref(xml_child)
@@ -4759,7 +4792,7 @@ def _read_background_event(self,
47594792
self._read_referrable(child_elements, data)
47604793
self._read_multi_language_referrable(child_elements, data)
47614794
self._read_identifiable(child_elements, xml_element.attrib, data)
4762-
self._read_rte_event(child_elements, data)
4795+
self._read_rte_event_group(child_elements, data)
47634796
self._report_unprocessed_elements(child_elements)
47644797
return ar_element.BackgroundEvent(**data)
47654798

@@ -4775,7 +4808,7 @@ def _read_data_receive_error_event(self,
47754808
self._read_referrable(child_elements, data)
47764809
self._read_multi_language_referrable(child_elements, data)
47774810
self._read_identifiable(child_elements, xml_element.attrib, data)
4778-
self._read_rte_event(child_elements, data)
4811+
self._read_rte_event_group(child_elements, data)
47794812
xml_child = child_elements.get("DATA-IREF")
47804813
if xml_child is not None:
47814814
data["data"] = self._read_r_variable_in_atomic_swc_instance_ref(xml_child)
@@ -4794,16 +4827,16 @@ def _read_data_received_event(self,
47944827
self._read_referrable(child_elements, data)
47954828
self._read_multi_language_referrable(child_elements, data)
47964829
self._read_identifiable(child_elements, xml_element.attrib, data)
4797-
self._read_rte_event(child_elements, data)
4830+
self._read_rte_event_group(child_elements, data)
47984831
xml_child = child_elements.get("DATA-IREF")
47994832
if xml_child is not None:
48004833
data["data"] = self._read_r_variable_in_atomic_swc_instance_ref(xml_child)
48014834
self._report_unprocessed_elements(child_elements)
48024835
return ar_element.DataReceivedEvent(**data)
48034836

4804-
def _read_send_completed_event(self,
4805-
xml_element: ElementTree.Element
4806-
) -> ar_element.DataSendCompletedEvent:
4837+
def _read_data_send_completed_event(self,
4838+
xml_element: ElementTree.Element
4839+
) -> ar_element.DataSendCompletedEvent:
48074840
"""
48084841
Reads complex Type AR:DATA-SEND-COMPLETED-EVENT
48094842
Tag variants: 'DATA-SEND-COMPLETED-EVENT'
@@ -4813,7 +4846,7 @@ def _read_send_completed_event(self,
48134846
self._read_referrable(child_elements, data)
48144847
self._read_multi_language_referrable(child_elements, data)
48154848
self._read_identifiable(child_elements, xml_element.attrib, data)
4816-
self._read_rte_event(child_elements, data)
4849+
self._read_rte_event_group(child_elements, data)
48174850
xml_child = child_elements.get("EVENT-SOURCE-REF")
48184851
if xml_child is not None:
48194852
data["event_source"] = self._read_variable_access_ref(xml_child)
@@ -4832,7 +4865,7 @@ def _read_data_write_completed_event(self,
48324865
self._read_referrable(child_elements, data)
48334866
self._read_multi_language_referrable(child_elements, data)
48344867
self._read_identifiable(child_elements, xml_element.attrib, data)
4835-
self._read_rte_event(child_elements, data)
4868+
self._read_rte_event_group(child_elements, data)
48364869
xml_child = child_elements.get("EVENT-SOURCE-REF")
48374870
if xml_child is not None:
48384871
data["event_source"] = self._read_variable_access_ref(xml_child)
@@ -4851,7 +4884,7 @@ def _read_external_trigger_occured_event(self,
48514884
self._read_referrable(child_elements, data)
48524885
self._read_multi_language_referrable(child_elements, data)
48534886
self._read_identifiable(child_elements, xml_element.attrib, data)
4854-
self._read_rte_event(child_elements, data)
4887+
self._read_rte_event_group(child_elements, data)
48554888
xml_child = child_elements.get("TRIGGER-IREF")
48564889
if xml_child is not None:
48574890
data["trigger"] = self._read_r_trigger_in_atomic_swc_instance_ref(xml_child)
@@ -4870,7 +4903,7 @@ def _read_init_event(self,
48704903
self._read_referrable(child_elements, data)
48714904
self._read_multi_language_referrable(child_elements, data)
48724905
self._read_identifiable(child_elements, xml_element.attrib, data)
4873-
self._read_rte_event(child_elements, data)
4906+
self._read_rte_event_group(child_elements, data)
48744907
self._report_unprocessed_elements(child_elements)
48754908
return ar_element.InitEvent(**data)
48764909

@@ -4886,7 +4919,7 @@ def _read_internal_trigger_occured_event(self,
48864919
self._read_referrable(child_elements, data)
48874920
self._read_multi_language_referrable(child_elements, data)
48884921
self._read_identifiable(child_elements, xml_element.attrib, data)
4889-
self._read_rte_event(child_elements, data)
4922+
self._read_rte_event_group(child_elements, data)
48904923
xml_child = child_elements.get("EVENT-SOURCE-REF")
48914924
if xml_child is not None:
48924925
data["event_source"] = self._read_internal_triggering_point_ref(xml_child)
@@ -4905,7 +4938,7 @@ def _read_mode_switched_ack_event(self,
49054938
self._read_referrable(child_elements, data)
49064939
self._read_multi_language_referrable(child_elements, data)
49074940
self._read_identifiable(child_elements, xml_element.attrib, data)
4908-
self._read_rte_event(child_elements, data)
4941+
self._read_rte_event_group(child_elements, data)
49094942
xml_child = child_elements.get("EVENT-SOURCE-REF")
49104943
if xml_child is not None:
49114944
data["event_source"] = self._read_mode_switch_point_ref(xml_child)
@@ -4924,7 +4957,7 @@ def _read_operation_invoked_event(self,
49244957
self._read_referrable(child_elements, data)
49254958
self._read_multi_language_referrable(child_elements, data)
49264959
self._read_identifiable(child_elements, xml_element.attrib, data)
4927-
self._read_rte_event(child_elements, data)
4960+
self._read_rte_event_group(child_elements, data)
49284961
xml_child = child_elements.get("OPERATION-IREF")
49294962
if xml_child is not None:
49304963
data["operation"] = self._read_p_operation_in_atomic_swc_instance_ref(xml_child)
@@ -4943,7 +4976,7 @@ def _read_swc_mode_manager_error_event(self,
49434976
self._read_referrable(child_elements, data)
49444977
self._read_multi_language_referrable(child_elements, data)
49454978
self._read_identifiable(child_elements, xml_element.attrib, data)
4946-
self._read_rte_event(child_elements, data)
4979+
self._read_rte_event_group(child_elements, data)
49474980
xml_child = child_elements.get("MODE-GROUP-IREF")
49484981
if xml_child is not None:
49494982
data["mode_group"] = self._read_p_mode_group_in_atomic_swc_instance_ref(xml_child)
@@ -4962,7 +4995,7 @@ def _read_swc_mode_switch_event(self,
49624995
self._read_referrable(child_elements, data)
49634996
self._read_multi_language_referrable(child_elements, data)
49644997
self._read_identifiable(child_elements, xml_element.attrib, data)
4965-
self._read_rte_event(child_elements, data)
4998+
self._read_rte_event_group(child_elements, data)
49664999
self._read_swc_mode_switch_event_group(child_elements, data)
49675000
self._report_unprocessed_elements(child_elements)
49685001
return ar_element.SwcModeSwitchEvent(**data)
@@ -5000,7 +5033,7 @@ def _read_timing_event(self,
50005033
self._read_referrable(child_elements, data)
50015034
self._read_multi_language_referrable(child_elements, data)
50025035
self._read_identifiable(child_elements, xml_element.attrib, data)
5003-
self._read_rte_event(child_elements, data)
5036+
self._read_rte_event_group(child_elements, data)
50045037
xml_child = child_elements.get("OFFSET")
50055038
if xml_child is not None:
50065039
data["offset"] = self._read_number(xml_child.text)
@@ -5022,7 +5055,7 @@ def _read_transformer_hard_error_event(self,
50225055
self._read_referrable(child_elements, data)
50235056
self._read_multi_language_referrable(child_elements, data)
50245057
self._read_identifiable(child_elements, xml_element.attrib, data)
5025-
self._read_rte_event(child_elements, data)
5058+
self._read_rte_event_group(child_elements, data)
50265059
self._read_transformer_hard_error_event_group(child_elements, data)
50275060
self._report_unprocessed_elements(child_elements)
50285061
return ar_element.TransformerHardErrorEvent(**data)
@@ -5076,7 +5109,12 @@ def _read_swc_internal_behavior_group(self, child_elements: ChildElementMap, dat
50765109
Most of it will be implemented in a future version
50775110
"""
50785111
child_elements.skip("AR-TYPED-PER-INSTANCE-MEMORYS")
5079-
child_elements.skip("EVENTS")
5112+
xml_child = child_elements.get("EVENTS")
5113+
if xml_child is not None:
5114+
events = []
5115+
for xml_grand_child in xml_child.findall("./*"):
5116+
events.append(self._read_rte_event_element(xml_grand_child))
5117+
data["events"] = events
50805118
child_elements.skip("EXCLUSIVE-AREA-POLICYS")
50815119
child_elements.skip("EXPLICIT-INTER-RUNNABLE-VARIABLES")
50825120
child_elements.skip("HANDLE-TERMINATION-AND-RESTART")
@@ -5097,3 +5135,13 @@ def _read_swc_internal_behavior_group(self, child_elements: ChildElementMap, dat
50975135
child_elements.skip("SUPPORTS-MULTIPLE-INSTANTIATION")
50985136
child_elements.skip("VARIATION-POINT-PROXYS")
50995137
child_elements.skip("VARIATION-POINT")
5138+
5139+
def _read_rte_event_element(self, xml_element: ElementTree.Element) -> RteEventElement:
5140+
"""
5141+
Reads one RTE event element
5142+
"""
5143+
read_method = self.switcher_rte_event.get(xml_element.tag, None)
5144+
if read_method is not None:
5145+
return read_method(xml_element)
5146+
else:
5147+
raise KeyError(f"Found no reader for '{xml_element.tag}'")

0 commit comments

Comments
 (0)