May 18, 2008
BLS wrote:
> Frank Benoit schrieb:
>> I added the template function Bill suggested once to the dwt.widgets.Listener module.
>>
>> http://www.dsource.org/projects/dwt-linux/browser/dwt/widgets/Listener.d?rev=243%3A84629474b5ec 
>>
>>
>> You can see that in action in this snippet
>> http://www.dsource.org/projects/dwt-samples/browser/snippets/treeeditor/Snippet111.d?rev=85%3Afa286c85e7b8 
>>
>>
>> See lines: 102..106
>>
>> Thanks Bill for the snippets and for this cool template function suggestion.
>>
>> Frank
> 
> Hi Frank, thanks for the update !
> 
> I still try to figure out how this code could fit ...
> 
> template MessageMap(Mappings ...) {
>   void addListener(uint uID) {
>      foreach(mapping; Mappings) {
>        if(mapping.matches(uID)) // DWTxxxx
>          mapping.executeAction();
>      }
>   }
> }
> 
> //maybe we need template specialisation here ???
> 
> 
> struct OnClose(alias fn) {
>   alias fn executeAction;
>   static bool matches(uint uid) { return uid == 5; }
> }
> 
> struct OnRange(uint a, uint b, alias fn) {
>   alias fn executeAction;
>   static bool matches(uint uid) { return uid >= a && uid <= b; }
> }
> 
> 
> class Foo {
>   void foo() {
>     writefln("foo called");
>   }
>   void bar() {
>     writefln("bar called");
>   }
> 
>   mixin MessageMap!(
>     OnClose!(foo),
>     OnRange!(1, 3, bar)
>   );
> 
> }
> 
> void main() {
>   auto f = new Foo;
>   f.addListener(5);
>   f.addListener(2);
> }
> 
> At least it looks simpler (to me) Ideas ? Bjoern

I don't get it.  What's 5?

--bb
May 19, 2008
Bill Baxter schrieb:
> BLS wrote:
>> Frank Benoit schrieb:
>>> I added the template function Bill suggested once to the dwt.widgets.Listener module.
>>>
>>> http://www.dsource.org/projects/dwt-linux/browser/dwt/widgets/Listener.d?rev=243%3A84629474b5ec 
>>>
>>>
>>> You can see that in action in this snippet
>>> http://www.dsource.org/projects/dwt-samples/browser/snippets/treeeditor/Snippet111.d?rev=85%3Afa286c85e7b8 
>>>
>>>
>>> See lines: 102..106
>>>
>>> Thanks Bill for the snippets and for this cool template function suggestion.
>>>
>>> Frank
>>
>> Hi Frank, thanks for the update !
>>
>> I still try to figure out how this code could fit ...
>>
>> template MessageMap(Mappings ...) {
>>   void addListener(uint uID) {
>>      foreach(mapping; Mappings) {
>>        if(mapping.matches(uID)) // DWTxxxx
>>          mapping.executeAction();
>>      }
>>   }
>> }
>>
>> //maybe we need template specialisation here ???
>>
>>
>> struct OnClose(alias fn) {
>>   alias fn executeAction;
>>   static bool matches(uint uid) { return uid == 5; }
>> }
>>
>> struct OnRange(uint a, uint b, alias fn) {
>>   alias fn executeAction;
>>   static bool matches(uint uid) { return uid >= a && uid <= b; }
>> }
>>
>>
>> class Foo {
>>   void foo() {
>>     writefln("foo called");
>>   }
>>   void bar() {
>>     writefln("bar called");
>>   }
>>
>>   mixin MessageMap!(
>>     OnClose!(foo),
>>     OnRange!(1, 3, bar)
>>   );
>>
>> }
>>
>> void main() {
>>   auto f = new Foo;
>>   f.addListener(5);
>>   f.addListener(2);
>> }
>>
>> At least it looks simpler (to me) Ideas ? Bjoern
> 
> I don't get it.  What's 5?
> 
> --bb

I wrote the first reply before I had my first coffee. Bad idea :)

A better, annotated sample :


template MessageMap(Mappings ...) {
  void addListener(uint uID) {
     foreach(mapping; Mappings) {
       if(mapping.matches(uID)) // DWTxxxx
         mapping.executeAction();
     }
  }
}

/*
Defining a few templated structs.
The structs (not instances of them, the actual type!) are
given to MessageMap which calls the *static* function(s).

So technically, OnFocusOut!(FocusOut) and OnRange!(1, 3, Range) are *types* that contain aliases (think of compile time references) to the methods you want to call.
*/

struct OnFocusOut(alias fn) {
  alias fn executeAction;
  static bool matches(uint uid) { return uid == DWT.FocusOut; }
}

// just an other sample
struct OnRange(uint a, uint b, alias fn) {
  alias fn executeAction;
  static bool matches(uint uid) { return uid >= a && uid <= b; }
}

class Window {
  void FocusOut() {
    writefln("DWT.FocusOut event");
  }
  void Range() {
    writefln("OnRange called");
  }

  mixin MessageMap!(
    OnFocusOut!(FocusOut),
    OnRange!(1, 3, Range)
  );


/*
This mixin expands to :

  void addListener(uint uID) {
     foreach(mapping; Mappings) { //loops 2 times -> see Mixin
       if(mapping.matches(uID))   //just like "if (uID == DWT.FocusOut)"
         mapping.executeAction(); //calls  alias fn -> see structs
     }
  }
}

The "mixin MessageMap!(...)" simply adds a new method to your class.
Note that because it is run over types, the "foreach(mapping; Mappings)
{ .. }" is done at compile time, ie its body is repeated for every type
(I called them Mapping's here), so all runtime overhead you have are
the ifs that evaluate to false.
*/

void main() {
  auto w = new Window;
  w.addListener(DWT.FocusOut);
  w.addListener(DWT.WhatEver);
}


This is an attemp to create something similar to MFCs
BEGIN_MESSAGE_MAP / END_MESSAGE_MAP

I am NOT sure how this snippet could fit into DWTs event management.
It is just an idea. :(

Finally : I guess template specialisation seems to be neessesary to support events that return a value ......
Bjoern
May 19, 2008
Sorry! just had a closer look at the DWT event-handling.
My snippet is off topic.
Bjoern (ashamed)
1 2
Next ›   Last »