SodiumFRP / sodium

Sodium - Functional Reactive Programming (FRP) Library for multiple languages
http://sodium.nz/
Other
848 stars 138 forks source link

C# continuous times samples: not running smoothly #86

Closed ziriax closed 8 years ago

ziriax commented 8 years ago

I started the bounce example, and the ball was bouncing, but the animation was not synchronized with the screen's refresh rate, resulting in rather jerky motion.

Changing the 'Animation.RunAnimation' code into

        public static void RunAnimation(Animate animate)
        {
            CompositionTarget.Rendering += (sender, args) => animate.InvalidateVisual();
        }

makes it much smoother, with less code as a bonus.

But it's not perfect yet. I suspect this is because

  1. The samples also use an TimerSystem that uses a system timer, and that time doesn't have high precision, and does not run in sync with the CompositionTarget
  2. The integrate does not seem to take time into account, so it does not adapt to different frame-rates
  3. To be really perfect, integration and other time dependent primitives should also estimate the delta-time of the next-frame, by looking at the history of the previous delta-times, but that is most likely overkill ;-)
  4. Windows is not a real-time gaming system ;-)
jam40jeff commented 8 years ago

Fixed with commits:

ab9b0ccd700794ab850bdd94ea99e61e520383df d3f9b8256d991bc3f13260ee1a5b0e22ba6420b4 592c78104741894ef9beb6071739f18b8b044e2a

Thanks for catching that. That's what I get for directly porting the Java code for the Animate class with no thought! The bounce is much smoother when using the Render event of CompositionTarget, as you said.

As for the other issues:

(1) I implemented a CompositionTarget timer system that uses the RenderingTime passed to the Render event as the "current time" for each frame render, which should be more accurate than using the system clock (although to the naked eye it's hard to tell a difference).

(2) Integrate does seem to take time into account. You can see this by adding a Thread.Sleep with a random amount of time into one of the calculations run each time a frame is rendered. The trajectory will be correct (although choppy).

(3) I don't think this is necessary now that the timer system is using the CompositionTarget event's time (which I believe takes into account the expected frame rate).

(4) True, but I think it's more WPF that is at fault than Windows.

ziriax commented 8 years ago

Thanks a lot! So you also now about the hidden RenderingEventArgs ;-)

Strange that I missed the time steps in the Integral, I must check again, I am curious how this is done.

Yes WPF is a slow beast. It would be interesting to port the samples to Xamarin and NoesisGUI on all platforms :-)

PS: Another thing I am working on, is easy MVVM with Sodium. I have a first example working. The SWidgets are nice, but for a real WPF app, you will want MVVM with XAML bindings no? But, this is another issue..

jam40jeff commented 8 years ago

I hate when Microsoft does things like that. If RenderingEventArgs is a public class and the event will always pass an instance of it, why not type the event handler correctly? It makes no sense.

I am interested in seeing what you have done with your MVVM solution. I was actually planning on replacing my RxMvvm repo with a SodiumMvvm one, but if you have something put together already, then I won't have to.

ziriax commented 8 years ago

I don't have anything special in mind, expect using T4 templates to generate the boilerplate code that converts bidirectional properties in the view-model to a pullable Cell (for reading the property) and pushable Stream (to push the user changes), and commands to a pullable Cell (for the CanExecute) and pushable Stream (to push the user actions). The inputs are converted to outputs by a Sodium circuit. That's the only thing for now, I want to keep it very minimal.

the-real-blackh commented 8 years ago

Please host SodiumMVVM in SodiumFRP if you would like to. You should have privileges to create repos now. Also, if you want to, feel free to separate sodium-C# out into a separate repo. I'm planning to do this with C++.