PDA

View Full Version : "Dynamic Arrays" in my UDT...



Oscar Ugolini
17-09-2012, 23:31
I'm looking for a method to include in my UDT also a dynamic array, using a pointer instead a real array,
but i found some difficulties.
How could i write this???

example:

type My_UDT
...
a as Long
points() as single ---> i want this but not permitted
points as dword ---> a pointer to some array, single array or multidimensional array, permitted
...
end type

how can i use this to store a single array or multidimensional array in my "variable as My_UDT"?

thanks all

Petr Schreiber
18-09-2012, 08:40
Hi Oscar,

you could use ThinBASIC memory allocation routines (Heap_Alloc, Heap_Free, ...) or take advantage of fact UDTs can contain dynamic string (ThinBASIC speciality). If you use STRING variable in UDT as memory buffer, you can do neat tricks including the redimensioning of the array at any time. And it is still garbage collected, so you don't have to worry about freeing memory.

What I show below is how I handle this task - it is not necessarily the best way, but it is quite easily maintainable. I tend to wrap UDTs in object oriented way, that is, beside the UDT definition I add more handling routines, which help with usage.

The example uses Polygon2D (which is equivalent of your MyUDT) and Point2D. The Polygon2D structure has dynamic array of Point2Ds.


Uses "Console"

' -- Main program
Function TBMain()
Dim myVar As Polygon2D
myVar = MyUDT_Create()

PrintL "numPoints = " + myVar.numPoints
PrintL "Redimensioning to 3 elements..."
MyUDT_PointsRedim(myVar, 3)
PrintL "numPoints = " + myVar.numPoints

MyUDT_PointsSetIndex(myVar, 1, 1, 2)
MyUDT_PointsSetIndex(myVar, 2, 3, 4)
MyUDT_PointsSetIndex(myVar, 3, 5, 6)

/* Alternative way:
Dim tempArray(myVar.numPoints) As Point2D At MyUDT_PointsGetPTR(myVar)
tempArray(1).x = 1
tempArray(1).y = 2

tempArray(2).x = 3
tempArray(2).y = 4

tempArray(3).x = 5
tempArray(3).y = 6
*/

Single x, y

PrintL "Read back index 1:"
MyUDT_PointsGetIndex(myVar, 1, x , y)
PrintL x, y

PrintL "Read back index 2:"
MyUDT_PointsGetIndex(myVar, 2, x , y)
PrintL x, y

PrintL "Read back index 3:"
MyUDT_PointsGetIndex(myVar, 3, x , y)
PrintL x, y

WaitKey
End Function

' -- Point2D
' >>
Type Point2D
x As Single
y As Single
End Type

' -- Creates new Point2D
Function Point2D_Create(x As Single, y As Single) As String

' -- Create temporary variable
Dim var As Point2D

' -- Assign defaults
var.x = x
var.y = y

' -- Return memory representation
Return Peek$(VarPtr(var), SizeOf(Point2D))

End Function
' <<

' -- Polygon2D
' >>
Type Polygon2D
numPoints As Long
sPoints As String ' -- String buffer used to contain array memory
End Type

' -- Creates new Polygon2D
Function MyUDT_Create(Optional numPoints As Long = 0) As String

' -- Create temporary variable
Dim var As Polygon2D

' -- Assign defaults
var.numPoints = 0
var.sPoints = ""

' -- Return memory footprint
Return Peek$(VarPtr(Var), SizeOf(Polygon2D))

End Function

' -- Returns pointer to points "dynamic" array
Function MyUDT_PointsGetPTR(ByRef var As Polygon2D) As DWord

Return StrPtr(var.sPoints)

End Function

' -- Redims the points array
Function MyUDT_PointsRedim(ByRef var As Polygon2D, numElements As Long, Optional preserveValues As Long = FALSE) As DWord

Long deltaElements = var.numPoints - numElements

' -- Like REDIM PRESERVE
If preserveValues Then
If deltaElements < 0 Then
var.sPoints = LEFT$(var.sPoints, SizeOf(Polygon2D) * numElements)
ElseIf deltaElements > 0 Then
var.sPoints = var.sPoints + Repeat$(deltaElements, Point2D_Create(0,0))
End If

' -- Like REDIM
Else

var.sPoints = Repeat$(numElements, Point2D_Create(0,0))
End If

var.numPoints = numElements

End Function

' -- Returns data from given points index
Function MyUDT_PointsGetIndex(ByRef var As Polygon2D, i As Long, ByRef x As Single, ByRef y As Single) As String

Dim tempArray(var.numPoints) As Point2D At MyUDT_PointsGetPTR(var)

x = tempArray(i).x
y = tempArray(i).y

End Function

' -- Sets data to given points index
Function MyUDT_PointsSetIndex(ByRef var As Polygon2D, i As Long, x As Single, y As Single) As String

Dim tempArray(var.numPoints) As Point2D At MyUDT_PointsGetPTR(var)

tempArray(i).x = x
tempArray(i).y = y

End Function
' <<



Petr

Oscar Ugolini
18-09-2012, 12:56
thanks Petr,
you're always ready to reply!! that's incredible... :)

bye
Oscar

Oscar Ugolini
18-09-2012, 21:04
... and thanks also to Eros!

i love ThinBasic :)
can run this line ... wow :occasion:

....
Dim tempArray(var.numPoints) As Point2D At MyUDT_PointsGetPTR(var)
....

i'm working on your example Petr :)

bye
Oscar

Petr Schreiber
18-09-2012, 21:12
I am happy it works for you! :occasion:


Petr