[ create a new paste ] login | about

Link: http://codepad.org/uSEMcD0g    [ raw code | fork ]

D, pasted on Oct 4:
module test;

import std.stdio;
import std.traits;
import std.string;

struct TrackChanges(T)
{
    T payload;
    alias payload this;
    void delegate()[] callbacks;

    void opAssign(T)(T rhs)
    {
        auto oldState = payload;
        this.payload = rhs;
        if (payload != oldState)
            notify();
    }
    
    void opOpAssign(string op, T)(T rhs)
    {
        auto oldState = payload;
        this.payload.opOpAssign!op(rhs);
        if (payload != oldState)
            notify();
    }
    
    auto opDispatch(string method, Args...)(Args args)
    {
        auto oldState = payload;
        
        static if (mixin("is(ReturnType!(T." ~ method ~ ") == void)"))
        {
            mixin("payload." ~ method ~ "(args);");
            if (payload != oldState)
                notify();
        }
        else
        {
            mixin("auto result = payload." ~ method ~ "(args);");
            if (payload != oldState)
                notify();
            return result;
        }
    }
    
    void addListener(void delegate() callback)
    {
        this.callbacks ~= callback;
    }
    
    void notify()
    {
        foreach (fun; callbacks)
        {
            fun();
        }     
    }
}

struct Point 
{ 
    void modify(int val)
    {
        x += val;
        y += val;
    }
    
    string toString() { return format("Point(%s %s)", x, y); }
    
    int x, y; 
}

class Widget
{
    this()
    {
        position.addListener({ writefln("Position changed to: %s", position); });
    }
    
    TrackChanges!Point position;
}

void main()
{
    auto widget = new Widget;
    widget.position = Point(10, 10);
    widget.position = Point(10, 10);
    widget.position.modify(+1);
}


Create a new paste based on this one


Comments: