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