{{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"}}