std.pattern.. templated publisher subscriber pattern, adding events to collections

Dmitry Olshansky dmitry.olsh at gmail.com
Tue Jul 6 15:35:23 PDT 2010


On 07.07.2010 2:01, BLS wrote:
> 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.
Will do, probably both :)
>
> 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;
> // opCall() or this() ?
> }
>
Why not just use plain delegate instead of pair Object,callback?
The object itself  could be bound like this:

struct MyObject{ string name; }
MyObject mb = MyObject("test");
callback c = (ref msg m){
	if(msg.action == INSERT)
		writeln("inserted " ~ mb.name);
	//....
};

And better yet it's real type is known inside delegate at binding point.
Not sure why msg is ref parameter? So that one subscriber can affect msg 
that will in turn see another one  - seems weird.

> receiver[] subscriber;
>
> publisherMsg!(T) msg;
>
> alias void delegate(ref msg) callback;
>
> void addSubscriber(object o, callback cb) {
> //subscriber ~= o;
> }
>
ditto.
> void publish(T t, Action act) {
> foreach (object o ; subscriber)
> {
> // create and send message
>
> }
> }
> }
and then maybe just call all  delegates with msg(t,act)?
>
> mixin template Subscriber() {
> // see UndoList
> }
>
> final class Stack(T, bool observable = false ) /+ should use alias +/ {
> T[] data;
> static if (observable) mixin Observable!T;
>
> void push(T t) {
> publish(t, Action.INSERT)
> }
> T pop() {
>
> }
> bool empty() {
>
> }
> T top() {
>
> }
> size_t size() {
>
> }
> }
>
>
> /// Undo list will receive every pushed or popped item (T and Action)
> class UndoList(T) {
> private:
> T[] data;
>
> // should be part of the subscriber mixin template.
> publisherMsg!T stackMessage;
>
> void delegate(ref stackMessage) dg;
>
> alias Stack!(int) IntegerStack;
> IntegerStack intstack = new IntegerStack;
>
> private this() {
> dg = &this.feedback;
>
> }
> public void feedback(ref stackMessage msg ) {
> writefln("push or pop action");
> }
>
> }
> -Bjoern


-- 
Dmitry Olshansky


More information about the Digitalmars-d-learn mailing list