Delegates As Method Parameters

Hey guys,

I have a couple of delegates defined in a class and I want to be able to pass either of them to an event handler. I want the event handler’s parameter to be a generic delegate object.

Is this possible?

I’m trying to do this but I can’t seem to set a parameter to a type “delegate.” So as delegates are pointers, I tried sending it as a ptr, but that didn’t work either on the other side.

How can I pass a generic delegate in my event handler?

I believe you will have to overload your function to handle each different type of delegate. Xojo needs to know what method signature is associated with each delegate that you pass to make sure that you properly invoke the delegate. If there existed a geneic delegate you would have no way of knowing whether the delegate must be invoked with parameters, what types the parameters are, if it returns a value, etc.

Actually, I just answered my own question and doing what I wanted to do IS possible. Not sure why I didn’t think of it before.

I simply made the parameter in the event definition that I wanted to use to pass the delegate as type object. Then in the event hander I simply checked which delegate type the object was using IsA.

It compiles and starts up just fine at least…

Can you please post a little example of pseudo-code? Do you assign the delegate as “Object” and the check & cast?

Can’t you use the same delegate definition with optional parameters? That way your methods can be made to fit the bill and your event handler doesn’t have to know which one you passed.

Sure.

So in the interest of full disclosure, what I am about to post does compile, but it doesn’t work the way I wanted it to. We’ll see if the astute reader can see my mistake…

So in the handling method for my delegate, I have the following:

ConnectedCallback is the instance of the delegate in my object, MyDevice. This delegate handler is to handle a TCPSocket connected event.

Private Sub HandleConnected(sender as MyDevice)
  If ConnectedCallback <> nil Then
    ConnectedCallback.Invoke(self)
  Else
    RaiseEvent SetHandlers(ConnectedCallback)
    If ConnectedCallback <> Nil Then
      ConnectedCallback.Invoke(self)
    End If
  End If
End Sub

Now the signature for the SetHanlders event was:

Event SetHandlers(del as Object)
Sub ()

Now, the method in my control that has this object as a property looks like:

Private Sub Device_SetHandlers(m as MyDevice, del as object)
 
If del IsA MyDevice.ConnectedCallback Then
    m.SetConnectedHandler(AddressOf MyDeviceConnectedEventHandler)
ElseIf del IsA MyDevice.ParametersLoadedCallback Then
    m.SetParametersLoadedHandler(AddressOf DeviceParametersLoadedEventHandler)
End If
End Sub

So did you see the problem?

Well, the problem is my callback is NIL when I raise the event. So the object is NIL! DOH! It never ends up returning what I want.

So I am sure that if the delegate object was not Nil, you could easily do this. For me, I changed to using an enum and set different enum values to check for and changed the Device_SetHandlers subroutine to set the proper delegates based on the enum value.

I’m doing this because I want to change where handlers for an object occurs when a specific window is open. Later after that window is closed, the handlers are all set to Nil and so the first window isn’t handling any of these events. So then when an event comes in I want to give myself the option of handling it and assigning a new handler. It works quite well…

I suppose I could. That’s the cool thing about using delegates. Makes things really, really flexible. But in this case, I’m trying to use a common method to add the handlers for two different events. So they can’t have the same delegate definition.