// Written in the D programming language.

/**
 * Signals and Slots are an implementation of the Observer Pattern.
 * Essentially, when a Signal is emitted, a list of connected Observers
 * (called slots) are called.
 *
 * There have been several D implementations of Signals and Slots.
 * This version makes use of several new features in D, which make
 * using it simpler and less error prone. In particular, it is no
 * longer necessary to instrument the slots.
 *
 * References:
 *      $(LUCKY A Deeper Look at Signals and Slots)$(BR)
 *      $(LINK2 http://en.wikipedia.org/wiki/Observer_pattern, Observer pattern)$(BR)
 *      $(LINK2 http://en.wikipedia.org/wiki/Signals_and_slots, Wikipedia)$(BR)
 *      $(LINK2 http://boost.org/doc/html/$(SIGNALS).html, Boost Signals)$(BR)
 *      $(LINK2 http://qt-project.org/doc/qt-5/signalsandslots.html, Qt)$(BR)
 *
 *      There has been a great deal of discussion in the D newsgroups
 *      over this, and several implementations:
 *
 *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/announce/signal_slots_library_4825.html, signal slots library)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/Signals_and_Slots_in_D_42387.html, Signals and Slots in D)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/Dynamic_binding_--_Qt_s_Signals_and_Slots_vs_Objective-C_42260.html, Dynamic binding -- Qt's Signals and Slots vs Objective-C)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/Dissecting_the_SS_42377.html, Dissecting the SS)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/dwt/about_harmonia_454.html, about harmonia)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/announce/1502.html, Another event handling module)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/41825.html, Suggestion: signal/slot mechanism)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/13251.html, Signals and slots?)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/10714.html, Signals and slots ready for evaluation)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/digitalmars/D/1393.html, Signals &amp; Slots for Walter)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/28456.html, Signal/Slot mechanism?)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/19470.html, Modern Features?)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/16592.html, Delegates vs interfaces)$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/16583.html, The importance of component programming (properties$(COMMA) signals and slots$(COMMA) etc))$(BR)
 *      $(LINK2 http://www.digitalmars.com/d/archives/16368.html, signals and slots)$(BR)
 *
 * Bugs:
 *      Slots can only be delegates formed from class objects or
 *      interfaces to class objects. If a delegate to something else
 *      is passed to connect(), such as a struct member function,
 *      a nested function or a COM interface, undefined behavior
 *      will result.
 *
 *      Not safe for multiple threads operating on the same signals
 *      or slots.
 * Macros:
 *      SIGNALS=signals
 *
 * Copyright: Copyright Digital Mars 2000 - 2009.
 * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
 * Authors:   $(HTTP digitalmars.com, Walter Bright)
 * Source:    $(PHOBOSSRC std/_signals.d)
 *
 * $(SCRIPT inhibitQuickIndex = 1;)
 */
/*          Copyright Digital Mars 2000 - 2009.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
module std.signals;

import core.exception : onOutOfMemoryError;
import core.stdc.stdlib : calloc, realloc, free;
import std.stdio;

// Special function for internal use only.
// Use of this is where the slot had better be a delegate
// to an object or an interface that is part of an object.
extern (C) Object _d_toObject(void* p);

// Used in place of Object.notifyRegister and Object.notifyUnRegister.
alias DisposeEvt = void delegate(Object);
extern (C) void  rt_attachDisposeEvent( Object obj, DisposeEvt evt );
extern (C) void  rt_detachDisposeEvent( Object obj, DisposeEvt evt );
//debug=signal;

/************************
 * Mixin to create a signal within a class object.
 *
 * Different signals can be added to a class by naming the mixins.
 */

mixin template Signal(T1...)
{
    static import core.exception;
    static import core.stdc.stdlib;
    /***
     * A slot is implemented as a delegate.
     * The slot_t is the type of the delegate.
     * The delegate must be to an instance of a class or an interface
     * to a class instance.
     * Delegates to struct instances or nested functions must not be
     * used as slots.
     */
    alias slot_t = void delegate(T1);

    /***
     * Call each of the connected slots, passing the argument(s) i to them.
     * Nested call will be ignored.
     */
    final void emit( T1 i )
    {
        if (status >= ST.inemitting || !slots.length)
            return; // should not nest

        status = ST.inemitting;
        scope (exit)
            status = ST.idle;

        foreach (slot; slots[0 .. slots_idx])
        {   if (slot)
                slot(i);
        }

        assert(status >= ST.inemitting);
        if (status == ST.inemitting_disconnected)
        {
            for (size_t j = 0; j < slots_idx;)
            {
                if (slots[j] is null)
                {
                    slots_idx--;
                    slots[j] = slots[slots_idx];
                }
                else
                    j++;
            }
        }
    }

    /***
     * Add a slot to the list of slots to be called when emit() is called.
     */
    final void connect(slot_t slot)
    {
        /* Do this:
         *    slots ~= slot;
         * but use malloc() and friends instead
         */
        auto len = slots.length;
        if (slots_idx == len)
        {
            if (slots.length == 0)
            {
                len = 4;
                auto p = core.stdc.stdlib.calloc(slot_t.sizeof, len);
                if (!p)
                    core.exception.onOutOfMemoryError();
                slots = (cast(slot_t*) p)[0 .. len];
            }
            else
            {
                import core.checkedint : addu, mulu;
                bool overflow;
                len = addu(mulu(len, 2, overflow), 4, overflow); // len = len * 2 + 4
                const nbytes = mulu(len, slot_t.sizeof, overflow);
                if (overflow) assert(0);

                auto p = core.stdc.stdlib.realloc(slots.ptr, nbytes);
                if (!p)
                    core.exception.onOutOfMemoryError();
                slots = (cast(slot_t*) p)[0 .. len];
                slots[slots_idx + 1 .. $] = null;
            }
        }
        slots[slots_idx++] = slot;

     L1:
        Object o = _d_toObject(slot.ptr);
        rt_attachDisposeEvent(o, &unhook);
    }

    /***
     * Remove a slot from the list of slots to be called when emit() is called.
     */
    final void disconnect(slot_t slot)
    {
        debug (signal) writefln("Signal.disconnect(slot)");
        size_t disconnectedSlots = 0;
        size_t instancePreviousSlots = 0;
        if (status >= ST.inemitting)
        {
            foreach (i, sloti; slots[0 .. slots_idx])
            {
                if (sloti.ptr == slot.ptr &&
                    ++instancePreviousSlots &&
                    sloti == slot)
                {
                    disconnectedSlots++;
                    slots[i] = null;
                    status = ST.inemitting_disconnected;
                }
            }
        }
        else
        {
            for (size_t i = 0; i < slots_idx; )
            {
                if (slots[i].ptr == slot.ptr &&
                    ++instancePreviousSlots &&
                    slots[i] == slot)
                {
                    slots_idx--;
                    disconnectedSlots++;
                    slots[i] = slots[slots_idx];
                    slots[slots_idx] = null;        // not strictly necessary
                }
                else
                    i++;
            }
        }

         // detach object from dispose event if all its slots have been removed
        if (instancePreviousSlots == disconnectedSlots)
        {
            Object o = _d_toObject(slot.ptr);
            rt_detachDisposeEvent(o, &unhook);
        }
     }

    /* **
     * Special function called when o is destroyed.
     * It causes any slots dependent on o to be removed from the list
     * of slots to be called by emit().
     */
    final void unhook(Object o)
    in { assert( status == ST.idle ); }
    body {
        debug (signal) writefln("Signal.unhook(o = %s)", cast(void*) o);
        for (size_t i = 0; i < slots_idx; )
        {
            if (_d_toObject(slots[i].ptr) is o)
            {   slots_idx--;
                slots[i] = slots[slots_idx];
                slots[slots_idx] = null;        // not strictly necessary
            }
            else
                i++;
        }
    }

    /* **
     * There can be multiple destructors inserted by mixins.
     */
    ~this()
    {
        /* **
         * When this object is destroyed, need to let every slot
         * know that this object is destroyed so they are not left
         * with dangling references to it.
         */
        if (slots.length)
        {
            foreach (slot; slots[0 .. slots_idx])
            {
                if (slot)
                {   Object o = _d_toObject(slot.ptr);
                    rt_detachDisposeEvent(o, &unhook);
                }
            }
            core.stdc.stdlib.free(slots.ptr);
            slots = null;
        }
    }

  private:
    slot_t[] slots;             // the slots to call from emit()
    size_t slots_idx;           // used length of slots[]

    enum ST { idle, inemitting, inemitting_disconnected }
    ST status;
}

///
@system unittest
{
    import std.signals;

    int observedMessageCounter = 0;

    class Observer
    {   // our slot
        void watch(string msg, int value)
        {
            switch (observedMessageCounter++)
            {
                case 0:
                    assert(msg == "setting new value");
                    assert(value == 4);
                    break;
                case 1:
                    assert(msg == "setting new value");
                    assert(value == 6);
                    break;
                default:
                    assert(0, "Unknown observation");
            }
        }
    }

    class Observer2
    {   // our slot
        void watch(string msg, int value)
        {
        }
    }

    class Foo
    {
        int value() { return _value; }

        int value(int v)
        {
            if (v != _value)
            {   _value = v;
                // call all the connected slots with the two parameters
                emit("setting new value", v);
            }
            return v;
        }

        // Mix in all the code we need to make Foo into a signal
        mixin Signal!(string, int);

      private :
        int _value;
    }

    Foo a = new Foo;
    Observer o = new Observer;
    auto o2 = new Observer2;
    auto o3 = new Observer2;
    auto o4 = new Observer2;
    auto o5 = new Observer2;

    a.value = 3;                // should not call o.watch()
    a.connect(&o.watch);        // o.watch is the slot
    a.connect(&o2.watch);
    a.connect(&o3.watch);
    a.connect(&o4.watch);
    a.connect(&o5.watch);
    a.value = 4;                // should call o.watch()
    a.disconnect(&o.watch);     // o.watch is no longer a slot
    a.disconnect(&o3.watch);
    a.disconnect(&o5.watch);
    a.disconnect(&o4.watch);
    a.disconnect(&o2.watch);
    a.value = 5;                // so should not call o.watch()
    a.connect(&o2.watch);
    a.connect(&o.watch);        // connect again
    a.value = 6;                // should call o.watch()
    destroy(o);                 // destroying o should automatically disconnect it
    a.value = 7;                // should not call o.watch()

    assert(observedMessageCounter == 2);
}

// A function whose sole purpose is to get this module linked in
// so the unittest will run.
void linkin() { }

@system unittest
{
    class Observer
    {
        void watch(string msg, int i)
        {
            //writefln("Observed msg '%s' and value %s", msg, i);
            captured_value = i;
            captured_msg   = msg;
        }

        int    captured_value;
        string captured_msg;
    }

    class Foo
    {
        @property int value() { return _value; }

        @property int value(int v)
        {
            if (v != _value)
            {   _value = v;
                emit("setting new value", v);
            }
            return v;
        }

        mixin Signal!(string, int);

      private:
        int _value;
    }

    Foo a = new Foo;
    Observer o = new Observer;

    // check initial condition
    assert(o.captured_value == 0);
    assert(o.captured_msg == "");

    // set a value while no observation is in place
    a.value = 3;
    assert(o.captured_value == 0);
    assert(o.captured_msg == "");

    // connect the watcher and trigger it
    a.connect(&o.watch);
    a.value = 4;
    assert(o.captured_value == 4);
    assert(o.captured_msg == "setting new value");

    // disconnect the watcher and make sure it doesn't trigger
    a.disconnect(&o.watch);
    a.value = 5;
    assert(o.captured_value == 4);
    assert(o.captured_msg == "setting new value");

    // reconnect the watcher and make sure it triggers
    a.connect(&o.watch);
    a.value = 6;
    assert(o.captured_value == 6);
    assert(o.captured_msg == "setting new value");

    // destroy the underlying object and make sure it doesn't cause
    // a crash or other problems
    destroy(o);
    a.value = 7;
}

@system unittest
{
    class Observer
    {
        int    i;
        long   l;
        string str;

        void watchInt(string str, int i)
        {
            this.str = str;
            this.i = i;
        }

        void watchLong(string str, long l)
        {
            this.str = str;
            this.l = l;
        }
    }

    class Bar
    {
        @property void value1(int v)  { s1.emit("str1", v); }
        @property void value2(int v)  { s2.emit("str2", v); }
        @property void value3(long v) { s3.emit("str3", v); }

        mixin Signal!(string, int)  s1;
        mixin Signal!(string, int)  s2;
        mixin Signal!(string, long) s3;
    }

    void test(T)(T a) {
        auto o1 = new Observer;
        auto o2 = new Observer;
        auto o3 = new Observer;

        // connect the watcher and trigger it
        a.s1.connect(&o1.watchInt);
        a.s2.connect(&o2.watchInt);
        a.s3.connect(&o3.watchLong);

        assert(!o1.i && !o1.l && o1.str == null);
        assert(!o2.i && !o2.l && o2.str == null);
        assert(!o3.i && !o3.l && o3.str == null);

        a.value1 = 11;
        assert(o1.i == 11 && !o1.l && o1.str == "str1");
        assert(!o2.i && !o2.l && o2.str == null);
        assert(!o3.i && !o3.l && o3.str == null);
        o1.i = -11; o1.str = "x1";

        a.value2 = 12;
        assert(o1.i == -11 && !o1.l && o1.str == "x1");
        assert(o2.i == 12 && !o2.l && o2.str == "str2");
        assert(!o3.i && !o3.l && o3.str == null);
        o2.i = -12; o2.str = "x2";

        a.value3 = 13;
        assert(o1.i == -11 && !o1.l && o1.str == "x1");
        assert(o2.i == -12 && !o1.l && o2.str == "x2");
        assert(!o3.i && o3.l == 13 && o3.str == "str3");
        o3.l = -13; o3.str = "x3";

        // disconnect the watchers and make sure it doesn't trigger
        a.s1.disconnect(&o1.watchInt);
        a.s2.disconnect(&o2.watchInt);
        a.s3.disconnect(&o3.watchLong);

        a.value1 = 21;
        a.value2 = 22;
        a.value3 = 23;
        assert(o1.i == -11 && !o1.l && o1.str == "x1");
        assert(o2.i == -12 && !o1.l && o2.str == "x2");
        assert(!o3.i && o3.l == -13 && o3.str == "x3");

        // reconnect the watcher and make sure it triggers
        a.s1.connect(&o1.watchInt);
        a.s2.connect(&o2.watchInt);
        a.s3.connect(&o3.watchLong);

        a.value1 = 31;
        a.value2 = 32;
        a.value3 = 33;
        assert(o1.i == 31 && !o1.l && o1.str == "str1");
        assert(o2.i == 32 && !o1.l && o2.str == "str2");
        assert(!o3.i && o3.l == 33 && o3.str == "str3");

        // destroy observers
        destroy(o1);
        destroy(o2);
        destroy(o3);
        a.value1 = 41;
        a.value2 = 42;
        a.value3 = 43;
    }

    test(new Bar);

    class BarDerived: Bar
    {
        @property void value4(int v)  { s4.emit("str4", v); }
        @property void value5(int v)  { s5.emit("str5", v); }
        @property void value6(long v) { s6.emit("str6", v); }

        mixin Signal!(string, int)  s4;
        mixin Signal!(string, int)  s5;
        mixin Signal!(string, long) s6;
    }

    auto a = new BarDerived;

    test!Bar(a);
    test!BarDerived(a);

    auto o4 = new Observer;
    auto o5 = new Observer;
    auto o6 = new Observer;

    // connect the watcher and trigger it
    a.s4.connect(&o4.watchInt);
    a.s5.connect(&o5.watchInt);
    a.s6.connect(&o6.watchLong);

    assert(!o4.i && !o4.l && o4.str == null);
    assert(!o5.i && !o5.l && o5.str == null);
    assert(!o6.i && !o6.l && o6.str == null);

    a.value4 = 44;
    assert(o4.i == 44 && !o4.l && o4.str == "str4");
    assert(!o5.i && !o5.l && o5.str == null);
    assert(!o6.i && !o6.l && o6.str == null);
    o4.i = -44; o4.str = "x4";

    a.value5 = 45;
    assert(o4.i == -44 && !o4.l && o4.str == "x4");
    assert(o5.i == 45 && !o5.l && o5.str == "str5");
    assert(!o6.i && !o6.l && o6.str == null);
    o5.i = -45; o5.str = "x5";

    a.value6 = 46;
    assert(o4.i == -44 && !o4.l && o4.str == "x4");
    assert(o5.i == -45 && !o4.l && o5.str == "x5");
    assert(!o6.i && o6.l == 46 && o6.str == "str6");
    o6.l = -46; o6.str = "x6";

    // disconnect the watchers and make sure it doesn't trigger
    a.s4.disconnect(&o4.watchInt);
    a.s5.disconnect(&o5.watchInt);
    a.s6.disconnect(&o6.watchLong);

    a.value4 = 54;
    a.value5 = 55;
    a.value6 = 56;
    assert(o4.i == -44 && !o4.l && o4.str == "x4");
    assert(o5.i == -45 && !o4.l && o5.str == "x5");
    assert(!o6.i && o6.l == -46 && o6.str == "x6");

    // reconnect the watcher and make sure it triggers
    a.s4.connect(&o4.watchInt);
    a.s5.connect(&o5.watchInt);
    a.s6.connect(&o6.watchLong);

    a.value4 = 64;
    a.value5 = 65;
    a.value6 = 66;
    assert(o4.i == 64 && !o4.l && o4.str == "str4");
    assert(o5.i == 65 && !o4.l && o5.str == "str5");
    assert(!o6.i && o6.l == 66 && o6.str == "str6");

    // destroy observers
    destroy(o4);
    destroy(o5);
    destroy(o6);
    a.value4 = 44;
    a.value5 = 45;
    a.value6 = 46;
}

// Triggers bug from issue 15341
@system unittest
{
    class Observer
    {
       void watch() { }
       void watch2() { }
    }

    class Bar
    {
       mixin Signal!();
    }

   auto a = new Bar;
   auto o = new Observer;

   //Connect both observer methods for the same instance
   a.connect(&o.watch);
   a.connect(&o.watch2); // not connecting watch2() or disconnecting it manually fixes the issue

   //Disconnect a single method of the two
   a.disconnect(&o.watch); // NOT disconnecting watch() fixes the issue

   destroy(o); // destroying o should automatically call unhook and disconnect the slot for watch2
   a.emit(); // should not raise segfault since &o.watch2 is no longer connected
}

version (none) // Disabled because of dmd @@@BUG5028@@@
@system unittest
{
    class A
    {
        mixin Signal!(string, int) s1;
    }

    class B : A
    {
        mixin Signal!(string, int) s2;
    }
}

// Triggers bug from issue 16249
@system unittest
{
    class myLINE
    {
        mixin Signal!( myLINE, int );

        void value( int v )
        {
            if ( v >= 0 ) emit( this, v );
            else          emit( new myLINE, v );
        }
    }

    class Dot
    {
        int value;

        myLINE line_;
        void line( myLINE line_x )
        {
            if ( line_ is line_x ) return;

            if ( line_ !is null )
            {
                line_.disconnect( &watch );
            }
            line_ = line_x;
            line_.connect( &watch );
        }

        void watch( myLINE line_x, int value_x )
        {
            line = line_x;
            value = value_x;
        }
    }

    auto dot1 = new Dot;
    auto dot2 = new Dot;
    auto line = new myLINE;
    dot1.line = line;
    dot2.line = line;

    line.value = 11;
    assert( dot1.value == 11 );
    assert( dot2.value == 11 );

    line.value = -22;
    assert( dot1.value == -22 );
    assert( dot2.value == -22 );
}

