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

2010-07-08 Thread BLS

@ Dmitry
Thanks for all the feedback Dmitry. Seems that we have similar projects 
in mind :) (maybe we can talk about the GUI project.. mine is similar to 
win32++ at http://sourceforge.net/projects/win32-framework/)



However : Like you I would prefer to use something like ..

void delegate(const ref message) CallBack;
CallBack[] cb;
@Jakob
Adding some delegates to our list (D dyn. array) like in C# is a piece 
of cake..


But keep in  mind that we also need  removeObserver() in order to 
implement the Observer pattern.  And removing makes the difference.


The question is now :
How do we identify our Observer object in order to remove..
possible solutions :

1) passing the object instance to the mixin template. (as shown in my 
code) adding of course a : toHash() method.

2)
adding a GUID to the delegate..
3)
...

Dmitry, I think

YOUR :

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

SOLUTION

is very hackish. (Beside, like IsForwardRange!R )

IMHO a mixin template is a more clean solution.

BUT this requires that container/collection classes are not final.

Well, even for final classes there is still the option to implement a 
decorator pattern! But the decorator pattern makes code quite unreadable...


However, ATM I am thinking about how we can you use std.concurrent 
message passing stuff...


Finally
Would be nice if we can write a few LOC together! ??
bjoern
PS Sure the Publisher/Observable mixin has to work for structs too.





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

2010-07-07 Thread Rory McGuire

On Wed, 07 Jul 2010 00:47:32 +0200, BLS windev...@hotmail.de 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() {
foreach  (object o ; subscriber)
{
// create message and send message

}
}   
}

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

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

static if (observable)  mixin Observable!T;

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);

}
public void feedback(const ref stackMessage msg ) {
writefln(Action);
}
}


Hi Bjoern,

your mixin template should have private { ... } rather than private: I  
believe the current way will make

everything that uses the mixin template private after its used.


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

2010-07-07 Thread Dmitry Olshansky

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



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

2010-07-07 Thread Jacob Carlborg

On 2010-07-07 10.48, Dmitry Olshansky wrote:

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.


I think it would be nice to simulate the events in C#. It's quite easy, 
just a struct containing a linked list of delegates, a function to call 
all the delegates and functions to add and remove delegates from the list.



--
Jacob Carlborg


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

2010-07-07 Thread Dmitry Olshansky

On 07.07.2010 14:54, Jacob Carlborg wrote:

On 2010-07-07 10.48, Dmitry Olshansky wrote:

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.


I think it would be nice to simulate the events in C#. It's quite 
easy, just a struct containing a linked list of delegates, a function 
to call all the delegates and functions to add and remove delegates 
from the list.


Never actually used C#, but I'm doing something alike, just with built 
in array instead of list, given the fact that number of callbacks is 
usually well under 100, it's should be faster and waste less space. I'll 
upload my efforts on dsource, when it's finally usable.


--
Dmitry Olshansky



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

2010-07-06 Thread Dmitry Olshansky

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


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

2010-07-06 Thread BLS
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() {
foreach  (object o ; subscriber)
{
// create message and send message

}
}   
}

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

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

static if (observable)  mixin Observable!T;

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);

}
public void feedback(const ref stackMessage msg ) {
writefln(Action);
}
}


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

2010-07-06 Thread BLS

Hi Dimitry, thanks for the feedback!
Please have a look at the new snippet (just posted)

msg is a ref parameter cause it is filled in our example from Stack. The 
Publisher mixin HOST.



In other words. Where ever you mixin the Publisher template a message 
will be broad casted to all subscribers containing 2 information.

1 ) a value of type T, and an enum value INSERT, DELETE etc...

will read your comments tomorrow more carefully.. have to sleep now.)

bjoern