DataType

Delegate


Description

A Delegate data type is an object representing a specific method.

Usage

For use in XojoScript code:

Delegate Sub name (parameterList)

or

Delegate Function name (parameterList) As DataType

Part

Description

name

Required. The name of the delegate.

parameterList

Optional: List of values representing parameters that are passed to the method when it is called. Multiple parameters are separated by commas.

DataType

Optional. The data type of the value returned by the function.

Methods

Name

Parameters

Returns

Shared

Constructor

p As Ptr

Invoke

[parameter1 As Type, parameterN As Type]

Type

Method descriptions


Delegate.Constructor

Constructor(p As Ptr)

Note

Constructors are special methods called when you create an object with the New keyword and pass in the parameters above.

The Delegate type's constructor takes a single Ptr, which is assumed to be correct for the Delegate type.

Assume there is a Delegate declared as SimpleProc:

Var pp As Ptr = AnOSFunctionThatReturnsAFunctionPointer()
Var sp As New SimpleProc(pp)
sp.Invoke()

Delegate.Invoke

Invoke([parameter1 As Type, parameterN As Type]) As Type

Call the method pointed by the Delegate. You must pass the same parameters as the method's ones and, if the method returns a value, you must use the return value as well.

If you defined a Delegate as:

Delegate Sub myDelegateMethod(x As Integer, y As Integer, s As String)

then you must use Invoke with the same parameters' type, as in:

Var d As myDelegateMethod
' <— Set d as your code requires
d.Invoke(1, 10, "An example string") ' Values are indicative

By contrast, if the Delegate is set to return a value as in:

Delegate Function myDelegateMethod(x As Integer, y As Integer, s As String ) As Boolean

then you must use the value returned by Invoke, as in:

Var d As myDelegateMethod
Var b As Boolean
' <— Set d as your code requires
b = d.Invoke(1, 10, "An example string") ' Values are indicative

Notes

A Delegate is a function pointer with a method signature. It has a single method, “Invoke” whose parameters and return value match the Delegate's parameters and return type. The Invoke method calls the method the Delegate instance represents.

Note

While delegates are objects, you cannot create a subclass of a Delegate type.

Delegates decouple interface from implementation in a similar way to events or interfaces. This decoupling allows you to treat a method implementation as a variable that is changeable based on runtime conditions. They represent methods that are callable without knowledge of the target object. You can change the function the Delegate points to on the fly.

A Delegate can be declared in either a module or a class. You use the Project > Add > Delegate menu command or the (optional) Add Delegate button in the Code Editor to create a Delegate entry.

A Delegate must have a name and can have optional parameters and a return type.


Creating a delegate value

Once you have added the Delegate as described above, create a variable or property of your Delegate type. For example, if you named your Delegate MyDelegate, you would declare a variable or property with myProp As MyDelegate.

There are two ways to create values that can be stored in delegates:

Usually, AddressOf (and WeakAddressOf) are used, taking an existing method and returning a function pointer in form of a Delegate.

The other way is to specify a function pointer address of type Ptr, passing it to a Delegate constructor. Assuming that there's a Delegate declared as Sub SimpleProc(), this could work as follows:

Var pp As Ptr = AnOSFunctionThatReturnsAFunctionPointer()
Var sp As New SimpleProc(pp)
sp.Invoke()

Sample code

Suppose you've added a Delegate named MethodCaller with no parameters or return type, and there is a checkbox MethodCheck that will determine which method to use.

Var callMethod As MethodCaller
If MethodCheck.Value Then
  callMethod = AddressOf TestMethod
Else
  callMethod = AddressOf AnotherMethod
End If
callMethod.Invoke

If you've defined your Delegate with parameters and a return type, the code might look like this instead:

someValue = callMethod.Invoke(param1, param2)

See the Invoke method for more examples.

A Delegate is a good way to allow one object to send the same message to various other objects. You can define a Register method that takes the Delegate as a parameter and adds it to an array of your Delegate type.

Sub Register (d As MessageDelegate)
  MessageDelegateArray.Add(d)
End Sub

When you need to send a message, you can call each Delegate in the array in a loop.

Sub SendMessage (msg As String)
  For Each d As MessageDelegate In MessageDelegateArray
    If d <> Nil Then
      d.Invoke(msg)
    End If
  Next d
End Sub

Compatibility

All project types on all supported operating systems.