{{fbdoc item="title" value="Callback"}}----
Callback procedures

{{fbdoc item="desc"}}
	From Wikipedia: A callback, also known as a "call-after" function, is any executable code that is passed as an argument to other code; that other code is expected to call back (execute) the argument at a given time. This execution may be immediate as in a synchronous (or blocking) callback, or it might happen at a later time as in an asynchronous (or deferred) callback.

{{fbdoc item="ex"}}
	Example where a mathematical function is an argument in plot function call:
	(the invocation is implemented by calling the ""'PlotF()'"" procedure, and the callback function is the 'Linear()', 'Sinusoidal()', or 'Quadratic()' function)
		{{fbdoc item="filename" value="examples/manual/proguide/callback/callback1.bas"}}%%(freebasic)
Type MathFunction As Function( Byval x As Double ) As Double

Function Linear( Byval x As Double ) As Double
	Return x
End Function

Function Quadratic( Byval x As Double ) As Double
	Return x * x
End Function

Function Sinusoidal( Byval x As Double ) As Double
	Return Sin(x)
End Function

Sub PlotF( Byval f As MathFunction )
	Pset( -15, f(-15) )
	For x As Double = -15 To 15 Step 0.1
		Line -( x, f(x) )
	Next
End Sub

Screen 19
Window (-15,-10)-(15,10)

PlotF( @Linear )
PlotF( @Sinusoidal )
PlotF( @Quadratic )

Sleep
		%%The three callback processes are synchronous because each callback function is completely executed before ""'PlotF()'"" returns to the caller code.
		
	Similar plotting example (as above) but with a asynchronous callback. Here an artificial delay is added. A more realistic case would be if the data to be plotted is retrieved form a web-server with a response time larger than acceptable for the main loop of our program (prevent blocking behavior):
		{{fbdoc item="filename" value="examples/manual/proguide/callback/callback2.bas"}}%%(freebasic)
#Include "fbthread.bi"

Type MathFunction As Function( Byval x As Double ) As Double

Sub ThreadPlot( Byval p As Any Ptr )
	Sleep 1500, 1  '' sleep added only to check the asynchronous way of the callback
	Dim f As MathFunction = p
	Window (-15,-10)-(15,10)
	Pset( -15, f(-15) )
	For x As Double = -15 To 15 Step 0.1
		Line -( x, f(x) )
	Next
End Sub

Function PlotF( Byval f As MathFunction ) As String
	Print "Plotting requested"
	Threaddetach( Threadcreate( @ThreadPlot, f ) )
	Return "Plotting request taken into account"
End Function

Function Linear( Byval x As Double ) As Double
	Return x
End Function

Function Quadratic( Byval x As Double ) As Double
	Return x * x
End Function

Function Sinusoidal( Byval x As Double ) As Double
	Return Sin(x)
End Function

Screen 19

Print PlotF( @Linear )
Print PlotF( @Sinusoidal )
Print PlotF( @Quadratic )

'' following code added only to check the asynchronous way of callbacks
Print "Main program continues ";
For I As Integer = 1 To 15
	Print ".";
	Sleep 200, 1
Next I
Print
Print "Main program finished"

Sleep
		%%The three callback processes are asynchronous because the ""'PlotF()'"" function returns immediately, and each callback function is executed in parallel with the caller's next code, from a ""'ThreadPlot()'"" thread created (previously) by ""'PlotF()'"" for each of them.
		
	Example of a callback function for comparing values in a array to be sorted by the qsort algorithm:
	(the invocation is implemented by calling the 'qsort()' procedure, and the callback function is the ""'CmpVarLenStr()'"" function)
		{{fbdoc item="filename" value="examples/manual/proguide/callback/callback_qsort.bas"}}%%(freebasic)
#include "crt/stdlib.bi"

Function CmpVarLenStr cdecl( Byval p1 As Any Ptr, Byval p2 As Any Ptr ) As long  '' compare 2 var-len strings
	Dim As String Ptr ps1 = p1
	Dim As String Ptr ps2 = p2
	If *ps1 < *ps2 Then
		Return -1
	Elseif *ps1 > *ps2 Then
		Return 1
	Else
		Return 0
	End If
End Function

Sub PrintList( array() As String)  '' print a var-len string list
	For I As Integer = Lbound(array) To Ubound(array)
		Print array(I)
	Next I
	Print
End Sub

Dim forename(1 to 12) As String = {"Madison", "Emily", "Hailey", "Sarah", "Kaitlyn", "Hannah", _
								   "Jacob", "Christopher", "Nicholas", "Michael", "Matthew", "Joshua" }

Print "LIST OF UNSORTED FORENAMES:"
PrintList( forename() )

qsort( @forename(Lbound(forename)), Ubound(forename) - Lbound(forename) + 1, Sizeof(String), @CmpVarLenStr )

Print "LIST OF SORTED FORENAMES:"
PrintList( forename() )

Sleep
		%%The callback process is synchronous because the callback function is completely executed (several times), (successively) called by 'qsort()', before 'qsort()' returns to the caller code.

{{fbdoc item="see"}}
	- [[KeyPgSubPtr|SUB Pointer]]
	- [[KeyPgFunctionPtr|FUNCTION Pointer]]
	- [[ProPgMtThreads|Threads]]
	- [[ProPgObjectRtti|OBJECT built-in and RTTI info]]

{{fbdoc item="back" value="CatPgProgrammer|Programmer's Guide"}}