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