[Question] About mixin, template and alias
Michael
pr at m1xa.com
Mon Sep 23 12:47:30 PDT 2013
Code below shows that I would achieve:
///// fire.d
alias void delegate() EventHandler;
class Event(T)
{
private T[] _events;
public void opOpAssign(string op)(T param) if (op == "~")
{
_events ~= param;
}
public void opCall(ParamType ...)(ParamType params)
{
this.emit(params);
}
protected void emit(ParamType ...)(ParamType params)
{
foreach (event; _events)
event(params);
}
}
mixin template AddEvent(DelegateType, string member)
{
private Event!DelegateType _eventObserver;
@property auto get()
{
if (_eventObserver is null)
_eventObserver = new Event!DelegateType();
return _eventObserver;
}
void doEventObserver(ParamType ...)(ParamType params)
{
mixin (member ~ "()(params);");
}
mixin ("alias get " ~ member ~ ";");
mixin ("alias doEventObserver do" ~ member ~ ";");
}
class Fire
{
public mixin AddEvent!(EventHandler, "click");
}
class DoubleFire
{
private Event!EventHandler _click;
public this()
{
_click = new Event!EventHandler();
}
@property public Event!EventHandler click()
{
return _click;
}
public void doClick(ParamType ...)(ParamType params)
{
click()(params);
}
}
///// water.d
import std.stdio;
import fire;
class Water : Fire
{
}
void main()
{
Fire element;
element = new Fire();
element.click ~= () { writeln("Fire!"); };
element.click()(); // Not needed with DIP 23
element = new Water();
element.click ~= () { writeln("Water!"); };
element.click()(); // Not needed with DIP 23
DoubleFire df = new DoubleFire();
df.click ~= () { writeln("Double Fire!"); };
df.doClick(); // Workaround
element.doclick(); // Workaround
}
///// Output
Fire!
Water!
Double Fire!
Water!
Thanks)
More information about the Digitalmars-d-learn
mailing list