Geek-o-Philiac

Sunday, September 03, 2006

Services/Subscribers

This isn't so much XNA as it is .NET in general, but I feel it's pertinent since it's related to me trying to get XNA to treat input in an event-driven way as opposed to using a polling mechanism.

I've been struggling a bit with delegates and the whole service/subscriber paradigm as used in .NET. Not the implementation - that's trivial - but the true benefits of their method versus my old habits. I'm used to having a service provider which is responsible for registering and unregistering subscribers and then sending events to the subscriber via calling an interfaced method. I'm not used to the subscribers registering/unregistering themselves by adding a delegate to the service provider. At first, I thought this second method would increase coupling by binding the subscriber to the service and then binding the service to the subscriber, but that's not really what's happening here. The provider doesn't care about the nature of the subscriber so long as the delegate has been added to it - any changes to the internals of the subscriber will be completely transparent. It seems that changes to the internals of the provider may require a change in the subscriber, and thus you've simply reversed the nature of your coupling from the first method, where a change in the provider was transparent to the subscriber but the opposite may not be true.
So I've been banging my head against a wall, trying to figure out why exactly everyone seems to prefer the .NET method. It could be simply that that's how the .NET documentation recommends developers so that they conform to the .NET standard of doing things, or there could be some clear benefit I'm missing. Clarification would be appreciated.

I've found one scenario where I can't find a simple implementation in .NET, and I have thus gone to my method. The problem is that I'd like to have one service provider that is speed-efficient and can easily handle multiple types of events. Having to add a new event type to my provider each time I recognized a new game event sounded extremely cumbersome. Further, having one event type store all my delegates did not seem efficient - the event would end up being sent to all listeners, even if those listeners were not interested in the specific type of event. My solution is to have a Dictionary mapping a Type to a List of GameEventSubscribers. When a subscriber is subscribed, it subscribes to a specific Type. When an event is posted, only that list of GameEventSubscribers that is actually listening for the specific event type gets notified.
The system has one apparent flaw, and that is it's not 100% type safe when registering/unregistering a listener. You can register a listener to any type, not just types that derive from GameEvent. PostEvent only takes a GameEvent, so those listeners will never receive something else, but it would be nice to prevent them ever registering themselves to, say, System.Generic (because some stupid programmer will try it). A simple solution I can see is to just throw an exception when someone tries something like that, which is easy enough, I suppose.

I know my meaning is not entirely apparent, and it'd be a lot easier to explain with source code. I did look for methods to post source code here, but I still haven't found anything good yet. Hopefully some golden knight will appear and offer a solution, and these updates can be a little clearer/more informative.

0 Comments:

Post a Comment

<< Home