www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - register mixin

reply Frank Benoit <keinfarbton nospam.xyz> writes:
/**/   // I want to use mixin very compact, like this:
/**/
/**/   class Speed : Signal!(int){
/**/     mixin Scaling( 0, 1.23, "km/h") scale_kmh;
/**/     mixin NamedRange( 100, 200, "HIGH SPEED" ) highSpeed;
/**/     mixin NamedValue( 250, "MAX" ) maxSpeed;
/**/   }
/**/
/**/   Speed speed = new Speed;
/**/   // set the internal 'Signal!(int).mValue'
/**/   // variable to a scaled value
/**/   speed.scaled_kmh.setValue( 250 );
/**/   // set the internal 'Signal!(int).mValue' variable to 250
/**/   speed.maxSpeed.set();
/**/
/**/   // So far no problem i think.
/**/
/**/   // And now I want the way back:
/**/   // Each mixin should register a class or delegate or ...
/**/   // to give the Signal class the possibility to find the
/**/   // Label "MAX" or print the scaled "km/h"
/**/
/**/   class Signal(T){
/**/     // ....
/**/     public char[] toString(){
/**/       char[] result;
/**/       foreach( SomeThing st; list ){
/**/         result ~= st.toString( mValue );
/**/       }
/**/       return result;
/**/     }
/**/     // ....
/**/   }
/**/

/*******************************/
/*     Is there any way?       */
/*******************************/
Apr 13 2006
next sibling parent Frank Benoit <keinfarbton nospam.xyz> writes:
A solution I though about was this:

/**/   class Speed : Signal!(int){
/**/     mixin Scaling   ( 0, 0, 1.23, "km/h") scale_kmh;
/**/     mixin NamedRange( 1, 100, 200, "HIGH SPEED" ) highSpeed;
/**/     mixin NamedValue( 2, 250, "MAX" ) maxSpeed;
/**/     mixin Impl      ( 3 );
/**/   }

One possiblity is to have and incrementing index in each mixin. Every
mixin creates a member variable containing the index. This can be done
with many static if:

static if( idx == 0 ){
	private Type getMixin0(){};
}
static if( idx == 1 ){
	private Type getMixin1(){};
}
static if( idx == 2 ){
	private Type getMixin2(){};
}
// ....

And than have an additional Impl mixin, which gets the count of
preceding mixins. It is implemented with a number of static if in the
constructor:

static if( count >= 1 ){
	list.append( getmMixin0() );
}
static if( count >= 2 ){
	list.append( getmMixin1() );
}
static if( count >= 3 ){
	list.append( getMixin2() );
}
// ....


Disadvantages:
* ugly
* upper limit for mixins
* manual indexing of the mixins + potential error
Apr 13 2006
prev sibling parent Frank Benoit <keinfarbton nospam.xyz> writes:
Perhaps for someone interesting...

Let the templates have a static constructor.
But I don't know if this is specified behaviour?

It works, if each mixin is a named mixin.
Then there are no linker errors. They are called in the sequence the
mixin appear in source. In these static constructor, it is possible to
make a registration in static class variables.
Apr 13 2006