Main Menu

ReDim in Function

Started by slayer93, June 28, 2008, 08:14:27 PM

Previous topic - Next topic

slayer93

Hi, my first post here. I usually use DarkBasic Pro but decided to try PlayBasic for the Heroes Competition(hopefully I get to enter).

Anyway the problem I am having is if I ReDim an array inside a function it is only local to that function, probably intended but what should I do to have a re-dimensioned array outside my function but redim it within my function (if possible). I want to redim in my function so everytime I call the function it can move up by one.

Here is some test code that's similar to what in my project so far.

PlayBASIC Code: [Select]
;
; Types

Type tTest
field1 as integer
EndType

Dim Test(0) as tTest

RedimArray()

; Main Loop
Do

text 0,20, "Outside Function: "+Str$(GetArrayElements(Test(),1))

;Sync
Sync
Loop

Function RedimArray()

i=GetArrayElements(Test(),1)
Redim Test(i+1)
text 0,0, "In Function: "+Str$(GetArrayElements(Test(),1))

EndFunction



I'm sure its something incredibly simple but maybe I am to use to DBP having all its arrays global.
Thanks for any help. Playbasic has been great so far. :)

kevin

#1
 If you DIM any array inside a function/psub it's local to that scope.  However, when a global array has been previously declared (before the local declaration), then the REDIM will act upon the global version rather than the local.



PlayBASIC Code: [Select]
  dim Test(0)
RedimArray()


; Main Loop
Do

text 0,20, "Outside Function: "+Str$(GetArrayElements(Test(),1))

;Sync
Sync
Loop

Function RedimArray()

i=GetArrayElements(Test(),1)
Redim Test(i+1)
text 0,0, "In Function: "+Str$(GetArrayElements(Test(),1))

EndFunction



slayer93

But Typed Arrays can't be redimmed in a function even if the array is global. Is that a bug or am I just doing it wrong?

kevin


What version are you using ?

slayer93

I have the 1.63 Learning Edition.

kevin

    There's something odd occurring with parser.   Will have a look at that a bit later.   In the mean time, what are you actually trying to do ?   Create a type stack ?



slayer93

QuoteIn the mean time, what are you actually trying to do ?   Create a type stack ?

I was attempting to create a dynamic button system. I create a button and I add another element to the typed array and I delete a button it is removed from the array.

Thanks for the help so far :)

kevin

#7
PlayBASIC Code: [Select]
;
; Types

Type tTest
X as integer
Y as integer
EndType

Dim Stack(0)
Dim Me as tTest pointer

Setfps 60
; Main Loop
Do
cls 0

For lp=1 to GetArrayElements(Stack(),1)
Me=Stack(lp)
circlec me.x,me.y, 20,true,rgb(0,0,255)
text me.x,me.y,str$(lp)
next


if Spacekey()
Me = new tTest
Me.x=rnd(800)
Me.y=rnd(600)
AddToStack(me)
FlushKeys
endif

;Sync
Sync
Loop




Function AddToStack(Me as pointer)
Size=GetArrayElements(stack(),1)+1
Redim Stack(Size)
Stack(Size)=Int(Me) ; recast the pointer to a integer and store in within the integer array
EndFunction



kevin

#8
  Or you could the GetFreeCell()  function to poll the array and return a free index.  It resizes the buffer as it needs.

PlayBASIC Code: [Select]
; Types
Type tTest
X as integer
Y as integer
EndType

Dim Objects(0) as ttest

Setfps 60

; Main Loop
Do

cls 0

For lp=1 to GetArrayElements(Objects(),1)
if Objects(lp)
circlec Objects(lp).x,Objects(lp).y, 20,true,rgb(0,0,255)
text Objects(lp).x,Objects(lp).y,str$(lp)
endif
next

if Spacekey()
index=AddToStack()
Objects(index) = new tTest
Objects(index).x=rnd(800)
Objects(Index).y=rnd(600)
FlushKeys
endif

;Sync
Sync
Loop




Function AddToStack()
index=GetFreeCell(Objects())
EndFunction Index




slayer93

Thanks the GetFreeCell() worked.

kevin

#10
   If the order doesn't matter, you could also use a LInked List

PlayBASIC Code: [Select]
; Types
Type tTest
X as integer
Y as integer
Count as integer
EndType

Dim Objects as ttest list

Setfps 60

; Main Loop
Do

cls 0

For each Objects()
circlec Objects.x,Objects.y, 20,true,rgb(0,0,255)
text Objects.x,Objects.y,str$(Objects.count)
next

if Spacekey()
Objects = new tTest
Objects.x=rnd(800)
Objects.y=rnd(600)
Objects.Count=Count
inc Count
FlushKeys
endif

;Sync
Sync
Loop



kevin

#11
     One last post,  this one addresses the original question.   The problem above occurs when referring to a typed array handle in it's short hand form.   It seems that in order to use the handle with the array commands locally, the parser requires the full declaration so it can decipher between the global edition or if you're creating a new array handle.  

  Ie.
     Size=GetArrayElements(MyArray() , 1)   ; <-  Within a local scope,   myarray() will be created if no global MyArray() (integer version) is present.   It never used to do this, so something has changed the order precedence in regards to array handles.

  So we can fix the original post by doing this.

PlayBASIC Code: [Select]
;
; Types

Type tTest
x as integer
y as integer
EndType

Dim Test(0) as tTest

RedimArray()

; Main Loop
Do

For lp=0 to GetArrayElements(Test(),1)
circlec Test(lp).x,Test(lp).y, 20,true,rgb(0,0,255)
text Test(lp).x,Test(lp).y,str$(lp)
Next

if Spacekey()
i=RedimArray()
Test(i).x=rnd(800)
Test(i).y=rnd(600)
EndIF

;Sync
Sync
Loop


Function RedimArray()
i=GetArrayElements(Test().ttest,1)+1
Redim Test(i) as ttest
EndFunction i






slayer93

Thanks for the help Kevin I'll remember that for the future.