Page 1 of 2

[Implemented] Resize Arrays in Structures

Posted: Sat Apr 10, 2004 8:37 pm
by Shannara
Reference (Near Bottom): viewtopic.php?t=10304&highlight=resize+structure

I would like to be able to resize (Dim) arrays that are in structures.

(Implemented as dynamic Array, where ReDim can be called)

Posted: Sat Apr 10, 2004 8:43 pm
by blueznl
you cannot (but why would you?)

Posted: Sat Apr 10, 2004 9:21 pm
by Kale
I thought i answered this once... you can't.

Posted: Sat Apr 10, 2004 9:33 pm
by Shannara
I know you answered this one, thus the whole reason it is in the "Feature Requests and Wishlists" forum......

And why? For example, I have a map data that holds tile information. I hate having artifical (not needed) limits on some things. This map data structure holds optional animated tiles (1 to many frames). Instead of putting a hard limit on frames, I want to be able to redim the frames array to hold how ever many frames a sprite will hold.

It would be a pain to have tons and tons of seperate arrays to keep track of, for map data, when it could be one array on the map data structure.

Posted: Sat Apr 10, 2004 10:20 pm
by freak
I'm sorry, but a structure has a fixed size... in every language.

Timo

Posted: Sat Apr 10, 2004 10:32 pm
by Shannara
lol :) In every language except VB.

Posted: Sat Apr 10, 2004 10:45 pm
by freak
ok then.... in every *real* language :P

Actually i don't know *every* language, but i don't quite see the point of
dynamically sized structures... how would you cereate an array of such structures?

Timo

Posted: Sat Apr 10, 2004 10:58 pm
by dell_jockey
Shannara, for your intended usage, perhaps you might want to check out linked lists... Perhaps all your structure needs is a pointer to a linked list.

Posted: Sat Apr 10, 2004 11:04 pm
by Shannara
Heh, well, if VB isnt a language, so isnt any of the .NET "languages" :) And I totally agree there. Anyways...

I was thinking of linklists, and have pointer to the link lists in the structure but consider the following:

Code: Select all

Structure MapData
   PointerToTileLinkList.ptr
EndStructure

Dim Array.MapData(Level,Width,Height)
I would need to have an linklist of every single tile on the map. The maps can be as small as 900 tiles to as high as ... well, there is currently no limit. There's no way in the world that I am going to type out over 10,000 linklists... the coding would be a nightmare.

Posted: Sun Apr 11, 2004 1:10 pm
by blueznl
why do it this way?

how do you think other programs use variable length information?

using pointers and allocated memory

Posted: Sun Apr 11, 2004 1:17 pm
by tinman
You could have a pointer in your structure to the array:

Code: Select all

Structure MapData
    a.w
EndStructure

Structure foo
    *array.MapData
EndStructure

Dim real_array.MapData(10)

DefType.foo var
var\array = @real_array(0)
Now you can use the pointer in the structure to access the array. I can't remember if PB has a "ReDim" or "Dim Keep" type of operation, but that would allow you to resize it.

Alternatively you could allocate the memory yourself.

And try searching the forums for "pointers to arrays". It's been asked about lots of times. My favourite solution is to use the [0] size arrays that everyone *loves* ;)

Posted: Sun Apr 11, 2004 1:51 pm
by blueznl
here's a pointy :-) example:

Code: Select all

Structure mapdata
  tilenumber.l
  p_tilepointer.l ; can't use *tilepointer here?!?
EndStructure

Dim map.mapdata(10,10)

Structure tiledata
  number.l
  length.l
EndStructure

*tile0.tiledata = AllocateMemory(1,200*1024,0)

tile_n = 100 ; let's say a hundred tiles

*tile.tiledata = *tile0
For tile = 0 To tile_n
  *tile\number = tile
  *tile\length = Random(1024) ; just arbitrary, i dunno what you wanna store per tile
  *tile = *tile + *tile\length
Next tile

; ok got 10 tiles now with variable length
; now fill in the mapdata, let's say every cell has a random tile

For x = 0 To 9
  For y = 0 To 9
    map(x,y)\tilenumber = Random(tile_n-1)
  Next y
Next x
    
; i assume maps could change, as well could tiles
; so just before running the real stuff, we'd better map each mapcell to a tile
; for this it's easy if we have a function

Procedure findtile(nr)
  Protected *tile.tiledata, n, *p
  Global *tile0.tiledata, tile_n.l
  ;
  ; no error checking in here :-)
  ;
  n = 0
  *p = 0
  *tile.tiledata = *tile0
  While *p = 0
    If *tile\number <> nr
      *tile = *tile + *tile\length
    Else
      *p = *tile
    EndIf
  Wend
  ProcedureReturn *p
EndProcedure

; ok let's map it

For x = 0 To 9
  For y = 0 To 9
    map(x,y)\p_tilepointer = findtile(map(x,y)\tilenumber)
    ; map(x,y)\*tilepointer = findtile(map(x,y)\tilenumber) ; fred, please fix this!
  Next y
Next x

Posted: Sun Apr 11, 2004 5:20 pm
by dell_jockey
If you use tiles that are assembled into a map, have you thought of a matrix (2-dimensional array) containing pointers to the tiles?

Assuming you're programming a game or simulation, you'll probably have a 'visibility' set somewhere. This visibility defines the radius around your current position. So, if you're the middle of a map, that is represented by a matrix, that matrix only need to be as large as to be able accomodate your visibility radius in all directions. You'll always be in the middle of the scene, hence matrix. If you move, you merely have to redefine the tiles (or the pointers to the tiles) of your map matrix.

Posted: Mon Apr 12, 2004 9:54 am
by blueznl
hey shanarra, is the problem solved now?

Posted: Tue Apr 13, 2004 7:56 am
by Shannara
Not yet, I havent had time to look at the sources on this thread yet :) Been having fun with the kids the last few days :) Im currently downloading 3.90 right now, and I'll check right back with you guys as soon as I have time to code :)

btw: thanks for the code samples guys :) I'm searching..