How to implement an optional Module callback?

I’m trying to port C code that’s written with self-implemented “classes”. My only difficulty at the moment is that the code (a parser) implements optional progress and error callbacks. This means the module needs to be able to call code in its client, of course.

I’m inclined to handle them as Event Definitions but I’m not sure that that is the best option.

Suggestions?

Delegates perhaps

https://documentation.xojo.com/api/language/delegate.html

Delegates sound more appropriate but how would I make them optional?

I think this should work.

Methodname(Arg1 as integer, optional delcallback as delcallbackdef =nil) as resulttype

Delegates can be checked for nil as well.

what would be the advantage(s) of the delegate over the event definition ?

As Jean-Yves Pochez asked

Could someone please do a quick ED versus Delegate benefit comparison to help me choose between them?

So far, the delegate seems easier but it appears that only the ED lets me enforce call parameters and return type, is this correct?

On the Delegate VS Event Definition issue, one difference that myself had been meaning to verify is this:
The method called via a delegate can continue running in a thread if called from within a thread.
On the other hand, an event, when fired, will always execute in the main thread.
Is this correct or am I missing something here?

[quote=451772:@Georgios Poulopoulos]On the Delegate VS Event Definition issue, one difference that myself had been meaning to verify is this:
The method called via a delegate can continue running in a thread if called from within a thread.
On the other hand, an event, when fired, will always execute in the main thread.
Is this correct or am I missing something here?[/quote]
The event will be part of the context it was triggered from. So if you use RaiseEvent from within a Thread.Run (or something called by Thread.Run of course) then the event will also be part of that thread.

There no tangible difference in how the code executes as a delegate vs an event.

An advantage of using events is the ability to only hook up code when you need to, such as on the layout or using AddHandler. The calling code simply uses RaiseEvent and doesn’t care at all about what is handling the event.
Delegates, however, allow greater flexibility. Imagine HTTPSocket.Get(url, callback) so the response could go to a method of your choice instead of the PageReceived event. Currently, all requests go to PageReceived, where you have to determine what the request was if you want to act on it. Using a delegate would mean you can pair a request to a specific method for handling the response.
The biggest drawback to delegates is they require very careful reference tracking and can introduce hard to find exceptions that in many cases, look like complete nonsense. You can use WeakAddressOf, but Xojo has no way to tell if the target has been destroyed before calling it. So… they can be problematic.