|
Archives
D Programming
DD.gnu digitalmars.D digitalmars.D.bugs digitalmars.D.dtl digitalmars.D.ide digitalmars.D.dwt digitalmars.D.announce digitalmars.D.learn digitalmars.D.debugger C/C++ Programming
c++c++.announce c++.atl c++.beta c++.chat c++.command-line c++.dos c++.dos.16-bits c++.dos.32-bits c++.idde c++.mfc c++.rtl c++.stl c++.stl.hp c++.stl.port c++.stl.sgi c++.stlsoft c++.windows c++.windows.16-bits c++.windows.32-bits c++.wxwindows digitalmars.empire digitalmars.DMDScript electronics |
digitalmars.D.dwt - Few thoughts
I have used DWT for some days and here are my thoughts:
"" must be the same as null . Feels more natural in D.
Adding listeners is unnatural too. addListener(...,new class Listener(void
handleEvent(Event e){..}})); .... come on.. I have brought this up about
Tioport too. I think DwtShawn's way is the right one. I can contribute some
code. Multi handlers would be general handler for multiple type of events (ie
Event). SingleHandlers could be used for non-general events that are used in
some places:
class MultiHandlers(EVENTYPE=uint,RETURNTYPE=bool,DELEGATE...)
{
struct HANDLER
{
RETURNTYPE delegate(DELEGATE,Object) dg;
Object param;
}
bool add(EVENTYPE event,RETURNTYPE delegate(DELEGATE,Object) dg,Object
param=null)
{
if(!dg) return false;
auto a=event in handlers;
if(a) *a~=HANDLER(dg,param);
else handlers[event]=[HANDLER(dg,param)];
return true;
}
void del(EVENTYPE event){handlers.remove(event);}
bool del(EVENTYPE event,RETURNTYPE delegate(DELEGATE,Object) dg)
{
if(!dg) return false;
auto a=event in handlers;
if(a)
{
foreach(i,d;*a)
{
if(d.dg is dg)
{
if((*a).length==1) handlers.remove(event);
else
{
if(i==0) *a=(*a)[1..$];
else if(i==(*a).length-1) *a=(*a)[0..i];
else *a=(*a)[0..i]~(*a)[i+1..$];
return true;
}
}
}
}
return false;
}
bool toggle(EVENTYPE event,RETURNTYPE delegate(DELEGATE,Object) dg)
{
if(!del(event,dg)) return add(event,dg);
}
bool call(EVENTYPE event,DELEGATE data)
{
auto a=event in handlers;
if(a)
{
static if(is(RETURNTYPE == void)) foreach(d;*a)
{
static if(data.length)
{
data[0].param=d.param;
scope(exit) data[0].param=null;
}
d.dg(data);
}
else foreach(d;*a)
{
static if(data.length)
{
data[0].param=d.param;
scope(exit) data[0].param=null;
}
if(d.dg(data)) return true;
}
}
return false;
}
bool canHandle(EVENTYPE event){return (event in handlers) !is null;}
//protected:
HANDLER[][EVENTYPE] handlers;
}
class SingleHandlers(RETURNTYPE=bool,DATA...)
{
struct HANDLER
{
RETURNTYPE delegate(DATA) dg;
Object param;
}
bool add(RETURNTYPE delegate(DATA) dg,Object param=null)
{
if(!dg) return false;
handlers~=HANDLER(dg,param);
return true;
}
void del(){delete handlers; handlers=null;}
bool del(RETURNTYPE delegate(DATA) dg)
{
if(!dg) return false;
tango.core.Array.removeIf(/*pseudo code*/ {foreach(h;handlers) h.dg is dg;} )
}
bool toggle(RETURNTYPE delegate(DATA) dg)
{
if(!del(dg)) return add(dg);
}
bool call(DATA data)
{
static if(is(RETURNTYPE == void)) foreach(d;handlers)
{
static if(data.length)
{
data[0].param=d.param;
scope(exit) data[0].param=null;
}
d.dg(data);
}
else foreach(d;handlers)
{
static if(data.length)
{
data[0].param=d.param;
scope(exit) data[0].param=null;
}
if(d.dg(data)) return true;
}
return false;
}
//protected:
HANDLER[] handlers;
}
add something like in Widget (and where appropriate)
MultiHandlers!(int,void,Event) mHandlers;
bool handleEvent(void delegate(Event) dg,Object param=null)
{
if(mHandlers is null) mHandlers=new MultiHandlers!(int,void,Event);
return mHandlers.add(dg,param);
}
bool unhandleEvent(void delegate(Event) dg)
{
if(mHandlers) return mHandlers.del(dg);
return false;
}
These things (or something similar) could be mixed in to keep the changes from
SWT minimal and be easier to port and share the stuff between linux/windows.
The rest is to mess with the code where event comes add do something like
if(mHandlers && mHandlers.canHandle(type)) mHandlers.call(type);
The easy way is to add filter in the display but this is kind of ugly...
Anyway this is just a suggestion.
Mar 03 2008
And what I wrote about the listeners also apply to Runnable. Mar 03 2008
Oh, and dwt.internal.win32.WINAPI.TIMERPROC should be alias VOID function(HWND, UINT, UINT, DWORD) TIMERPROC; not alias VOID function(HWND, UINT, UINT) TIMERPROC; Seems that it is not used anyway... Mar 03 2008
Yes i think you are right, i was trying to get around that for some time :) Can we make use of tango.core.Signal here ? Are you interested in doing the implementation in dwt-win & dwt-linux ? Mar 04 2008
Frank Benoit Wrote:Yes i think you are right, i was trying to get around that for some time :) Can we make use of tango.core.Signal here ? Mar 04 2008
Frank Benoit schrieb:Yes i think you are right, i was trying to get around that for some time :) Can we make use of tango.core.Signal here ? Mar 09 2008
Bjoern schrieb:The forum thread at : http://www.dsource.org/projects/tango/forums/topic/221 Mar 09 2008
|