News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Nested types / typed arrays error

Started by lime_spring, July 23, 2016, 07:24:33 PM

Previous topic - Next topic

lime_spring

Very simple:

Map.tilesets(1).image.width = 10

Gives error "Expecting equals"

I tried using Lists, but got even stranger errors

After looking at another post, I tried this method:


dim ts as tileset pointer
ts = Map.tilesets(1)
ts.image.width = 10


but it just crashes without an error

kevin

#1
  The parser doesn't support it,  for a list of what is supported see HELP under ABOUT->TYPES.

  None the less,  You can create arrays  of types a bunch of ways,  here's just one.. 

PlayBASIC Code: [Select]
   ; Delcare some type we'll use as nested pointers
Type tVector
x#,y#,z#
EndType

Type tStuff
; declare INTEGER STATIC ARRAY to hold nested fields
Vector_Array(10)
EndType


; delcare ME as type stuff
Dim Me as tStuff

; alloc a tSTUFF structure and place it in ME
Me = New tStuff


; declare typed pointer for
Dim ThisVector as tVector Pointer

; allocate and store the RAW pointers in the aray fields
For lp=0 to 9
; Allocate a structure somewhere else in memory
ThisVector = New tVector

; fill it with some stuff
ThisVector.X= 1000 +lp
ThisVector.Y= 2000 +lp
ThisVector.Z= 3000 +lp

; Store this pointer in our Vector_Array() for later use
Me.Vector_Array(lp) = int(ThisVector)

next



For lp=0 to 9
; Get this pointer
Thisvector=Me.Vector_Array(lp)

; check it's assigned a value
If int(Thisvector)

s$ =str$(int(ThisVector))+".tVector pointer = "
s$+=" X="+str$(ThisVector.x)+","
s$+=" Y="+str$(ThisVector.y)+","
s$+=" Z="+str$(ThisVector.z)

print s$
endif
next


Sync
waitkey






lime_spring

I see, so how do you destroy the vectors when you're done?

kevin


kevin

#4
 Creating Nested Structures:
   
    Here's another version, in this one we're creating a static array (an array that size can't be changed at runtime)  this time we define an Integer array field and then write directly into it via UDT pointers.   Which just means we need a bit of logic to size the integer field to something bit enough to house what we want, and a bit of logic to compute pointers to each virtual array index


PlayBASIC Code: [Select]
  ; Declare some type we'll use to nest 
Type tVector
x#,y#,z#
EndType

Constant VectorArraySize = 10
Constant VectorArraySizeInBytes = ((VectorArraySize * SizeOf(tVector) )/4) +1


Type tStuff
; declare INTEGER STATIC ARRAY which is used as a buffer to hold
; our array of vector or whatever.
Vector_Array(VectorArraySizeInBytes)
EndType


; delcare ME as type stuff
Dim Me as tStuff

; alloc a tSTUFF structure and place it in ME
Me = New tStuff


; declare typed pointer, so we can look at structures in memory
Dim ThisVector as tVector Pointer

; Init the data inside the array as if it's out array of types
For lp=0 to VectorArraySize-1

; Compute Pointer to this structure within the
ThisVector = Me.Vector_Array + (Sizeof(tVector) * lp)

; fill it with some stuff
ThisVector.X= 1000 +lp
ThisVector.Y= 2000 +lp
ThisVector.Z= 3000 +lp

next



For lp=0 to VectorArraySize-1
; Get this pointer to this
ThisVector = Me.Vector_Array + (Sizeof(tVector) * lp)

; check it's assigned a value
If int(Thisvector)
s$ =str$(int(ThisVector))+".tVector pointer = "
s$+=" X="+str$(ThisVector.x)+","
s$+=" Y="+str$(ThisVector.y)+","
s$+=" Z="+str$(ThisVector.z)

print s$
endif
next


Sync
waitkey









    You could also stack them together  like this into an array type to avoid having to compute some constants.   You could also store the number of items and stuff in the structure.  Then  write some wrappers to hide it all away.


PlayBASIC Code: [Select]
  ; Declare some type we'll use to nest 
Type tVector
x#,y#,z#
EndType


; Here you could unroll structure inside of the another structure
Type tVectorArray
V0 as tVector
V1 as tVector
V2 as tVector
V3 as tVector
V4 as tVector

V5 as tVector
V6 as tVector
V7 as tVector
V8 as tVector
V9 as tVector
EndType


Constant VectorArraySize = 10


Type tStuff
; declare unrolled subtype, which we use as an array
Vector_Array as tVectorArray
EndType


; delcare ME as type stuff
Dim Me as tStuff

; alloc a tSTUFF structure and place it in ME
Me = New tStuff


; declare typed pointer, so we can look at structures in memory
Dim ThisVector as tVector Pointer

; Init the data inside the array as if it's out array of types
For lp=0 to VectorArraySize-1

; Compute Pointer to this structure within the
ThisVector = Me.Vector_Array + (Sizeof(tVector) * lp)

; fill it with some stuff
ThisVector.X= 1000 +lp
ThisVector.Y= 2000 +lp
ThisVector.Z= 3000 +lp

next



For lp=0 to VectorArraySize-1
; Get this pointer to this
ThisVector = Me.Vector_Array + (Sizeof(tVector) * lp)

; check it's assigned a value
If int(Thisvector)
s$ =str$(int(ThisVector))+".tVector pointer = "
s$+=" X="+str$(ThisVector.x)+","
s$+=" Y="+str$(ThisVector.y)+","
s$+=" Z="+str$(ThisVector.z)
print s$
endif
next


Sync
waitkey





Using Handles:

       Another method (and the one I generally use) to create infinitely nested structures is by using handles


PlayBASIC Code: [Select]
  ; Declare some type we'll use to nest 
Type tVector
x#,y#,z#
EndType


Type tStuff
; declare unrolled subtype, which we use as an array
VectorARRAY_HANDLE
EndType


; delcare ME as type stuff
Dim Me as tStuff list


;
For OutterLoop =0 to rndrange(1,5)

; alloc a tSTUFF structure and insert it at the head of tge ME list
Me = New tStuff

; Create an array and return it's handle and remeber in it in this field
Me.VectorArray_Handle =CreateVectorArray()


; To Access the array we need a STUB/POINTER array so we delcare one in the same
; scope
makeArray V().tVector


; put the handle of our vector array in here, so now we can access that array through V()
V() = Me.VectorArray_Handle

; Randomly Add Stuff to it
For lp =0 to rndrange(5,10)

; Request an index from a typed 1D array, if there none empty
; the array is expanded for us
Index=GetFreeCell(V())

; fill it with some stuff
V(index).X = SomeValue +lp
V(index).Y = SomeValue +lp+1
V(index).Z = SomeValue +lp+2

SomeValue+=100

next



Next



// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------


OutterLoop=0

For Each Me()

print "-[Object #"+Str$(OutterLoop)+"]----------------------------------------------------------"

; Place the objects list of sub types in handle in V()
; now V() acts like that array
V() = Me.VectorArray_Handle

; run through and see what's in this array
For lp=0 to GetArrayElements(V())

; check it's there's a type at this position within the array
If V(lp)
s$ ="#"+str$(lp)+".tVector = "
s$+=" X="+str$(V(lp).x)+","
s$+=" Y="+str$(V(lp).y)+","
s$+=" Z="+str$(V(lp).z)
print s$
endif
next

OutterLoop++

next




Sync
waitkey




Function CreateVectorArray(Size=0)
Dim VectorArray(Size) as tVector
EndFunction VectorArray() as tVector