News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Array Handles (Advanced)

Started by kevin, January 20, 2015, 05:56:35 PM

Previous topic - Next topic

kevin

  Array Handles (Advanced)

     This is a slightly more advanced example showing how to return array handles  as normal every day integers, than pass those integer handle into other functions.  The functions you pass them into, then access the data via a stub array.   So inside the function it's like you passed the array in manually, so if you modify the array, those changes aren't local, they're being made to the array that actual owns the data.    Most operations will work, like resizing, even dimensioning, but If you undim the array, you'll destroy the array handle, which will make the parent array invalid..  Doing so will give undefined behavior.

PlayBASIC Code: [Select]
   ; check if we're compiling in a debug mode ?
#if pbdebugmode=0
; if not, abort compile with a message
#abort "COMPILE ABORT: Compile & Run in Debug mode (f7) to see console output"
#endif



Dim Stuff1D(100)
Dim Stuff2D(50,50)

; fill this 2d array with
FillArray(GetIntegerarrayhandle(Stuff1d()),1000)

ShowArray(GetIntegerarrayhandle(Stuff1d()))

FillArray(GetIntegerarrayhandle(Stuff2d()),1000)
ShowArray(GetIntegerarrayhandle(Stuff2d()))


sync
waitkey



Function ShowArray(ArrayHandle)

if ArrayHandle
MakeArray LocalArray()
LocalArray()=ArrayHandle


#print "Array Handle:"+Str$(ArrayHandle)

; -----------------------------------------------------------------------
; here you might like to check is the array exists (was a valid handle)
; it's number of dimensions, size
; -----------------------------------------------------------------------
if GetArrayStatus(LocalArray())

Select GetArrayDimensions(LocalArray())

; -------------------------------------------------
case 1 ; 1D array
; -------------------------------------------------
#print "1D Array"

; dump each cell to a new row in the console
for lp=0 to GetArrayElements( LocalArray() )
#print digits$(lp,4)+"="+str$(LocalArray(lp))
next
#print ""

; -------------------------------------------------
case 2 ; 2D Array
; -------------------------------------------------

#print "2D Array"

; if it's a 2D array we'll need to define a 2D array stub
; as the parse won't allow us to index an array with unknown number
; of dimensions at compile time

MakeArray Local2DArray()

Local2DArray() = ArrayHandle

; dump each cell to a new row in the console
for ylp=0 to GetArrayElements( Local2DArray(),2 )

row$=""
for xlp=0 to GetArrayElements( Local2DArray(),1 )

row$+=str$(Local2DArray(xlp,ylp))+","

next

Row$=trimright$(row$,",")

#print digits$(xlp,4)+"="+row$
next


#print ""

EndSelect

endif

endif

EndFunction




Function FillArray(ArrayHandle,FillValue)

if ArrayHandle
MakeArray LocalArray()
LocalArray()=ArrayHandle

; -----------------------------------------------------------------------
; here you might like to check is the array exists (was a valid handle)
; it's number of dimensions, size
; -----------------------------------------------------------------------
if GetArrayStatus(LocalArray())

Select GetArrayDimensions(LocalArray())

; -------------------------------------------------
case 1 ; 1D array
; -------------------------------------------------
; fill each cell with it's index
for lp=0 to GetArrayElements( LocalArray() )
LocalArray(lp)=FillValue+lp
next

; -------------------------------------------------
case 2 ; 2D Array
; -------------------------------------------------

; if it's a 2D array we'll need to define a 2D array stub
; as the parse won't allow us to index an array with unknown number
; of dimensions at compile time

MakeArray Local2DArray()

Local2DArray() = ArrayHandle

; fill each cell with it's index
for lp=0 to GetArrayElements( Local2DArray(),1 )
Local2Darray(lp,0)=FillValue+lp
next

EndSelect

endif

endif

EndFunction



Function GetIntegerArrayHandle(ThisArray())
EndFunction ThisArray()

Login required to view complete source code


     This method is useful for doing things like writing DLL functions for PlayBASIC2DLL, or functions that you can call via CallFunction for example, or just disconnecting 'data' from a individual array.      




  Related Links:

     - PlayBASIC Live:  Array Handles (2017-07-08)


kevin

   LearnToCode:  Array Handles:  Using Integer array to READ / WRITE types without deleting them

   In this example we create an array with a function and return it's handle back to the caller.   We then assign this VEctor3 typed array handle to both a vector2 array and an integer array in parallel.  

   This means we can READ or even WRITE to the typed array without PlayBASIC destroying any over written types.  Thus we can read an type handle from a typed array,  export it and place it within another array,  without COPYING the TYPE at all.  

 

PlayBASIC Code: [Select]
; PROJECT : Project1
; AUTHOR :
; CREATED : 21/03/2022
; ---------------------------------------------------------------------


Type Vector3
X#,Y#,Z#
EndType


Size=10

handle= AllocVectorArray(10)


makearray me2().vector3
makearray me().vector3
makearray ime()

me()= Handle
iMe() = Handle

Dim Me2(Size) as vector3


// if you run in debug you'll see both arrays are looking
// at the same data, but the INTEGER array iME() is considered
// To be typed by the debugger..

// Now if you delete (overwrite) a handle in IME(), PB wont
// call the FREE TYPE on this cell in the array.

// This means you can export a TYPE from an array this way,
// without having to get a pointer and peek / poke the array
// structure.

// EG.

print "-ME().Vector---------------------------------"
for lp=0 to size
print "Handle:"+str$(me(lp))
next


// Grab Handle from Ime(5)
ThisTYpeHANDLE = iMe(5)


// Write it our second ME2() vector array
Me2(5) = ThisTypeHANDLE


// Delete a handle from IME()
iMe(5) = Null


print "-ME().Vector---------------------------------"
for lp=0 to size
print "Handle:"+str$(me(lp))
next


print "-ME2().Vector---------------------------------"
for lp=0 to size
print "Handle:"+str$(me2(lp))
if me2(lp)
// Now even though there's a HANDLE at this location
// is it actually valid ??
print " X="+str$(me2(lp).x)+" Y="+str$(me2(lp).y)+" Z="+str$(me2(lp).z)
endif

next




sync
waitkey





Function AllocVectorArray(Size)
DIm V(Size) as vector3

for lp =0 to size
v(lp)= new vector3
v(lp).x = 1000+lp
v(lp).y = 2000+lp
v(lp).z = 3000+lp

next

EndFunction V() as vector3