Project members: Class variant
With a class variant you can override another class definitions existing in your project. Once overridden, the variant can retrospectively modify all data members and the implementation of methods defined within the original class. Moreover, the variant can add new data members and new methods to the class. Class variants are represented in Composer by following bricks. Please note the additional small overlay in the icon of the brick:
The derivation of variants provides the fundamental technique to manage several product and design versions within one and the same GUI application. The selection of the appropriate variant occurs automatically depending on the condition specified in the VariantCond attribute of the variant member. Depending on this condition, Embedded Wizard distinguishes between following two types of a variant:
Type |
Short description |
---|---|
Static |
The condition for the selection of the respective variant results in a value well known at the code compilation time and immutable at the runtime. If this condition is true, the affected variant overrides the original class definition permanently. If the condition is false, the variant has no effect. |
Dynamic |
The condition for the variant selection depends on styles. Since styles can be activated and deactivated individually at the runtime, the overriding changes dynamically. |
A class definition, which has been overridden by a variant member is considered as being multi-variant. You can derive as many variants of an original member as you want. Moreover, one class variant can override another class variant resulting in a hierarchy of variants. With the Browser window you can inspect this hierarchy. Please note, a member overridden by a variant is signed in the Browser with an additional small icon. You can thus recognize multi-variant members easily. Additionally, the corresponding variant condition is shown between a pair of [...] (squared brackets):
The original class definition is overridden by a variant, which, in turn, is overridden by another variant. Both variants specify as condition true and are thus static.
It is important to understand, that with variant derivation the original class definition isn't simply replaced by a variant. Instead, the original class definition is inherit and overridden in object-oriented sense.
Create new class variant
You create a new class variant by simply deriving it from an existing class or another class variant. In the simplest case, if both, the original class and the variant are defined within the same unit, do following:
★First ensure, that the original class definition is selected.
★Then drag and drop the selected class while holding the keys CtrlShiftAlt pressed.
Deriving a new variant from a class existing within the same unit.
If the original member is not defined within the same unit, you can use the Browser window:
★First switch to the Composer page for the respective unit member, where you want to add the new variant.
★Then ensure that the Browser window is visible.
★Within the Browser locate the desired class definition. This can be done easily with Browser's own filter function.
★Select the found class in the Browser window.
★Drag and drop the selected class into the Composer area while holding the keys CtrlShiftAlt pressed.
Deriving a new variant by using the Browser window.
Alternatively, you can derive a class variant by using the clipboard functions Copy & Paste:
★First ensure, that the original class definition is selected (e.g. in Composer, Inspector or Browser).
★Press the keys CtrlC or use the menu item to copy the selected class into the clipboard.
★Eventually switch to another Composer page where you want to add the new derived class variant.
★Press the keys CtrlShiftAltV or use the menu item to add a new class variant by deriving it from the class stored in the clipboard.
Name the class variant
★First ensure, that the class variant is selected.
★Press the key F2 or select the menu item .
★Enter the new name in the Inspector window.
Variant members have a global character - they can be accessed from everywhere within your project. To address a variant member, you must always use its full name, which is composed of the unit name, the member is defined inside, and the name of the member itself, both separated by :: (double colon) signs. For example Examples::DeviceInterfaceClassWithCANBus.
Specify the variant condition
The effect of an overriding depends on the condition you specify in the attribute VariantCond of the respective variant member. Per default newly derived variants are configured with the condition true. They overrides thus statically and permanently the original member. You should therefore always review this attribute after deriving a new variant.
Please note, if two variants override the same original member and both variants are configured with the same condition, Embedded Wizard will report a compilation error because of the ambiguity.
Edit the class variant
You edit the derived class variant exactly as you do with the original class. In particular, you can add new members or override and modify inherited members. Please note, all new members you add to a class variant are considered as being private. They are not published in the original class.
Duplicate an existing class variant
You can create any number of copies of an already existing class variant member.
★First ensure, that the variant member is selected.
★Press the keys CtrlC and CtrlV in succession ...
★... or hold the key Ctrl pressed while you drag and drop the selected variant member.
★Finally rename the just duplicated class variant member ...
★... and review its variant condition.
You can also Drag & Drop a class variant member from the Browser into the Composer window and create so a duplicate of the affected member:
★First switch to the Composer page for the respective unit member, where you want to add the duplicate of the class variant.
★Then ensure that the Browser window is visible.
★Within the Browser window locate the desired class variant member. This can be done easily with Browser's own filter function.
★Select this class variant member in the Browser window.
★Drag and drop the selected class variant member into the Composer:
Duplicating a class variant by simply Drag & Drop it between the Browser and Composer windows
★Finally rename the just duplicated class variant member ...
★... and review its variant condition.
Use the class variant
Embedded Wizard selects the appropriate variant automatically either at the code generation time or just at the moment when a new instance of the corresponding original class is created. Accessing the class variants individually is not possible. The selection is controlled by the attribute VariantCond.
Delete a class variant
★First ensure, that the variant member is selected.
★Press the key DEL or select the menu item .
Attributes of a class variant
The following table shows the complete list of attributes provided by the class variant definition:
Attribute name |
Short description |
---|---|
Determines the position and the size of a variant brick within the Composer window. |
|
Contains the description for the variant member. |
|
Determines the condition to activate a particular variant member. |
|
Determines the original class definition to override by the variant member. |
Chora syntax of a class variant
This section describes the Chora syntax of how class variants are stored inside Embedded Wizard project files. The knowledge about the syntax can be helpful when you plan to process the project contents by third party tools. In particular, the general purpose Export and Import functionality introduced in version 14 requires a good understanding of how project members are represented in Chora syntax to correctly interpret the exported members and synthesize the Chora code for members to import. Please note, Embedded Wizard project files (and thus Chora code) are encoded as text in UTF-8 format.
In Chora syntax, class variant definition is always introduced with the keyword vclass, followed by the name of the variant, the fully qualified name of the original class member to override by the variant and a list of members (variables, methods, etc.) existing in the class variant. The variant name and the name of the original class are separated by : colon sign. The members belonging to the class variant are enclosed between a pair of following curly braces {..}. More details concerning the members which may exist in a class variant can be found in the section Edit the class. The name of the original class corresponds to the content of the attribute VariantOf.
The definition of a class variant can be initiated by a comment block providing optional description for the variant. The content of this comment corresponds to the value of the variant's attribute Description. Furthermore the directives $rect and $variant can be specified providing values for the corresponding attributes Brick and VariantCond. The following example demonstrate the described syntax:
// This is a class variant overriding the original class 'Example::BaseClass'. \ // In this variant the method 'Increment()' has been overriden. // // $rect determines the position of the brick inside Composer window. // $variant determines the condition when the variant is used. Here, let \ // assume, the variant depends on the profile named 'Debug'. $rect <210,10,420,50> $variant Debug vclass DebugBaseClass : Example::BaseClass { $rect <20,20,220,60> inherited method Increment() { super(); trace counter; } }
Each Chora file (or text exchanged with an external Export and/or Import tool) can be (or even should be) prefixed with $version directive. This directive determines the version number of the included Chora code. For details concerning the syntax of the version please see the chapter $version macro. Furthermore, the code can include a $scope directive followed by a path to a project member acting as the original owner of the corresponding code. That means the members described by the Chora code existed inside the member specified in $scope. In case of a class variant, $scope would specify the name of the unit the variant belongs to.