Post by (X) on Mar 5, 2024 4:07:10 GMT 1
This is a break-through moment for me and I thought I would share it immediately.
The code presented can obviously be modifed and improved.
I stumbled on this 'solution' while working on a project that will make use of a UDT (User Defined Type) designed to track the element names and values or the physical properties of any particle or body:{ position, velocity, acceleration, jerk etc...} and similarly the modeling information of any 3D contruct:{ translation, rotation, scale etc...}.
OK, what did I find?
I'll start by quoting the Help Doc.:
A Gfa_Types item contains the properties that allow you to get information about a user-defined type like its name, elements, and their type.
and...
Offset(n) Returns the offset from the start of element n in bytes
I used this information to view all the UDT element names and values automatically, meaning, I did not have to manually prepare a print or trace statement.
As you may or may not know, GFA already provides this capability for the Debug window, which is evident when you use:
Trace <some UDT typed variable>
The element names and values will be shown in the Debug window.
But, how - "in code" - do you 'display' / 'get access to' a set of UDT typed variable element names and values automatically?
This code did the trick!
This is the main procedure that calls the one above...
Proc P_Get_UDT_Element_Value(addr%, type%, type$, offset%)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Well, this is a big leap forward in being able to get maximum information with
' minimum effort. By using the offset value kindly provided by the Gfa_Types
' feature, I can now view the value of a UDT element effortlessly !!! using this
' here procedure.
'
Dim s$, n#
Select type%
Case basDouble
Print DblPeek(addr% + offset%)
EndSelect
Dim udt As Gfa_Type, i%, offset2%
For Each udt In Gfa_Types
If udt.Name(0) == type$
For i = 1 To udt.Count
type% = udt.Type(i)
offset2% = udt.OffSet(i)
Select type%
Case basSingle
n = SngPeek(addr% + offset% + offset2%)
If n >= 0 s$ = "+" Else s$ = ""
Print " "; udt.Name(i); ":"; Format(n, s$ & "0.#######0 "),
Case basDouble
n = DblPeek(addr% + offset% + offset2%)
If n >= 0 s$ = "+" Else s$ = ""
Print " "; udt.Name(i); ":"; Format(n, s$ & "0.###############0 "),
EndSelect
Next i
Print
EndIf
Next
EndProc
This is the main procedure that calls the one above...
Proc Prt_Phy_Obj_Dat(ByRef o As T_Phy_Obj)
Static th! = 20
Static x! = 20
°Text x, 1 * th, "EDIT PHYSICAL OBJECT"
°Text x, 2 * th, "o.Ät = " & F_n(o.Ät)
°D_Text x, 3, "o.s.x = ", (o.s.x)
°D_Text x, 4, " .y = ", (o.s.y)
°D_Text x, 5, " .z = ", (o.s.z)
°D_Text x, 6, "o.v.x = ", (o.v.x)
°D_Text x, 7, " .y = ", (o.v.y)
°D_Text x, 8, " .z = ", (o.v.z)
°D_Text x, 9, "o.a.x = ", (o.a.x)
°D_Text x, 10, " .y = ", (o.a.y)
°D_Text x, 11, " .z = ", (o.a.z)
°D_Text x, 12, "o.j.x = ", (o.j.x)
°D_Text x, 13, " .y = ", (o.j.y)
°D_Text x, 14, " .z = ", (o.j.z)
Print AT(0, 0)
Dim udt As Gfa_Type, i%
For Each udt In Gfa_Types
Try
If udt.Name(0) == "T_Phy_Obj"
Print "Type "; udt.Name(0)
For i = 1 To udt.Count
Print " "; udt.Name(i) & " ";
If udt.IsArray(i) Then
Print "("; udt.LBound(i); ".."; udt.UBound(i); ")";
EndIf
Print "As "; udt.TypeName(i); " ",
P_Get_UDT_Element_Value(V:o, udt.Type(i), udt.TypeName(i), udt.OffSet(i))
Next i
Print "EndType"
EndIf
Catch
Print "Error in Print_type "; Err; Err$
EndCatch
Next
EndProc
This is the print out to the form...
As you can see, there are many elements composing this UDT I called: "T_Phy_Obj", I was looking for a way to avoid having to prepare a print statement for each element value. This can obviously be adapted to any UDT. I am also very happy to be able to use Greek symbols as used in Maths and Physics text books.