Standard Event Driven Object Library for D

Christopher Wright dhasenan at gmail.com
Wed Apr 2 21:44:15 PDT 2008


Brian White wrote:
>> I'm seeing two types of events: notifications and responsibilities.
>>
>> A notification just says "This happened, and I don't care if anyone 
>> reacts to it." std.signals does okay with that, except for a few bits 
>> of ugliness and the fact that it places undesirable dependencies 
>> between objects.
>>
>> A responsibility says "This happened, and someone (but only one) 
>> should take care of it." It might be an error if nobody handles it. 
>> Something can take a look at a responsibility before determining that 
>> it's somebody else's problem.
> 
> That's a good distinction.  The word "event" is too loose.
> 
> 
>> However, I don't see the utility in automatically removing a listener 
>> when it claims that it cannot handle a particular responsibility. Not 
>> handling a particular message and not handling any further messages 
>> are different use cases.
> 
> You could be right.  That's why I want to get other people involved; I 
> can't see everything.  Here was my reasoning...
> 
> When doing embedded controller work, I used a very similar design for 
> passing data up a TCP/IP stack to the app.  During profiling, I found 
> that a significant amount of the CPU time was being spent in the 
> dispatching of i/o events that just got ignored.  By changing the event 
> handlers to say "thanks, but don't send me any more", I was able to save 
> something like 10-15% CPU time.  (Profiling never shows you what you 
> expect.  :-)

Interesting. I suppose in GUI design, one widget will always or never 
want to handle a responsibility. You could return an enum value PassOn, 
Stop, or SendNoMore. And then the library would want to determine which 
to return, and just accept a void delegate for the event handler.

> In the case of a C++ program in a proper operating system, think of the 
> "write" event from a select call.  If you leave it active but write 
> nothing, you'll just get the event again and again and again.  You'll 
> spin CPU instead of letting the OS notify you.
> 
> There are other solutions, of course.  In my C++ library, you had to 
> make a call to clear the "write callback" when you didn't want such 
> events.  That would work it's way down the stack of objects until it 
> cleared the respective bit from the "write" fd_set.  This ended up being 
> somewhat clumsy to implement though because objects are responsible for 
> themselves, it was never anything the library user had to worry about.

A bit easier to manage if you're using singletons, though that doesn't 
work in many cases. Or you could pass in whatever created the event 
along with the event data.

> Instead, I thought I'd take a simpler approach of just requesting "all 
> or nothing" and letting the system take care of turning off those that 
> aren't wanted when they occurred.
> 
> I figured it would also be beneficial to minimize the number of 
> potential loops in the object stack.  If calling "DisableEvent" from 
> within an event handler, you run the risk of that method generating some 
> different event and calling back up the stack yet again.  By returning 
> the status, then any other events generated aren't a loop.

I've had some issues with that in the past. I don't think there is a 
simple solution. Though for GUI stuff, you could often use data binding 
for simple cases.

> In the presence of a proper event queue, loops never happens because the 
> next item on the queue doesn't get processed until the previous one 
> completes.  Using callbacks, however, this is not the case as every 
> "event" is always processed directly and immediately.

What prevents you from adding to the queue an event that will cause this 
event to be added to the queue again?

> -- Brian



More information about the Digitalmars-d mailing list