UnderwareDESIGN

PlayBASIC => Beginners => Topic started by: lime_spring on July 23, 2016, 07:24:33 PM

Title: Nested types / typed arrays error
Post by: lime_spring on July 23, 2016, 07:24:33 PM
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
Title: Re: Nested types / typed arrays error
Post by: kevin on July 24, 2016, 10:37:51 AM
  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.. 

[pbcode]

   ; 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
   
[/pbcode]


Title: Re: Nested types / typed arrays error
Post by: lime_spring on July 24, 2016, 08:33:42 PM
I see, so how do you destroy the vectors when you're done?
Title: Re: Nested types / typed arrays error
Post by: kevin on July 24, 2016, 11:03:26 PM

  by   Freeing them
Title: Re: Nested types / typed arrays error
Post by: kevin on July 26, 2016, 10:52:46 AM
 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


[pbcode]

 ; 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




[/pbcode]



    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.


[pbcode]



 ; 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
 
[/pbcode]


Using Handles:

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


[pbcode]


  ; 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


[/pbcode]