Signals and Slots in D

Chad J "gamerChad\" at spamIsBad gmail.com
Thu Sep 28 21:04:06 PDT 2006


Tom S wrote:
> Walter Bright wrote:
> 
>> Ok, before anyone jumps on me, this has all been discussed in 
>> http://www.digitalmars.com/d/archives/28456.html
>>
>> Looks like the deletion problem is a real issue. Let me think about it 
>> a bit.
> 
> 
> could something like this work ?
> 
> 
> // ----
> 
> import std.stdio, std.c.stdlib, std.gc;
> 
> 
> class Observer {
>     this (char[] name) {
>         this.name = name;
>     }
> 
> 
>     void connect(Observee o) {
>         observee = o;
>         o.register(this);
>     }
> 
> 
>     void hear() {
>         writefln("%s hears !", name);
>     }
> 
> 
>     ~this() {
>         writefln("%s goes bye bye", name);
>         if (observee) {
>             observee.unregister(this);
>         }
>     }
> 
> 
> 
>     Observee    observee;
>     char[]        name;
> }
> 
> 
> class Observee {
>     void register(Observer o) {
>         writefln("registering ", o.name);
> 
>         if (observers.length == 0) {
>             observers = (cast(Observer*)malloc(Observer.sizeof))[0..1];
>         } else {
>             observers = (cast(Observer*)realloc(
>                     observers.ptr,
>                     Observer.sizeof * (observers.length+1)
>                 ))[0..observers.length+1];
>         }
>         observers[length-1] = o;
>     }
> 
>     void unregister(Observer o) {
>         writefln("unregistering ", o.name);
> 
>         foreach (i, inout x; observers) {
>             if (x is o) {
>                 x.observee = null;
>                 x = observers[length-1];
>                 observers = observers[0..length-1];
>                 return;
>             }
>         }
>         assert (false);
>     }
> 
>     void shout() {
>         writefln("shouting !");
>         foreach (o; observers) o.hear();
>     }
> 
> 
>     ~this() {
>         foreach (o; observers) delete o;
>     }
> 
> 
>     Observer[]    observers;
> }
> 
> 
> void foo(Observee stuff) {
>     Observer foo1 = new Observer("frisky");
>     Observer foo2 = new Observer("bob");
>     foo1.connect(stuff);
>     foo2.connect(stuff);
> }
> 
> 
> void main() {
>     Observee stuff = new Observee;
>     foo(stuff);
>     float[100] eraseStack;
> 
>     Observer foo3 = new Observer("pat");
>     foo3.connect(stuff);
> 
>     Observer foo4 = new Observer("zomg");
>     foo4.connect(stuff);
>     
>     std.gc.fullCollect();
>     delete foo4;
> 
>     stuff.shout();
>     writefln("exiting");
> }
> 
> 
> // ----
> 
> basically, the registered observers are stored as weak pointers due to 
> the gc not scanning malloc'd memory blocks. if both sides do the 
> unregistration, it seems to work fine...
> 
> 
> 
> -- 
> Tomasz Stachowiak

Couldn't you also do weak pointers by XORing them with 0xFFFFFFFF (or, 
better yet, const size_t weakxor = -1), then XORing again before and 
after you need to operate on them?

Just thought I'd toss that out there.



More information about the Digitalmars-d mailing list