View Full Version : Static UDT not possible?
ReneMiner
26-03-2014, 09:02
Seems I ran into some limit again. Is not allowed to have static udt as subset of another udt?
only primitive variables (Long, String, Byte...) allowed?
' thinBasic 1.9.12.0
Uses "console"
Type t_RGB
R As Byte
G As Byte
B As Byte
End Type
Type t_myType
Static Backcolor As t_RGB ' not possible?
myCol As t_RGB ' <<< comment this line in second run to get a crash
End Type
Sub assign_shared()
Local a As t_myType
a.Backcolor.R = 64
a.Backcolor.G = 128
a.Backcolor.B = 192
End Sub
assign_shared
Dim Test As t_myType
PrintL "Test.R:" + Test.Backcolor.R
PrintL "Test.G:" + Test.Backcolor.G
PrintL "Test.B:" + Test.Backcolor.B
PrintL Repeat$(50,"-") + $CRLF
PrintL "Key to end"
WaitKey
Let run twice:
1. as is = wrong output
2.comment "myCol as t_RGB" in Type-definition to crash
ReneMiner
27-03-2014, 10:21
If not possible to use udt I simply invented a new primitive variable-type that I can use to bind anything anywhere.
- looks familiar probably though I used similar approach in a few examples already, but now I use a "Double-DWord" i.e. Quad to contain some handle to DATA and TYPE in ONE variable but uses a "Union-in-mind"-approach so my Alias Quad As Storage does not have any type-functions and can be attached to static members of UDT. I tested already - and works - but the example below does not contain any statics since I simplified a little using ByRef for better readability instead of a pointer - so this example is not working on UDT-subsets, but the approach itself does.
To have it work it needs currently constant user-made Stringpointers to the attached types-name.
To read out a string just having its pointer available is pretty simple. thinBasic offers great method Memory_Get:
String s = Memory_Get(sPtr, Peek(DWord, sPtr-4))
because
a) If have more than once to store the same strings (that never change) is mostly less memory needed when just storing the StrPtr of it.
b) a StrPtr is always 4 bytes in our world - no matter what string, so this allows something like:
' thinBasic 1.9.12.0
Uses "console"
' it's all about storing different subtypes to variables
Alias DWord As Heap
Alias DWord As ConstStrPtr
' it's in fact kind of a union
' but Union won't work with static subsets
Alias Quad As Storage ' = 2 * SizeOf(dword)
Type t_Storage
pData As HEAP
pType As ConstStrPtr
End Type
' union get's applied in untyped-functions
Function Storage_Create( ByRef hndl As Storage, _
ByVal datatype As ConstStrPtr, _
Optional ByVal sData As String _
) As Storage
' -- treat the Storage-hndl as t_Storage now:
Local Me As t_Storage At VarPtr(hndl)
' -- kill possible old data
If HEAP_Size(Me.pData) Then HEAP_Free(Me.pData)
' create data-pattern like datatype to obtain size
Local data Like Memory_Get(datatype, Peek(DWord, datatype-4))
If StrPtrLen(StrPtr(sData)) < SizeOf(data) Then
' fill optional passed data with zeros to fit the pattern
sData += Repeat$( SizeOf(data) - StrPtrLen(StrPtr(sData)), MKBYT$(0) )
EndIf
' store data to Heap and save heap-pointer + datatype to Me
Me.pData = HEAP_AllocByStr( sData )
Me.pType = datatype
' return hndl from it's position
Function = Peek( Storage, VarPtr(Me) )
End Function
Function Storage_Destroy(ByRef hndl As Storage) As Boolean
' -- treat the Storage-hndl as t_Storage now:
Local Me As t_Storage At VarPtr(hndl)
If HEAP_Size(Me.pData) Then
HEAP_Free(Me.pData)
Function = TRUE
EndIf
Me.pData = 0
Me.pType = 0
End Function
Function Storage_Delegate(ByRef hndl As Storage, ByVal sFunction As String) As Boolean
' pass a function-name to call at stored data
' -- treat the Storage-hndl as t_Storage now:
Local Me As t_Storage At VarPtr(hndl)
' -- treat the stored data like the stored type now:
Local data Like Memory_Get(Me.pType, Peek(DWord, Me.pType-4)) At Me.pData
' currently no other way nor parameters possible to call the function at data
Select Case Ucase$(sFunction)
Case "GETDATA"
Function = data.GetData
End Select
End Function
' --------------------------------------------------------------
' some different types to store
Type t_RGB
R As Byte
G As Byte
B As Byte
GetData As Function
End Type
$t_RGB = "t_RGB" : %t_RGB = StrPtr($t_RGB) As ConstStrPtr
Function t_RGB.GetData() As Boolean
If VarPtr(Me) Then
PrintL "R:" + Me.R
PrintL "G:" + Me.G
PrintL "B:" + Me.B
Function = TRUE
EndIf
End Function
Type t_Vec3d
X As Double
Y As Double
Z As Double
GetData As Function
End Type
$t_Vec3d = "t_Vec3d" : %t_vec3d = StrPtr($t_vec3d) As ConstStrPtr
Function t_Vec3d.getData() As Boolean
If VarPtr(Me) Then
PrintL "X:" + Me.X
PrintL "Y:" + Me.Y
PrintL "Z:" + Me.Z
Function = TRUE
EndIf
End Function
' --------------------------------------------------------------
Dim myArray(3) As Storage ' create simple quad-array to hold all data
Storage_Create( myArray(1), %t_RGB, MKBYT$(11,12,13) )
Storage_Create( myArray(2), %t_Vec3d, MKD$(1.11, 1.22, 1.33) )
Storage_Delegate(myArray(1), "GetData")
PrintL
Storage_Delegate(myArray(2), "GetData")
PrintL $CRLF + Repeat$(40,"-") + $CRLF + "key to end"
WaitKey
Good morning!
ReneMiner
27-03-2014, 13:08
seems to be some monologue...reminds me of the Heap_-unit once. Anyway, before trashing your minds with any more page-filling examples
- the result/the catch is currently that I have no way to call a function of an attached type in the reverse way as inheritage does:
if the function is not part of the "parenting type" it should get called from the attached type
- so that "delegate"-stuff should be done somehow like the way an extended type already works.
Since Heap is part of Core-engine already there's nothing against a variable-type - somewhat similar to string on user-side, concerning dynamics -
which could hold these 2 Dwords and have a few basic functionalities - for the interested audience I attached some example of these.
Petr Schreiber
27-03-2014, 19:59
I can confirm the static member crash :(
The HEAP way is really nice, I think it could serve as base for implementation of dynamic arrays in types - would be definitely useful to use them "natively".
Petr
ReneMiner
29-03-2014, 08:53
...it could serve as base for implementation of dynamic arrays in types...
yes it could be used to attach dynamic arrays too - but that's not the main-intention for me trying - it's not limited to sub-arrays of the same type.
I can use this to attach any variable of any available datatype (also arrays of these) to anything that has the ability to store a quad-variable.
That's why this ended up in this thread: even static members of udt can get a whole christmas-tree branched to it if desired....
Each "parent" of the same type can have a different "child-type" attached - (non-static of course then) - but all is accessable as long as we know the parent.
That's what currently already doable having the new LIKE-functionalities.
see also example here (http://www.thinbasic.com/community/showthread.php?12201-TypeOf-ideas&p=90889#post90889)
-imagine the circles and boxes being different GUI-controls or meshes all having different amount of bones, submeshes, vertex-types etc. that could be stored as members of the same parent-array, having a few type-specific and a few common functions such as ".Draw()"
There would be constrictions to store arrays of dynamic strings - but would be possible in the end too. Therefor one could attach a dictionary in Case ...() as String and put the keyptrs in an array to storage - or just some array of heap-pointers and store strings at and retrieve strings from heap using Heap_AllocByStr/Heap_Get.
If thinBasic would understand a function called at this special quad-type ("Storage") has to be called at a variable of the attached subtype and would bequeath the passed parameters to it, we could not just store anything here, but also use all functions of the attached subtype instantly - since "storage" has no own functions anyway -
Currently I'm not sure if it would be better to implement a TypeID-function which stores types-name on request and returns a pointer - or just to have use user-made ConstStrPtr's as above - or if probably a function could return the pointer to internal somewhere stored type-names.
Finally a type would decide which function gets called. Can you interpret the direction that goes?
Like-keyword, heap-memory + heap-functions, type-functions and absolute variables already offer anything else needed to go this way - now is just a small piece of bridge needed to close the gap and to have a magnificent highway
.:egg26:
ReneMiner
30-03-2014, 09:08
idea:
(see post above)
ability to call functions on "raw data" directly like this:
Syntax:
CallAt pData [As t_myType| Like "t_myType"], FunctionName ([PARAMETERS]) [To Result]
CallAt: call a type-function but data-position passed as pointer and not as variable-name
pData: pointer to current element ( =VarPtr(myVar) )
FunctionName: the name of a function as defined inside type-definition
Parameters: parameters as t_myType.FunctionName would expect
I think this could solve the current "delegate-inflexibility" and allow to call type-functions on anything that's stored somewhere in memory