NoesisGUI

Using Delegates

Delegates are a generic implementation for Callbacks. Delegates in Noesis Engine are implemented very similar to .NET functionality. Delegates ensure that the callback method is type-safe. Delegates also integrate the ability to call multiple methods sequentially and support the calling of static methods as well as instance methods.

Declaring Delegates

A delegate is declared using a function signature. For example:

/// A delegate with void return and two parameters: NsSize and NsFloat32
Delegate<void (NsSize, NsFloat32)> delegate;

Call Back Static Methods

Following with the example above, we add a static method to the delegate and invoke it:

void Print(NsSize size, NsFloat32 value)
{
    printf("%d %4.3f", size, value);
}

void main()
{
    // Create and Bind the delegate
    Delegate<void (NsSize, NsFloat32)> delegate(&Print);

    // Invoke
    delegate(500, 10.0f);
}

Call Back Instance Methods

In a similar way, instance methods are binded to the delegate

struct Printer
{
    void Print(const NsChar* string) const
    {
        printf("%s", string);
    }
};

void main()
{
    // Create the instance
    Printer printer;

    // Create and Bind the delegate
    Delegate<void (const NsChar*)> delegate(&printer, &Printer::Print);

    // Invoke
    delegate("hi :)");
}

Call Back Many Methods (MultiDelegates)

A delegate can be binded to several callbacks using the overloaded operators += and -=:

struct Printer
{
    void Print(const NsChar* string) const
    {
        printf("Printer: %s", string);
    }
};

struct Screen
{
    void Print(const NsChar* string) const
    {
        printf("Screen: %s", string);
    }
};

void main()
{
    // Create the instances
    Printer printer;
    Screen screen;

    // Create and Bind the delegate
    Delegate<void (const NsChar*)> delegate;

    delegate += MakeDelegate(&printer, &Printer::Print);
    delegate += MakeDelegate(&screen, &Screen::Print);

    // Invoke. This line will call all the callbacks
    delegate("hi :)");
}

When using MultiDelegates the returning value from the delegate invocation is the one obtained from the last invocation.

Reference Counting

Delegates do not increment the reference counter of the target instance. This is done to avoid creating circular references that appears when a delegate points back to the object that contains it. This implies that before destroying an instance that is the target of a delegate it must be removed from the delegate.

But if the target instance supports weak references then the delegate employs that mechanism to ensure that no dangling pointers are used. In this case it is not necessary that you remove the target instance from the delegate because it becomes automatically null.

© 2017 Noesis Technologies