Signals and Slots in D

Tom S h3r3tic at remove.mat.uni.torun.pl
Thu Sep 28 20:50:52 PDT 2006


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



More information about the Digitalmars-d mailing list