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);
}

Reply via email to