views:

559

answers:

3

All examples on System.Reactive.dll I've seen so far deal with Events, EventArgs and EventHandlers, I wonder whether someone can show me an example where event notification is handled without this.

For instance, in Microsoft's XNA framework, you have a static method called Mouse.GetState() which will return the current MouseState (with mouseState.LeftButton == ButtonState.Pressed you could see whether the left button is pressed, for instance). So there are no EventArgs, Events etc. in the first place and I think this could serve as an example of achieving event notification without introducing the concept of an event at all.

Could System.Reactive be of help here? Can anyone wrap this into an example with System.Reactive?

+2  A: 

Polling mouse or keyboard states works in a game where you have direct access to update methods that are the heartbeat of the application. The update method IS your event that is called and passed on to many objects, not much different to MouseDown. So even here you do rely on the observer pattern.

galaktor
I know that, but this was a specific question regarding System.Reactive.dll and its IObservable<T>, IObserver<T> interfaces
kitsune
+3  A: 

Quote from an article that I found helpful:

In C#, a programmer uses reactive programming whenever he specifies a call-back for an asynchronous operation or a handler for an event. When the asynchronous operation finishes or when the handled event takes place, a method gets called and executed as a reaction to the event.

Mouse.GetState() is a method that gets the current state of the Mouse. Reactive programming would be useful if you were trying to continuously handle (react to) changes to the state of the mouse.

For example, you could create a wrapper that continuously polls the mouse state, and then notifies its observers (essentially back to publishing events here). You could then write code to handle (react to) those updates.

Nader Shirazie
A: 

You can create Observables from existing events. You can use Observable.FromEvent for this purpose. You may write a GetMouseDown event wrapper like this, as an extension method for a UI Element.

 public static IObservable<Event<MouseButtonEventArgs>> 
                                      GetMouseDown (this UIElement el)
    {                        
     var allevents = Observable.FromEvent<MouseButtonEventHandler, MouseButtonEventArgs>
      (   h => new MouseButtonEventHandler(h), 
       h => el.MouseDown += h, 
       h=> el.MouseDown -= h
       );

     return allevents;            
    }

And later, you may 'handle' your event in a completely declarative manner. Like

//create an observable declaratively
var mouseDowns=button.GetMouseDown(); 
//subcribe and do what ever you need
mouseDowns.Subscribe(arg=> MessageBox.Show(arg.ClickCount.ToString()) );

And here is how to create a 'drag' observable, with the intial position and current position.

  //Get the initial position and dragged points using LINQ to Events
            var mouseDragPoints = from md in e.GetMouseDown()
                                  let startpos=md.EventArgs.GetPosition(e)
                                  from mm in e.GetMouseMove().Until(e.GetMouseUp())
                                  select new
                                  {
                                      StartPos = startpos,
                                      CurrentPos = mm.EventArgs.GetPosition(e),
                                  };


 //And subscribe here to mouseDragPoints

Read this article LINQ to Events - More on .NET Reactive Extensions and play with the source code.

amazedsaint
Note, you can code up your own IObservable and IObserver implementations in C#3.0, but unfortunately you can't use the syntax above for FromEvent, because of the CS1911 warning (http://msdn.microsoft.com/en-us/library/ms228459.aspx)
Benjol