On 07.07.2010 2:47, BLS wrote:
Okay a bit better snippet than before. snippet should be almost functional..

/*
Hi,
Andrei brings in the idea of std.pattern. Seems that this module is
"stalled";  Unfortunately !
However I would like to enhance collection classes (likewise
dcollections)  with a Publisher - Subscriber pattern (signal - slot, or
observer pattern) , if you prefer)
Hope the idea of enhancing collections with events become clear with the
following snippet.
!!! I am able to spend just a few hours a month with D programming.. in
other words, please don't kill me :)
Untested Draft code which requires a lot of help and ,more important,
feedback from you.

*/

struct publisherMsg(T) {
    T data;
    Action a;
}

mixin template Publisher(T) {
private :

    enum Action = {INSERT, UPDATE, DELETE, READONLY};
    //alias typeof(this) PT;

    struct receiver {
        Object o;
        callback cb;
    }

    receiver[] subscriber;

    publisherMsg!(T) msg;

    alias void delegate(const ref msg) callback;

    void addSubscriber(object o, callback cb) {
        //subscriber ~= o;
    }

    void publish() {
Now where are arguments? kind of  (T t,Action act)
        foreach  (object o ; subscriber)
        {
        // create message and send message

        }
    }
The considerations are still the same :
    foreach(c;subscriber)
        c.callback(
 see my erlier post
}


mixin template Subscriber() {
  // see UndoList for implementation
}

final class Stack(T, bool observable = false ) {
    T[] data;

    static if (observable)    mixin Observable!T;
Yes, I think Observable is more appropriate then Publisher. Then maybe methods should be:
addObserver instead of addSubscriber,
notify instead of publish?
But back to the whole idea - I'm sure you do not want to reimplement all the shiny std.container. What I think we basically need is universal wrapper for _any_ container stuff.
let's call that Observable!Cont. Something like :
final class Observable(Cont){
    Cont cont;
    //here goes your current Publisher stuff
    //...
    alias Cont!ElementType T;
static if(__traits(compiles,cont.insert(T.init)))//some such ... need to test if it has this method
    {
size_t insert(Stuff)(Stuff s){//trouble is - we could insert anything that converts to T
            size_t n = cont.insert(s);
            notify(cast!(T)s,Action.Insert);
        }
    }
   //and all such stuff from std.continer.TotalContainer
    //in theory could even be generated from phobos source
    ....
}
usage :
   alias Observable!(Array!int) observableArray;
    observableArray arr = [ 4,5,6]; //that would be nice
arr.addObserver( (ref msg m){ writeln("arr insertion: ",to!string(m.data,m.action));
    arr.insert(42); //should print that fancy message
    ...
Yes, I still think that plain delegates approach is more flexible and straightforward (see my earlier post).

    void push( T t) {
        data ~= t;
        publish(t, Action.INSERT);
    }
    T pop() {
        publish(t, Action.DELETE);
        //...
    }
    bool empty() {

    }
    T top() {
        publish(t, Action.READONLY);
        //...
    }
    size_t size() {

    }
}
// Undo list will receive every pushed or popped item -data and action)
class UndoList(T) {
    private:
    T[] data;

    /// should be part of the sunscriber mixin templates.
    publisherMsg!T stackMessage;

    void delegate(const ref stackMessage) dg;

    alias Stack!(int) IntegerStack;

    IntegerStack intstack = new IntegerStack;

    private this() {
        dg = &this.feedback;

        // SUBBSCRIBE Stack(T) push and pop events.
        intstack.addSubscriber(this, dg);
Again from my POV it could be:
    intstack.addSubcriber(
        (const ref stackMessage msg){ feedback(msg); }
    );
//somewhat scary in this case, but in fact it does not restrict you to class instances.

    }
    public void feedback(const ref stackMessage msg ) {
        writefln("Action");
    }
}
BTW I'm definitely interesed in this effort, and in fact want that kind of functionality for my upcoming gui lib.
It all just needs to be more reusable and flexible.

--
Dmitry Olshansky

Reply via email to