A tutorial on D templates: updates

bls bizprac at orange.fr
Mon Jan 30 13:14:26 PST 2012


Hi Philippe,
Ok, something more interesting it combines suggestion 2)  and 3). Still 
a quick hack, not much tested, but I think the intention is clear.

The snippets show how a publisher subscriber pattern can be mixed in. 
Further it shows how a simple class could become a stack, queue, list etc.
The FooMixin was just to show (due to a question on D.Learn), how we can 
mimic partial C# classes.

import std.stdio;
import std.cstream;
import std.functional;

void main(string[] args)
{
	auto  p = new PersonStack();
	
	p.add("Hans", 42);// uses MIStack push(), MISubScriber notify()
	din.getc();
}

mixin template MIPublisher()
{
	alias void delegate(Object sender, string event) CallBack;
	CallBack[] callBacks;

	public void register(CallBack callBack)
	{
		callBacks ~= callBack;
	}

	// There is for sure a smarter solution to remove
	public void unRegister(CallBack callBack)
	{
		for ( int i=0 ; !i<callBacks.length ; i++ )
		{
			if (callBacks[i] == callBack)
			{
				callBacks = callBacks[0..i] ~ callBacks[i+1..callBacks.length];
				--i;
			}
		}
	}
	// Notify ALL Subscribers
	public void notify(string evt)
	{
		
		foreach ( CallBack callBack ; callBacks )
		{
			callBack( this, evt );
		}
	}
}

mixin template MIStack()
{
	alias typeof(this) Me;
	//alias Me[] Us;
	static Me[] stack;
	
	
	public:
	
	bool empty()
	{
		return stack.length == 0;
	}
	
	int count()
	{
		return stack.length;
	}
	
	void push(Me element)
	{
		stack ~= element;
	}
	
	Me pop()
	{
		Me element = peek();
		stack.length = stack.length - 1;
		return element;
	}
	
	Me peek()
	{
		if ( stack.length == 0 )
		{
			// throw error
		}
		Me element = stack[stack.length-1];
		return element;
	}
}


	
class PersonStack
{
	private string name;
	private int age;
	
	// Our Mixins
	mixin MIStack;
	mixin MIPublisher;
		
	this()
	{
		// Register some subscribers (MIPublisher register function)
		// I have used free functions to show the useful toDelegate()
		register( toDelegate(&DrawPersonBarChart) ); 	
		register( toDelegate(&DrawPersonPieChart) ); 	
	}
	
	// Push
	void add(string name, int age)
	{
		this.name = name;
		this.age = age;
		// Push Person (MIStack push function.)
		push(this);
		
		// Notify all subscribers		
		notify("Push");
			
	}
	// remove()
}

//Subscriber free functions
void DrawPersonBarChart(Object sender, string msg)
{
	writeln("Bar " ~ msg);
}
void DrawPersonPieChart(Object sender, string msg)
{
	writeln("Pie " ~ msg);
}


More information about the Digitalmars-d-announce mailing list