News:

PlayBASIC2DLL V0.99 Revision I Commercial Edition released! - Convert PlayBASIC programs to super fast Machine Code. 

Main Menu

Returning Data from Dynamically Called Functions in PlayBASIC

Started by kevin, August 12, 2024, 12:18:51 PM

Previous topic - Next topic

kevin

Returning Data from Dynamically Called Functions in PlayBASIC


In this example source code we use a user defined type (a structure) to hold our return type from a function call.  This is really handle approach for when dynamically calling functions in your PlayBASIC programs using CallFunction   

Simple, but powerful pattern to wrap your coding brain around ! 



PlayBASIC Code: [Select]
    Type tReturn
DataType
iValue
fValue#
sString$
EndType

dim Result as tReturn pointer
Result = new tReturn

for lp =0 to 20
Index=wrapvalue(Index+1,1,4)
Name$="Work_Function_"+digits$(index,2)
callFunction Name$,result

// display what's in the result structure
Name$+=" returns "+GetReturn(Result)
print Name$

next
sync
waitkey




// Test worker functions that are called by name that we
// need to return data from.


Function Work_Function_01(result as tReturn pointer)
ReturnInteger(result, 100)
EndFunction

Function Work_Function_02(result as tReturn pointer)
ReturnFloat(result, 123.456)
EndFunction



Function Work_Function_03(result as tReturn pointer)
ReturnString(result, "MyString"+str$(rnd(100)) )
EndFunction


// Functins to set and get the return data structure.


function GetReturn(Output as tReturn pointer)
select Output.datatype
case 1
Result$="Integer:"+str$(output.ivalue)
case 2
Result$="float:"+str$(output.fvalue)
case 3
Result$="String:"+output.sstring
endselect
ENdFunction result$

Function ReturnInteger(Output as tReturn pointer, ThisInteger)
Output.DataType =1
Output.iValue = ThisInteger
ENdFunction

Function ReturnFloat(Output as tReturn pointer, ThisFloat#)
Output.DataType =2
Output.fValue = ThisFloat#
ENdFunction

Function ReturnString(Output as tReturn pointer, ThisString$)
Output.DataType =3
Output.sString = ThisString$
ENdFunction










  Example #2  - As seen in the video


 

PlayBASIC Code: [Select]
    Type tReturn
DataType
iValue
fValue#
sString$
EndType

dim CallFunctionResult as tReturn
CallFunctionResult= new tReturn

for lp =0 to 20
Index=wrapvalue(Index+1,1,4)
Name$="Work_Function_"+digits$(index,2)
callFunction Name$

// display what's in the result structure
Name$+=" returns "+GetReturn()
print Name$

next
sync
waitkey




// Test worker functions that are called by name that we
// need to return data from.


Function Work_Function_01()
ReturnInteger( 100)
EndFunction

Function Work_Function_02()
ReturnFloat( 123.456)
EndFunction

Function Work_Function_03()
ReturnString("MyString"+str$(rnd(100)) )
EndFunction


// Functins to set and get the return data structure.

function GetType()
result=CallFunctionResult.dataType
EndFunction result


function GetReturn()
select GetType()
case 1
Result$="Integer:"+str$(CallFunctionResult.ivalue)
case 2
Result$="float:"+str$(CallFunctionResult.fvalue)
case 3
Result$="String:"+CallFunctionResult.sstring
endselect
ENdFunction result$

Function ReturnInteger(ThisInteger)
CallFunctionResult.DataType =1
CallFunctionResult.iValue = ThisInteger
ENdFunction

Function ReturnFloat(ThisFloat#)
CallFunctionResult.DataType =2
CallFunctionResult.fValue = ThisFloat#
ENdFunction

Function ReturnString(ThisString$)
CallFunctionResult.DataType =3
CallFunctionResult.sString = ThisString$
ENdFunction








kevin

Variants - Variable Input Parameters in Function Calls


  Here's the basic usage 


PlayBASIC Code: [Select]
    type tInputParams
X,Y
TITLE$
Colour
EndType

Dim Inputs as tInputParams pointer
inputs=new tInputParams




for lp =0 to 20
Index=wrapvalue(Index+1,1,4)

Name$="Work_Function_"+digits$(index,2)


Inputs.x = 600
Inputs.y = 200
inputs.title = "DUDE WHERES MY CAR?"


// Push
FlushParameters()
PushParamInt( "X" ,600)
PushParamInt( "Y" ,200)
PushParamString( "TITLE" ,"DUDE WHERES MY CAR?")
PushParamInt( "JUNK" ,99999)
callFunction Name$, Inputs


// display what's in the result structure
Name$+=" returns "+GetReturn()
print Name$




// Test calling a functin wit
Work_Function_TEST(Inputs)


next
sync
waitkey




// Test worker functions that are called by name that we
// need to return data from.

Function Work_Function_TEST(Params as tInputParams pointer)

// f
X =Params.X
Y =Params.Y
Title$=Params.Title$

X+=200
Circlec X,Y,100,true,$00ff00
ink $00
centertext x,y,Title$
ink -1

// Return
ReturnInteger( 100)
EndFunction




Function Work_Function_01(Params as tInputParams pointer)

// Decode pushed parameters by name
repeat
Name$=ParamName$()
Select Name$
case "X" : X = GetParamINT()
case "Y" : Y = GetParamINT()
case "TITLE" : TITLE$ = GetParamSTRING$()
default : SkipParam()
EndSelect
until len(Name$)=0

Circle X,Y,100,true
ink 0
centertext x,y,Title$
ink -1

// Return
ReturnInteger( 100)
EndFunction

Function Work_Function_02(Params as tInputParams pointer)

boxc 700,100,750,800,true,$ff0000
ReturnFloat( 123.456)
EndFunction

Function Work_Function_03(Params as tInputParams pointer)

line params.x,params.y,rnd(800),rnd(800)

ReturnString("MyString"+str$(rnd(100)) )
EndFunction









  Ideas on Dynamically Passing Arguments in PlayBASIC

 


  Commands Usage

    - CallFunction



DownLoad

    Full Code attached

kevin

Variants - Variable Input Parameters in Function Calls V003

  This is a more elegant way of achieving argument passing into dynamically called functions.  The idea being is that the function prototypes (the pattern of parameters) are not all the same,  but if we push all the things we need, then call  our function and let it grab what it needs we can decouple of the code block from each other.  So the functions don't need to call back or access global structures. 



PlayBASIC Code: [Select]
; PROJECT : 2024-08-13 - Variant - Function Calling - V003
; AUTHOR : Kevin Picone - PlayBASIC Tutor - https://playbasic.com
; CREATED : 13/08/2024
; EDITED : 16/08/2024
; ---------------------------------------------------------------------


Dim Messages$(100)

Do
Cls

GridX=200
GridY=200
X=GridX/2
Y=GridY/2


for lp =0 to 20
Index=wrapvalue(Index+1,1,4)

Name$="Work_Function_"+digits$(index,2)

// Push
FlushParameters()
PushParamInt( "X" ,X)
PushParamInt( "Y" ,Y)
PushParamString( "TITLE" ,"DUDE WHERES MY CAR?"+str$(lp))
PushParamInt( "MOUSEX" ,mouseX())
PushParamInt( "MOUSEY" ,mouseY())
PushParamInt( "MOUSEBUTTON" ,mousebutton())
callFunction Name$

// display what's in the result structure
Messages$(lp)=Name$+" returned "+GetReturn()

if (X+GridX)>=GetSurfaceWidth()
X=gridX/2
Y+=GridY
if Y>GetSurfaceHeight() then exit
else
X+=GridX
endif

next

// draw the messages over the top of the display
for lp=0 to GetArrayelements(Messages$())
m$=Messages$(lp)
if len(m$) then print m$
next


sync
loop




Function Work_Function_01()

// Get our variables from the stack, in the type we want them
X =GetIntVariable("X")
Y =GetIntVariable("Y")
Title$=GetStringVariable$("TITLE")

Circlec X,Y,100,true,$334455
ink 0
centertext x,y,Title$
ink -1

// Return
ReturnInteger( X)
EndFunction

Function Work_Function_02()

X =GetIntVariable("X")
Y =GetIntVariable("Y")
Title$=GetStringVariable$("TITLE")

Radius=95
boxc x-Radius,y-Radius,X+Radius,Y+Radius,true,$ff00ff

ink 0
centertext x,y,Title$
ink -1

ReturnFloat( X*Y )
EndFunction

Function Work_Function_03()

// This Function only needs the X/Y and Mouse cords
// so that's all we read
X =GetIntVariable("X")
Y =GetIntVariable("Y")
MX =GetIntVariable("MOUSEX")
MY =GetIntVariable("MOUSEY")

// compute the direction of the mouse cursor from this point
Angle#=getangle2d(x,y,mx,my)
x2 =x+cos(angle#)*45
y2 =y+sin(angle#)*45

// draw a line from the grid X/Y towards the mouse
line X,Y,x2,y2

ReturnString("MyString"+str$(XPOS) )
EndFunction












  Download Full Source Code:

  Attached bellow (login)