Function interfaces
If functions are objects then we may as well have interfaces for them.
The syntax for function interfaces is: function interface name takes (arguments) returns (return value) It is actually similar to a function declaration.
Variables/values of a function interface type may be called using execute() and evaluate() as defined above:
To assign to variables of a function interface type you first need to get a function's pointer. The syntax to get them is understandable if you assume that every declared function interface will get as static members the functions found in the map script that follow its argument/return value rules.
function interface Arealfunction takes real x returns real
function double takes real x returns real
    return x*2.0
endfunction
function triple takes real x returns real
    return x*2.0
endfunction
function Test1 takes real x, Arealfunction F returns real
    return F.evaluate(F.evaluate(x)*F.evaluate(x))
endfunction
function Test2 takes nothing returns nothing
    local Arealfunction fun = Arealfunction.double //syntax to get pointer to function
    call BJDebugMsg( R2S(  Test1(1.2, fun) ))
    call BJDebugMsg( R2S(  Test1(1.2, Arealfunction.triple ) )) //also possible...
endfunction
In this example we are actually having functions as arguments and as a variable. You may also typecast(see bellow) a function pointer to integer and then back to the interface function it originated.
It is also possible to get a function pointer without typing the interface's name, notice that this will not allow you to validate the function as following the interface's declaration, but it is simpler nontheless.:
//repeat a call of the same function on a real variable thrice!
function double takes real x returns real
    return 2*x
endfunction
function square takes real x returns real
    return x*x
endfunction
function interface realfunc takes real x returns real
function repeater3 takes real x, realfunc F returns real
    set x=F.evaluate(x)
    set x=F.evaluate(x)
    set x=F.evaluate(x)
    return x
endfunction
function test takes nothing returns nothing
    local real x = repeater3( 2.0, double) //notice we are just using the functions' names as if they were values.
    local real y = repeater3( 2.0, square)
   //The results are x=16 and y=256.
   //explanation: the first is equivalent to:
   //       set x=2
   //       set x=2*x
   //       set x=2*x
   //       set x=2*x
  
   // While the second is:
   //       set y=2
   //       set y=y*y
   //       set y=y*y
   //       set y=y*y
 // yep, function interfaces allow you to use functions as if they were just another sort of variable.
endfunction
You may also use methods for function interfaces, the static method gets converted into a function pointer.
function interface myFunc takes integer a, integer b returns nothing
struct try
    static method AAAA takes integer a, integer b returns nothing
       call BJDebugMsg( I2S(a)+", "+I2S(b) )
    endmethod
    method ooz takes nothing returns nothing
       local myFunc fun = try.AAAA
          call fun.evaluate(5,6)
          call fun.evaluate(7,8)
    endmethod
endstruct
Notice that non-static methods are usable as well for function interfaces. They behave as functions that take an integer in the first argument though.
When using non-static methods as function pointers, you are just converting them into functions that take an integer as first argument, the function pointer instance will require one of the struct's instances to get called.
function interface myFunc takes integer x returns nothing
struct TestStruct
    string msg
    method AAAA takes nothing returns nothing
       call BJDebugMsg(msg)
    endmethod
endstruct
function test takes nothing returns nothing
    local TestStruct ts = TestStruct.create()
    local myFunc mf
    set ts.msg = "!!! !!! !!! !!! "
    set mf = TestStruct.AAAA
    call mf.evaluate(ts ) //notice that we are explicitly feeding the function a instance
endfunction
Last modified: 16 October 2024