Assigning a function reference to a type field.

BlitzMax Forums/BlitzMax Programming/Assigning a function reference to a type field.

very handy feature. i used it quite a bit in the Irrlicht wrapper in order to bind C++ classes to BMAX types. here is an example. hopefully its clear enough...

Strict
Framework BRL.Blitz

Type testfuncstore
	Field testfunc3val:Int=2233445

	' function references are stored as byte ptrs
	Field func1:Byte Ptr
	Field func2:Byte Ptr
	Field func3:Byte Ptr
	
	Method dofunc1:Float()
		' this definition must match the function called and have the ()
		' after this line you can use locfunc1 just like a function
		Local locfunc1:Float()=func1
		Return locfunc1()
	EndMethod
	Method dofunc2(msg:String)
		' this definition must match the function called and have the ()
		' after this line you can use locfunc2 just like a function
		Local locfunc2(msg:String)=func2
		locfunc2(msg)
	EndMethod	
	Method dofunc3:Int()
		' this definition must match the function called and have the ()
		' after this line you can use locfunc3 just like a function
		Local locfunc3:Int(test:testfuncstore)=func3
		
		' pass this instance in
		Return locfunc3(Self)
	EndMethod
	
	Method getFunc3Val:Int()
		Return testfunc3val
	EndMethod
	
	' you can also point to Type functions since they are static
	' this is particularly interesting if you use this function as a C callback
	' function.  you can essentially call Methods on particular instances of BMAX types
	' from C.  it takes a little more setup than this shows but hopefully you get the idea.
	Function typefunc3:Int(test:testfuncstore)
		' you can call methods and reference fields on the particular instance passed in
		Return test.getFunc3Val()
	EndFunction
EndType

' test function with a return value
Function func1:Float()
	Return 1.111
EndFunction

' test function with a paramter
Function func2(msg:String)
	DebugLog(msg)
EndFunction

Local tester:testfuncstore=New testfuncstore

' store pointers to the functions
tester.func1=func1
tester.func2=func2
tester.func3=testfuncstore.typefunc3

' show the return value
DebugLog(tester.dofunc1())
' dofunc2 does the debuglog
tester.dofunc2("msg parameter passed")
' show the int return value from the type function
DebugLog(tester.dofunc3())


as for the import files, try moving the functions to a new file:

' testfuncs.bmx
Public

' test function with a return value
Function func1:Float()
Return 1.111
EndFunction

' test function with a paramter
Function func2(msg:String)
DebugLog(msg)
EndFunction

and then adding an import line at the top of the type file (remember to remove the functions from the first file. works the same as before.
Strict
Framework BRL.Blitz
Import "testfuncs.bmx"

Type testfuncstore
	Field testfunc3val:Int=2233445
	
	' function references are stored as byte ptrs
	Field func1:Byte Ptr
	Field func2:Byte Ptr
	Field func3:Byte Ptr
	
	Method dofunc1:Float()
		' this definition must match the function called and have the ()
		' after this line you can use locfunc1 just like a function
		Local locfunc1:Float()=func1
		Return locfunc1()
	EndMethod

	Method dofunc2(msg:String)
		' this definition must match the function called and have the ()
		' after this line you can use locfunc2 just like a function
		Local locfunc2(msg:String)=func2
		locfunc2(msg)
	EndMethod

	Method dofunc3:Int()
		' this definition must match the function called and have the ()
		' after this line you can use locfunc3 just like a function
		Local locfunc3:Int(test:testfuncstore)=func3
		
		' pass this instance in
		Return locfunc3(Self)
	EndMethod
	
	Method getFunc3Val:Int()
		Return testfunc3val
	EndMethod
	
	' you can also point to Type functions since they are static
	' this is particularly interesting if you use this function as a C callback
	' function.  you can essentially call Methods on particular instances of BMAX types
	' from C.  it takes a little more setup than this shows but hopefully you get the idea.
	Function typefunc3:Int(test:testfuncstore)
		' you can call methods and reference fields on the particular instance passed in
		Return test.getFunc3Val()
	EndFunction
EndType


Local tester:testfuncstore=New testfuncstore

' store pointers to the functions
tester.func1=func1
tester.func2=func2
tester.func3=testfuncstore.typefunc3

' show the return value
DebugLog(tester.dofunc1())
' dofunc2 does the debuglog
tester.dofunc2("msg parameter passed")
' show the int return value from the type function
DebugLog(tester.dofunc3())