DWT event handling

BLS nanali at nospam-wanadoo.fr
Mon May 19 01:11:23 PDT 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


More information about the Digitalmars-d-dwt mailing list