| |
| h2. Model Details |
| |
| h3. Qualified name |
| |
| The following image shows the logical dependency between the name segments and describe the used notations. The details differ in terms of delimiters and encoding of the segments. |
| |
| !../pictures/dev_model_qualified_name.png! |
| |
| |
| h3. Unique ID generation |
| |
| AMALTHEA uses a named based schema to reference other elements inside of a model. |
| A custom implementation is used instead of the standard EMF mechanism, which uses an index based implementation. |
| The target element id is identified by the following schema: |
| |
| bc. |
| java.net.URLEncoder.encode(<name of element>, StandardCharsets.UTF_8.toString)) + "?type=" + <element>.eClass.name |
| |
| Samples: |
| |
| Refering to a Runnable element with name foo in a RunnableCall looks like the following snippet: |
| |
| bc. |
| <items xsi:type="am:RunnableCall" runnable="foo?type=Runnable" /> |
| |
| |
| h3. Interfaces and base objects |
| |
| Several interfaces and abstract classes are defined in the common model. |
| They provide basic common functionality for all objects, which are extending it, like the possibility to add __CustomAttributes__ or __Tags__. Tags are available at different elements with the purpose to group them together or to annotate them. |
| |
| !(scale)../pictures/model_common_interfaces_base_objects.png! |
| |
| |
| h3. Derived references |
| |
| Some derived references are introduces to simplify a multi-level navigation. They are read only. |
| |
| | |{text-align:center}. Reference | | |
| | @ISystem@ |>. *innerPorts* → | @QualifiedPort@ | |
| | @HwStructure@ |>. *innerPorts* → | @HwPort@ | |
| | @HwPath@ |>. *source* → | @ProcessingUnit@ | |
| | @HwPath@ |>. *destination* → | @HwDestination@ | |
| | @TaskScheduler@ |>. *childSchedulers* → | @TaskScheduler@ | |
| | @TaskScheduler@ |>. *parentScheduler* → | @TaskScheduler@ | |
| |
| |
| h3. Transient back pointers |
| |
| AMALTHEA maintains a number of back pointers in the model. These transient references of an object 'point back' to the object referring to it. |
| |
| h4. Container references |
| |
| Container references provide an easier access to the eContainer of an object. |
| |
| The following references are specified as opposite references and can be modified. |
| By the prefix "containing" they clearly indicate that a containment is changed. |
| |
| | | Container reference |>. Containment reference | | |
| | @Component@ |{color:green}. ← *containingComponent* |>. *ports* → | @ComponentPort@ | |
| | @EnumMode@ |{color:green}. ← *containingMode* |>. *literals* → | @ModeLiteral@ | |
| | @HwFeatureCategory@ |{color:green}. ← *containingCategory* |>. *features* → | @HwFeature@ | |
| | @HwAccessElement@ |{color:green}. ← *containingAccessElement* |>. *accessPath* → | @HwAccessPath@ | |
| | @RunnableCall@ |{color:green}. ← *containingCall* |>. *arguments* → | @CallArgument@ | |
| | @ISystem@ |{color:green}. ← *containingSystem* |>. *componentInstances* → | @ComponentInstance@ | |
| | @ISystem@ |{color:green}. ← *containingSystem* |>. *connectors* → | @Connector@ | |
| | @Namespace@ |{color:green}. ← *previousSegment* |>. *nextSegments* → | @Namespace@ | |
| | @Runnable@ |{color:green}. ← *containingRunnable* |>. *parameters* → | @RunnableParameter@ | |
| | @ComponentInterface@ |{color:green}. ← *containingInterface* |>. *subInterfaces* → | @SubInterface@ | |
| |
| The following references are specified as opposite references. |
| |
| | | Container reference (read only) |>. Reference | | |
| | @ProcessingUnit@ |{color:green}. ← *source* |>. *accessElements* → | @HwAccessElement@ | |
| | @TaskScheduler@ |{color:green}. ← *child* |>. *parentAssociation* → | @SchedulerAssociation@ | |
| |
| |
| The following container references are a special case. Because of the nested structure of sub elements the access to a dedicated container object is computed by traversing multiple eContainer references. |
| |
| | | Container reference (read only) |>. Containment reference | | |
| | @Runnable@ |{color:green}. ← *containingRunnable* |>. *activityGraph ...* → | @ActivityGraphItem@ | |
| | @Process@ |{color:green}. ← *containingProcess* |>. *activityGraph ...* → | @ActivityGraphItem@ | |
| | @ActivityGraph@ |{color:green}. ← *containingActivityGraph* |>. *items ...* → | @ActivityGraphItem@ | |
| | @Runnable@ |{color:green}. ← *containingRunnable* |>. *...* → | @DataDependency@ | |
| |
| |
| h4. References (via inverse index) |
| |
| The inverse index allows easier and faster navigation, at the expense of greater memory consumption. |
| The index is built on demand. |
| |
| The data model has some intermediate objects to express the call of a runnable or the access to a label. |
| These objects are containments of __Task__ or __Runnable__ and can have additional attributes. The back pointers support an easy way to answer queries like "Which tasks call runnable x ?" or "Which functions read label y ?". |
| |
| | | Back pointer (read only) |>. Reference | | |
| | @LabelAccess@ |{color:green}. ← *labelAccesses* |>. *data* → | @Label@ | |
| | @ChannelAccess@ |{color:green}. ← *channelAccesses* |>. *data* → | @Channel@ | |
| | @SemaphoreAccess@ |{color:green}. ← *semaphoreAccesses* |>. *semaphore* → | @Semaphore@ | |
| | @RunnableCall@ |{color:green}. ← *runnableCalls* |>. *runnable* → | @Runnable@ | |
| |
| All elements with memory representation (e.g. labels, runnables) can be mapped to a memory via a MemoryMapping. The back pointers provides a list of all mapping elements that refer to a specific memory or a specific MemoryElement. |
| |
| | | Back pointer (read only) |>. Reference | | |
| | @MemoryMapping@ |{color:green}. ← *mappings* |>. *memory* → | @Memory@ | |
| | @MemoryMapping@ |{color:green}. ← *mappings* |>. *abstractElement* → | @AbstractMemoryElement@ | |
| |
| Labels and runnables can be located in exactly one section. The back pointer provides a list of all elements that are assigned to a specific section. |
| |
| | | Back pointer (read only) |>. Reference | | |
| | @Label@ |{color:green}. ← *labels* |>. *section* → | @Section@ | |
| | @Runnable@ |{color:green}. ← *runnables* |>. *section* → | @Section@ | |
| |
| CustomEvent and InterProcessStimulus can have explicit triggers. The pointer is established from CustomEventTrigger and InterProcessTrigger. The back pointers provides easier access to the triggering runnables / processes. |
| |
| | | Back pointer (read only) |>. Reference | | |
| | @CustomEventTrigger@ |{color:green}. ← *explicitTriggers* |>. *event* → | @CustomEvent@ | |
| | @InterProcessTrigger@ |{color:green}. ← *explicitTriggers* |>. *stimulus* → | @InterProcessStimulus@ | |
| |
| Components define lists of included software elements (e.g. labels, runnables, semaphores). The back pointer provides access to all referring components. |
| |
| | | Back pointer (read only) |>. Reference | | |
| | @Component@ |{color:green}. ← *referringComponents* |>. *labels* → | @Label@ | |
| | @Component@ |{color:green}. ← *referringComponents* |>. *runnables* → | @Runnable@ | |
| | @Component@ |{color:green}. ← *referringComponents* |>. *processes* → | @AbstractProcess@ | |
| | @Component@ |{color:green}. ← *referringComponents* |>. *semaphores* → | @Semaphore@ | |
| | @Component@ |{color:green}. ← *referringComponents* |>. *osEvents* → | @OsEvent@ | |
| |
| Allocations refer to a scheduler (Scheduler, TaskScheduler, InterruptController). The back pointer provides access from the scheduler to the allocations. |
| |
| | | Back pointer (read only) |>. Reference | | |
| | @SchedulerAllocation@ |{color:green}. ← *schedulerAllocations* |>. *scheduler* → | @Scheduler@ | |
| | @RunnableAllocation@ |{color:green}. ← *runnableAllocations* |>. *scheduler* → | @Scheduler@ | |
| | @TaskAllocation@ |{color:green}. ← *taskAllocations* |>. *scheduler* → | @TaskScheduler@ | |
| | @ISRAllocation@ |{color:green}. ← *isrAllocations* |>. *controller* → | @InterruptController@ | |
| |
| Some other useful back references. |
| |
| | | Back pointer (read only) |>. Reference | | |
| | @Process@ |{color:green}. ← *affectedProcesses* |>. *stimuli* → | @Stimulus@ | |
| | @ITaggable@ |{color:green}. ← *taggedObjects* |>. *tags* → | @Tag@ | |
| | @SchedulerAssociation@ |{color:green}. ← *childAssociations* |>. *parent* → | @TaskScheduler@ | |
| | @INamespaceMember@ |{color:green}. ← *memberObjects* |>. *namespace* → | @Namespace@ | |
| | @IComponentStructureMember@ |{color:green}. ← *memberObjects* |>. *structure* → | @ComponentStructure@ | |
| | @HwConnection@ |{color:green}. ← *connections* |>. *port1* → | @HwPort@ | |
| | @HwConnection@ |{color:green}. ← *connections* |>. *port2* → | @HwPort@ | |
| |
| |
| h4. Implementation |
| |
| **Xcore:** |
| |
| A derived back pointer is computed by %*AmaltheaIndex.getInverseReferences(...)*%. |
| The visiblity in the generated code and in the user interface is controlled by %*@GenModel*% annotations. |
| |
| Example |
| |
| bc.. |
| class Runnable extends AbstractMemoryElement |
| { ... |
| // back pointer (readonly) |
| @GenModel(documentation="<p><b>Returns an <em>immutable</em> list of callers (RunnableCalls).</b></p>") |
| @GenModel(propertyCategory="Read only", propertyFilterFlags="org.eclipse.ui.views.properties.expert") |
| refers transient readonly volatile derived RunnableCall[] runnableCalls get { |
| AmaltheaIndex.getInverseReferences(this, AmaltheaPackage.eINSTANCE.runnable_RunnableCalls, |
| #{AmaltheaPackage.eINSTANCE.runnableCall_Runnable} ) |
| } |
| p. |
| |
| h4. User Interface |
| |
| !../pictures/impl/model_transient_backpointer_ui.png! |