Skip to content

Commit

Permalink
Refactoring template API
Browse files Browse the repository at this point in the history
- Template classes can now choose if created element is added to package
- Change argument type in element template create-method
- Rename init_package_map in Workspace class to create_package_map
- Create example of creating composition using element template
  • Loading branch information
cogu committed Mar 24, 2024
1 parent 9e7c81d commit 016d144
Show file tree
Hide file tree
Showing 16 changed files with 344 additions and 123 deletions.
90 changes: 78 additions & 12 deletions examples/template/demo_system/component.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""
Component type templates
"""
# flake8: noqa
# pylint: disable=C0103, C0301


Expand All @@ -12,17 +11,16 @@
NAMESPACE = "Default"


def create_ReceiverComponent(_0: str,
def create_ReceiverComponent(_0: ar_element.Package,
workspace: ar_workspace.Workspace,
deps: dict[str, ar_element.ARElement] | None,
**_1) -> ar_element.ApplicationSoftwareComponentType:
"""
Create Receiver component type
"""

timer_interface = deps[portinterface.FreeRunningTimer_I.ref(workspace)]
vehicle_speed_interface = deps[portinterface.EngineSpeed_I.ref(workspace)]
engine_speed_interface = deps[portinterface.VehicleSpeed_I.ref(workspace)]
vehicle_speed_interface = deps[portinterface.VehicleSpeed_I.ref(workspace)]
engine_speed_interface = deps[portinterface.EngineSpeed_I.ref(workspace)]
engine_speed_init = deps[constants.EngineSpeed_IV.ref(workspace)]
vehicle_speed_init = deps[constants.VehicleSpeed_IV.ref(workspace)]
swc = ar_element.ApplicationSoftwareComponentType("ReceiverComponent")
Expand All @@ -43,14 +41,82 @@ def create_ReceiverComponent(_0: str,
return swc


def create_TimerComponent(_0: ar_element.Package,
workspace: ar_workspace.Workspace,
deps: dict[str, ar_element.ARElement] | None,
**_1) -> ar_element.ApplicationSoftwareComponentType:
"""
Create TimerComponent component type
"""
timer_interface = deps[portinterface.FreeRunningTimer_I.ref(workspace)]
swc = ar_element.ApplicationSoftwareComponentType("TimerComponent")
swc.create_provide_port("FreeRunningTimer", timer_interface, com_spec={"GetTime": {"queue_length": 1},
"IsTimerElapsed": {"queue_length": 1}
})
swc.create_internal_behavior()
return swc


def create_composition_component(package: ar_element.Package,
workspace: ar_workspace.Workspace,
deps: dict[str, ar_element.ARElement] | None,
**_1) -> ar_element.ApplicationSoftwareComponentType:
"""
Creates a composition component
The created swc must be manually added to the package, otherwise the
swc.create_connector will not work properly.
To disable automatic adding of the SWC by the workspace, set append_to_package to False
in the template constructor.
"""
engine_speed_interface = deps[portinterface.EngineSpeed_I.ref(workspace)]
vehicle_speed_interface = deps[portinterface.VehicleSpeed_I.ref(workspace)]
engine_speed_init = deps[constants.EngineSpeed_IV.ref(workspace)]
vehicle_speed_init = deps[constants.VehicleSpeed_IV.ref(workspace)]
receiver_component = workspace.find(ReceiverComponent.ref(workspace))
timer_component = workspace.find(TimerComponent.ref(workspace))
assert isinstance(receiver_component, ar_element.ApplicationSoftwareComponentType)
assert isinstance(timer_component, ar_element.ApplicationSoftwareComponentType)
swc = ar_element.CompositionSwComponentType("CompositionComponent")
swc.create_require_port("EngineSpeed", engine_speed_interface, com_spec={"init_value": engine_speed_init.ref(),
"uses_end_to_end_protection": False})
swc.create_require_port("VehicleSpeed", vehicle_speed_interface, com_spec={"init_value": vehicle_speed_init.ref(),
"uses_end_to_end_protection": False})

swc.create_component_prototype(receiver_component)
swc.create_component_prototype(timer_component)
# Element must be added to workspace before connectors can be created
package.append(swc)
swc.create_connector("TimerComponent/FreeRunningTimer", "ReceiverComponent/FreeRunningTimer", workspace)
swc.create_connector("VehicleSpeed", "ReceiverComponent/VehicleSpeed", workspace)
swc.create_connector("EngineSpeed", "ReceiverComponent/EngineSpeed", workspace)
return swc


ReceiverComponent = factory.GenericComponentTypeTemplate("ReceiverComponent",
NAMESPACE,
create_ReceiverComponent,
depends=[portinterface.EngineSpeed_I,
portinterface.VehicleSpeed_I,
portinterface.FreeRunningTimer_I,
constants.EngineSpeed_IV,
constants.VehicleSpeed_IV,])
NAMESPACE,
create_ReceiverComponent,
depends=[portinterface.EngineSpeed_I,
portinterface.VehicleSpeed_I,
portinterface.FreeRunningTimer_I,
constants.EngineSpeed_IV,
constants.VehicleSpeed_IV])
ReceiverComponent_Implementation = factory.SwcImplementationTemplate("ReceiverComponent_Implementation",
NAMESPACE,
component_type=ReceiverComponent)
TimerComponent = factory.GenericComponentTypeTemplate("TimerComponent",
NAMESPACE,
create_TimerComponent,
depends=[portinterface.FreeRunningTimer_I])
TimerComponent_Implementation = factory.SwcImplementationTemplate("TimerComponent_Implementation",
NAMESPACE,
component_type=TimerComponent)
CompositionComponent = factory.GenericComponentTypeTemplate("CompositionComponent",
NAMESPACE,
create_composition_component,
depends=[portinterface.EngineSpeed_I,
portinterface.VehicleSpeed_I,
constants.EngineSpeed_IV,
constants.VehicleSpeed_IV,
ReceiverComponent_Implementation,
TimerComponent_Implementation],
append_to_package=False)
39 changes: 20 additions & 19 deletions examples/template/demo_system/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def __init__(self,
self.native_declaration = native_declaration

def create(self,
element_ref: str,
package: ar_element.Package,
workspace: ar_workspace.Workspace,
dependencies: dict[str, ar_element.ARElement] | None,
**kwargs) -> ar_element.SwBaseType:
Expand Down Expand Up @@ -58,7 +58,7 @@ def __init__(self,
self.upper_limit = upper_limit

def create(self,
element_ref: str,
package: ar_element.Package,
workspace: ar_workspace.Workspace,
dependencies: dict[str, ar_element.ARElement] | None,
**kwargs) -> ar_element.DataConstraint:
Expand Down Expand Up @@ -87,7 +87,7 @@ def __init__(self,
self.desc = desc

def create(self,
element_ref: str,
package: ar_element.Package,
workspace: ar_workspace.Workspace,
dependencies: dict[str, ar_element.ARElement] | None,
**kwargs) -> ar_element.CompuMethod:
Expand Down Expand Up @@ -133,7 +133,7 @@ def __init__(self,
self.type_emitter = type_emitter

def create(self,
element_ref: str,
package: ar_element.Package,
workspace: ar_workspace.Workspace,
dependencies: dict[str, ar_element.ARElement] | None,
**kwargs) -> ar_element.ImplementationDataType:
Expand Down Expand Up @@ -205,7 +205,7 @@ def _create_compu_method(self,
return CompuMethodEnumTemplate(element_name + suffix, namespace_name, value_table, auto_label=False)

def create(self,
element_ref: str,
package: ar_element.Package,
workspace: ar_workspace.Workspace,
dependencies: dict[str, ar_element.ARElement] | None,
**kwargs) -> ar_element.ImplementationDataType:
Expand Down Expand Up @@ -242,7 +242,7 @@ def __init__(self,
self.initial_mode_name = initial_mode_name

def create(self,
element_ref: str,
package: ar_element.Package,
workspace: ar_workspace.Workspace,
dependencies: dict[str, ar_element.ARElement] | None,
**kwargs) -> ar_element.ModeDeclarationGroup:
Expand All @@ -251,7 +251,7 @@ def create(self,
"""
initial_mode_ref = None
if self.initial_mode_name is not None:
initial_mode_ref = '/'.join([element_ref, self.initial_mode_name])
initial_mode_ref = '/'.join([str(package.ref()), self.element_name, self.initial_mode_name])
elem = ar_element.ModeDeclarationGroup(name=self.element_name,
mode_declarations=self.mode_declarations,
initial_mode_ref=initial_mode_ref)
Expand All @@ -276,7 +276,7 @@ def __init__(self,
self.is_service = is_service

def create(self,
element_ref: str,
package: ar_element.Package,
workspace: ar_workspace.Workspace,
dependencies: dict[str, ar_element.ARElement] | None,
**kwargs) -> ar_element.ModeSwitchInterface:
Expand All @@ -288,8 +288,8 @@ def create(self,
return elem


CreateFuncType = Callable[[str, ar_workspace.Workspace, dict[str, ar_element.ARElement] | None],
ar_element.PortInterface]
CreateFuncType = Callable[[ar_element.Package, ar_workspace.Workspace, dict[str, ar_element.ARElement] | None],
ar_element.ARElement]


class GenericPortInterfaceTemplate(ar_template.ElementTemplate):
Expand All @@ -306,14 +306,14 @@ def __init__(self,
self.create_func = create_func

def create(self,
element_ref: str,
package: ar_element.Package,
workspace: ar_workspace.Workspace,
dependencies: dict[str, ar_element.ARElement] | None,
**kwargs) -> ar_element.PortInterface:
"""
Create method
"""
elem = self.create_func(element_ref, workspace, dependencies, **kwargs)
elem = self.create_func(package, workspace, dependencies, **kwargs)
return elem


Expand All @@ -333,7 +333,7 @@ def __init__(self,
self.data_element_name = data_element_name

def create(self,
element_ref: str,
package: ar_element.Package,
workspace: ar_workspace.Workspace,
dependencies: dict[str, ar_element.ARElement] | None,
**kwargs) -> ar_element.SenderReceiverInterface:
Expand Down Expand Up @@ -361,19 +361,20 @@ def __init__(self,
element_name: str,
namespace_name: str,
create_func: CreateFuncType,
depends: list[TemplateBase] | None = None) -> None:
super().__init__(element_name, namespace_name, ar_enum.PackageRole.COMPONENT_TYPE, depends)
depends: list[TemplateBase] | None = None,
append_to_package: bool = True) -> None:
super().__init__(element_name, namespace_name, ar_enum.PackageRole.COMPONENT_TYPE, depends, append_to_package)
self.create_func = create_func

def create(self,
element_ref: str,
package: ar_element.Package,
workspace: ar_workspace.Workspace,
dependencies: dict[str, ar_element.ARElement] | None,
**kwargs) -> ar_element.PortInterface:
"""
Create method
"""
elem = self.create_func(element_ref, workspace, dependencies, **kwargs)
elem = self.create_func(package, workspace, dependencies, **kwargs)
return elem


Expand All @@ -390,7 +391,7 @@ def __init__(self,
self.component_type = component_type

def create(self,
_0: str,
_0: ar_element.Package,
workspace: ar_workspace.Workspace,
dependencies: dict[str, ar_element.ARElement] | None,
**kwargs) -> ar_element.SwBaseType:
Expand All @@ -417,7 +418,7 @@ def __init__(self,
self.value = value

def create(self,
_0: str,
_0: ar_element.Package,
_1: ar_workspace.Workspace,
_2: dict[str, ar_element.ARElement] | None,
**_3) -> ar_element.SwBaseType:
Expand Down
2 changes: 1 addition & 1 deletion examples/template/generate_xml_using_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def apply_component_types(workspace: ar_workspace.Workspace):
"""
Applies component type templates
"""
workspace.apply(component.ReceiverComponent_Implementation)
workspace.apply(component.CompositionComponent)


def main():
Expand Down
2 changes: 1 addition & 1 deletion examples/template/generate_xml_without_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def apply_component_types(workspace: ar_workspace.Workspace):
"""
Applies component type templates
"""
workspace.apply(component.ReceiverComponent_Implementation)
workspace.apply(component.CompositionComponent)


def main():
Expand Down
88 changes: 88 additions & 0 deletions examples/template/generated/CompositionComponent.arxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<AUTOSAR xsi:schemaLocation="http://autosar.org/schema/r4.0 AUTOSAR_00051.xsd" xmlns="http://autosar.org/schema/r4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AR-PACKAGES>
<AR-PACKAGE>
<SHORT-NAME>ComponentTypes</SHORT-NAME>
<ELEMENTS>
<COMPOSITION-SW-COMPONENT-TYPE>
<SHORT-NAME>CompositionComponent</SHORT-NAME>
<PORTS>
<R-PORT-PROTOTYPE>
<SHORT-NAME>EngineSpeed</SHORT-NAME>
<REQUIRED-COM-SPECS>
<NONQUEUED-RECEIVER-COM-SPEC>
<DATA-ELEMENT-REF DEST="VARIABLE-DATA-PROTOTYPE">/PortInterfaces/EngineSpeed_I/EngineSpeed</DATA-ELEMENT-REF>
<USES-END-TO-END-PROTECTION>false</USES-END-TO-END-PROTECTION>
<INIT-VALUE>
<CONSTANT-REFERENCE>
<CONSTANT-REF DEST="CONSTANT-SPECIFICATION">/Constants/EngineSpeed_IV</CONSTANT-REF>
</CONSTANT-REFERENCE>
</INIT-VALUE>
</NONQUEUED-RECEIVER-COM-SPEC>
</REQUIRED-COM-SPECS>
<REQUIRED-INTERFACE-TREF DEST="SENDER-RECEIVER-INTERFACE">/PortInterfaces/EngineSpeed_I</REQUIRED-INTERFACE-TREF>
</R-PORT-PROTOTYPE>
<R-PORT-PROTOTYPE>
<SHORT-NAME>VehicleSpeed</SHORT-NAME>
<REQUIRED-COM-SPECS>
<NONQUEUED-RECEIVER-COM-SPEC>
<DATA-ELEMENT-REF DEST="VARIABLE-DATA-PROTOTYPE">/PortInterfaces/VehicleSpeed_I/VehicleSpeed</DATA-ELEMENT-REF>
<USES-END-TO-END-PROTECTION>false</USES-END-TO-END-PROTECTION>
<INIT-VALUE>
<CONSTANT-REFERENCE>
<CONSTANT-REF DEST="CONSTANT-SPECIFICATION">/Constants/VehicleSpeed_IV</CONSTANT-REF>
</CONSTANT-REFERENCE>
</INIT-VALUE>
</NONQUEUED-RECEIVER-COM-SPEC>
</REQUIRED-COM-SPECS>
<REQUIRED-INTERFACE-TREF DEST="SENDER-RECEIVER-INTERFACE">/PortInterfaces/VehicleSpeed_I</REQUIRED-INTERFACE-TREF>
</R-PORT-PROTOTYPE>
</PORTS>
<COMPONENTS>
<SW-COMPONENT-PROTOTYPE>
<SHORT-NAME>ReceiverComponent</SHORT-NAME>
<TYPE-TREF DEST="APPLICATION-SW-COMPONENT-TYPE">/ComponentTypes/ReceiverComponent</TYPE-TREF>
</SW-COMPONENT-PROTOTYPE>
<SW-COMPONENT-PROTOTYPE>
<SHORT-NAME>TimerComponent</SHORT-NAME>
<TYPE-TREF DEST="APPLICATION-SW-COMPONENT-TYPE">/ComponentTypes/TimerComponent</TYPE-TREF>
</SW-COMPONENT-PROTOTYPE>
</COMPONENTS>
<CONNECTORS>
<ASSEMBLY-SW-CONNECTOR>
<SHORT-NAME>TimerComponent_FreeRunningTimer_ReceiverComponent_FreeRunningTimer</SHORT-NAME>
<PROVIDER-IREF>
<CONTEXT-COMPONENT-REF DEST="SW-COMPONENT-PROTOTYPE">/ComponentTypes/CompositionComponent/TimerComponent</CONTEXT-COMPONENT-REF>
<TARGET-P-PORT-REF DEST="P-PORT-PROTOTYPE">/ComponentTypes/TimerComponent/FreeRunningTimer</TARGET-P-PORT-REF>
</PROVIDER-IREF>
<REQUESTER-IREF>
<CONTEXT-COMPONENT-REF DEST="SW-COMPONENT-PROTOTYPE">/ComponentTypes/CompositionComponent/ReceiverComponent</CONTEXT-COMPONENT-REF>
<TARGET-R-PORT-REF DEST="R-PORT-PROTOTYPE">/ComponentTypes/ReceiverComponent/FreeRunningTimer</TARGET-R-PORT-REF>
</REQUESTER-IREF>
</ASSEMBLY-SW-CONNECTOR>
<DELEGATION-SW-CONNECTOR>
<SHORT-NAME>VehicleSpeed_ReceiverComponent_VehicleSpeed</SHORT-NAME>
<INNER-PORT-IREF>
<R-PORT-IN-COMPOSITION-INSTANCE-REF>
<CONTEXT-COMPONENT-REF DEST="SW-COMPONENT-PROTOTYPE">/ComponentTypes/CompositionComponent/ReceiverComponent</CONTEXT-COMPONENT-REF>
<TARGET-R-PORT-REF DEST="R-PORT-PROTOTYPE">/ComponentTypes/ReceiverComponent/VehicleSpeed</TARGET-R-PORT-REF>
</R-PORT-IN-COMPOSITION-INSTANCE-REF>
</INNER-PORT-IREF>
<OUTER-PORT-REF DEST="R-PORT-PROTOTYPE">/ComponentTypes/CompositionComponent/VehicleSpeed</OUTER-PORT-REF>
</DELEGATION-SW-CONNECTOR>
<DELEGATION-SW-CONNECTOR>
<SHORT-NAME>EngineSpeed_ReceiverComponent_EngineSpeed</SHORT-NAME>
<INNER-PORT-IREF>
<R-PORT-IN-COMPOSITION-INSTANCE-REF>
<CONTEXT-COMPONENT-REF DEST="SW-COMPONENT-PROTOTYPE">/ComponentTypes/CompositionComponent/ReceiverComponent</CONTEXT-COMPONENT-REF>
<TARGET-R-PORT-REF DEST="R-PORT-PROTOTYPE">/ComponentTypes/ReceiverComponent/EngineSpeed</TARGET-R-PORT-REF>
</R-PORT-IN-COMPOSITION-INSTANCE-REF>
</INNER-PORT-IREF>
<OUTER-PORT-REF DEST="R-PORT-PROTOTYPE">/ComponentTypes/CompositionComponent/EngineSpeed</OUTER-PORT-REF>
</DELEGATION-SW-CONNECTOR>
</CONNECTORS>
</COMPOSITION-SW-COMPONENT-TYPE>
</ELEMENTS>
</AR-PACKAGE>
</AR-PACKAGES>
</AUTOSAR>
Loading

0 comments on commit 016d144

Please sign in to comment.