Structures
Structures allow you to organize information to increase the overall clarity of your code. Much like a structure in C, these are collections of variables and their values, placed under one name.
The use of a structure is illustrated by the following example:
Mod [ Dims STRUCT [ Length; Width; Height; ]; ] Main [ … ]
An instance of the structure Dims can now be assigned to a variable as follows:
A = Dims();
You can also assign values to the various nodes in the same statement:
A = Dims(15, 30, 45);
In either, the variable A will now contain a structure that is 3 items long and that can be indexed using the keywords Length, Width and Height as defined.
The values can now be used as shown in the following examples:
Example 1:
Rval = A.Width;
Rval now holds the value 30.
Example 2:
A.Length = 42;
42 is now the value stored in index position 0 of our structure.
You can also use array indexing notation to access the underlying data:
A[1] == 30;
Structures and Dictionaries
It is interesting to note that structures are based on the concepts of VTScada dictionaries and metadata.
The example above will create a variable named Dims. Dims is a constant containing a locked dictionary with a root value of the text "Dims". The underlying structure of Dims can be visualized as follows:
Dims = Dictionary(Dims) { dictionary with a root value of Invalid } Dims["Length"] = 0 { meta data elements of the dictionary } Dims["Width"] = 1 Dims["Height"] = 2
When Dims was instantiated as A in the examples above, A became a one dimensional array containing within it a pointer to Dims. This enables us to reference the contents of A using the keywords Length, Width and Height and get the correct pointers into the array A.
Because of this, it is possible to store additional data of use to the structure within the defining dictionary. In particular, the name of the structure is stored in the dictionary’s root. Thus, to identify an unknown structure, you can use the following expression:
RootValue(Cast(<struct>, 47);
Structures may be extended as shown in the following example:
{ structure 1, named Y } Y STRUCT [ A; B; ]; { structure 2, named X extends Y } X:Y STRUCT [ C; D; ]; A = X(); { variable A now holds a 4 element array, where the elements of the array will be in the order A, B, C, D }
Structures can also be compound data structures, containing other structures as well as more basic data types:
Z STRUCT [ A STRUCT [ Q; R; ]; B; C STRUCT [ S; ]; ];
Practice with structures
In this example, a structure will be used to store the current time in its separate components. This would be useful if you needed to refer to those time-parts in a variety of places within a module and didn't want to recalculate each instance.
Graphics [ StartTime { a timestamp }; TimeParts STRUCT [ { structure definition including... } ss { Seconds }; mm { Minutes }; hh { Hours (24) }; dd { Day of month }; M { Month of year (1-based) }; yy { Year }; ]; TimeStructure { an instance of the time structure }; Constant #SecInDay = 86400 { seconds in a day }; ] Init [ If 1 Main; [ StartTime = CurrentTime(); { Collect the current time stamp } TimeStructure = TimeParts( { break it up, storing each part } Time(StartTime % #SecInDay, "ss" ) { ss }, Time(StartTime % #SecInDay, "mm" ) { mm }, Time(StartTime % #SecInDay, "H" ) { hh }, Date(StartTime / #SecInDay, "dd" ) { dd }, Date(StartTime / #SecInDay, "MM" ) { M }, Date(StartTime / #SecInDay, "yyyy") { yy }); ] ] Main [ { display values from the time structure } ZText(100, 100, Concat("Year ", TimeStructure\yy), 5, 0); ZText(100, 115, Concat("Month ", TimeStructure\M), 5, 0); ZText(100, 130, Concat("Day ", TimeStructure\dd), 5, 0); ZText(100, 145, Concat("Hour ", TimeStructure\hh), 5, 0); ZText(100, 160, Concat("Min ", TimeStructure\mm), 5, 0); ZText(100, 175, Concat("Sec ", TimeStructure\ss), 5, 0); ] { End of System\Graphics } >