Introspection
The MARTe2 Introspection and IntrospectionT allow to register in the ClassRegistryDatabase members of a class or a C struct
.
This allows to develop components that query and adapt in runtime to the properties of a given class or structure. Examples are the configuration of Objects using structures and the interchange of real-time data between GAMs.
Class/struct register
Note
See the following link for a full data-driven alternative on how to create and register structures.
In order to automatically register a MARTe Object or a C struct
into the ClassRegistryDatabase, the following macros must be used:
DECLARE_CLASS_MEMBER(className, memberName, type, modifierString, attributeString )
, where:className
is the name of the class or structure;memberName
is the name of the member to be registered;type
is the member type (a basic type or a structure);modifierStrubg
are the possible member modifiers as described in the documentation of the methodGetMemberModifiers
of IntrospectionEntry;attributeString
is a list of attributes as specified in the documentation of the methodGetMemberAtributes
of IntrospectionEntry.
DECLARE_CLASS_INTROSPECTION(className, introEntryArray)
or, in the case ofC structs
,DECLARE_STRUCT_INTROSPECTION(structName, introEntryArray)
, where:className
is the name of the class andstructName
is the name of the struct;introEntryArray
is a zero terminated array of all the previously declared IntrospectionEntry elements for this class or structure. The entries in the array shall be named&className_memberName_introspectionEntry
, whereclassName
is the name of the struct of class andmemberName
is the name of the member to be registered.
struct A {
MARTe::float32 f1;
MARTe::float32 f2;
};
struct B {
struct A a1;
struct A a2;
};
...
DECLARE_CLASS_MEMBER(A, f1, float32, "", "");
DECLARE_CLASS_MEMBER(A, f2, float32, "", "");
static const MARTe::IntrospectionEntry* AStructEntries[] = { &A_f1_introspectionEntry, &A_f2_introspectionEntry, 0 };
DECLARE_STRUCT_INTROSPECTION(A, AStructEntries)
...
DECLARE_CLASS_MEMBER(B, a1, A, "", "");
DECLARE_CLASS_MEMBER(B, a2, A, "", "");
static const MARTe::IntrospectionEntry* BStructEntries[] = { &B_a1_introspectionEntry, &B_a2_introspectionEntry, 0 };
DECLARE_STRUCT_INTROSPECTION(B, BStructEntries)
Note
This introspection infrastructure is expected to be mostly used by higher level tools, which will automatically generate the required code.
Query instrospection
The introspection information is accessible by querying the ClassRegistryDatabase against the relevant struct/class name and by calling the method GetIntrospection
on the retrieved ClassRegistryItem (see example below).
Examples
The following example show how to register a structure, a MARTe object and to how to query their properties in runtime.
1/**
2 * @file ObjectsExample3.cpp
3 * @brief Source file for class ObjectsExample3
4 * @date 14/03/2018
5 * @author Andre' Neto
6 *
7 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
8 * the Development of Fusion Energy ('Fusion for Energy').
9 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
10 * by the European Commission - subsequent versions of the EUPL (the "Licence")
11 * You may not use this work except in compliance with the Licence.
12 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
13 *
14 * @warning Unless required by applicable law or agreed to in writing,
15 * software distributed under the Licence is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17 * or implied. See the Licence permissions and limitations under the Licence.
18
19 * @details This source file contains the definition of all the methods for
20 * the class ObjectsExample3 (public, protected, and private). Be aware that some
21 * methods, such as those inline could be defined on the header file, instead.
22 */
23
24#define DLL_API
25
26/*---------------------------------------------------------------------------*/
27/* Standard header includes */
28/*---------------------------------------------------------------------------*/
29
30/*---------------------------------------------------------------------------*/
31/* Project header includes */
32/*---------------------------------------------------------------------------*/
33#include "AdvancedErrorManagement.h"
34#include "ClassRegistryDatabase.h"
35#include "ErrorLoggerExample.h"
36#include "IntrospectionT.h"
37#include "IntrospectionEntry.h"
38#include "Object.h"
39#include "StreamString.h"
40
41/*---------------------------------------------------------------------------*/
42/* Static definitions */
43/*---------------------------------------------------------------------------*/
44
45/*---------------------------------------------------------------------------*/
46/* Method definitions */
47/*---------------------------------------------------------------------------*/
48namespace MARTe2Tutorial {
49/**
50 * @brief A MARTe::Object class will be automatically registered
51 * into the ClassRegistryDatabase.
52 */
53class ControllerEx1: public MARTe::Object {
54public:
55 CLASS_REGISTER_DECLARATION()
56
57 /**
58 * @brief NOOP.
59 */
60ControllerEx1 () {
61 gain = 0xffu;
62 }
63
64 /**
65 * A property.
66 */
67 MARTe::uint32 gain;
68
69 /**
70 * Another property.
71 */
72 MARTe::float32 reference[6];
73};
74
75CLASS_REGISTER(ControllerEx1, "")
76//Register the member gain
77DECLARE_CLASS_MEMBER(ControllerEx1, gain, uint32, "", "");
78DECLARE_CLASS_MEMBER(ControllerEx1, reference, float32, "[6]", "");
79//The array members must follow the naming convention CLASSNAME_MEMBERNAME_introspectionEntry
80static const MARTe::IntrospectionEntry* ControllerEx1ClassEntries[] = { &ControllerEx1_gain_introspectionEntry,
81 &ControllerEx1_reference_introspectionEntry, 0 };
82//Finally declare the class as introspectable
83DECLARE_CLASS_INTROSPECTION(ControllerEx1, ControllerEx1ClassEntries)
84
85//An introspectable structure
86struct A {
87 MARTe::float32 f1;
88 MARTe::float32 f2;
89};
90struct B {
91 struct A a1;
92 struct A a2;
93};
94//The strategy is identical to the class registration
95DECLARE_CLASS_MEMBER(A, f1, float32, "", "");
96DECLARE_CLASS_MEMBER(A, f2, float32, "", "");
97static const MARTe::IntrospectionEntry* AStructEntries[] = { &A_f1_introspectionEntry, &A_f2_introspectionEntry, 0 };
98DECLARE_STRUCT_INTROSPECTION(A, AStructEntries)
99DECLARE_CLASS_MEMBER(B, a1, A, "", "");
100DECLARE_CLASS_MEMBER(B, a2, A, "", "");
101static const MARTe::IntrospectionEntry* BStructEntries[] = { &B_a1_introspectionEntry, &B_a2_introspectionEntry, 0 };
102DECLARE_STRUCT_INTROSPECTION(B, BStructEntries)
103
104}
105
106static void PrintIntrospection(const MARTe::char8 * const structOrClassToSearch) {
107 using namespace MARTe;
108
109 ClassRegistryDatabase *crdSingleton = ClassRegistryDatabase::Instance();
110 const ClassRegistryItem *classRegistryItem = crdSingleton->Find(structOrClassToSearch);
111 if (classRegistryItem != NULL) {
112 //Get the object builder (which knows how to build classes of this type).
113 const Introspection *introspection = classRegistryItem->GetIntrospection();
114 //Print all the available information.
115 if (introspection != NULL) {
116 uint32 numberOfMembers = introspection->GetNumberOfMembers();
117 uint32 n;
118 REPORT_ERROR_STATIC(ErrorManagement::Information, "[%s] number of members: %d:", structOrClassToSearch, numberOfMembers);
119 for (n = 0u; n < numberOfMembers; n++) {
120 const IntrospectionEntry entry = introspection->operator [](n);
121 const char8 * const memberName = entry.GetMemberName();
122 const char8 * const memberType = entry.GetMemberTypeName();
123 const char8 * const memberModifiers = entry.GetMemberModifiers();
124 const char8 * const memberAttributes = entry.GetMemberAttributes();
125 REPORT_ERROR_STATIC(ErrorManagement::Information, "[%d] [name]: %s [type]: %s [mods]: %s [attrs]: %s", n, memberName, memberType, memberModifiers, memberAttributes);
126 }
127 }
128 else {
129 REPORT_ERROR_STATIC(ErrorManagement::FatalError, "No introspection available for struct or class "
130 "with name: %s", structOrClassToSearch);
131 }
132 }
133 else {
134 REPORT_ERROR_STATIC(ErrorManagement::FatalError, "Could not find struct or class "
135 "with name: %s", structOrClassToSearch);
136 }
137}
138
139int main(int argc, char **argv) {
140 using namespace MARTe;
141 using namespace MARTe2Tutorial;
142 SetErrorProcessFunction(&ErrorProcessExampleFunction);
143
144 PrintIntrospection("ControllerEx1");
145 PrintIntrospection("A");
146 PrintIntrospection("B");
147
148 return 0;
149}
Instructions on how to compile and execute the examples can be found here.