Frege/FregeFX

Support for AnimationTimer

Opened this issue · 3 comments

In order to use javafx.animation.AnimationTimer you have to subclass it and override its handle method. This is not an option if you want to use it directly from frege. So I implemented a 'builder' where you can just pass the function you want to be called on every frame:

data AnimationTimerBuilder = mutable native graphics.AnimationTimerBuilder where
   native from graphics.AnimationTimerBuilder.from :: (Long -> IO ()) -> IO AnimationTimer
import javafx.animation.AnimationTimer;
import frege.prelude.PreludeBase;
import frege.runtime.Lambda;

public class AnimationTimerBuilder {
  public static AnimationTimer from(Lambda handler) {
    return new AnimationTimer() {
      @Override
      public void handle(long arg0) {
        frege.runtime.Delayed.<java.lang.Void>forced(
          PreludeBase.TST.performUnsafe(handler.apply(arg0).result().forced())
        );
      }
    };
  }
}

Now you can use it like this:

do animTimer <- AnimationTimerBuilder.from $ \time -> do
  println "Hi" 
  println time

animTimer.start

If you could add something similar to your fx utils module, I could drop my version.

Dierk commented

Cool, thanks!

My goal was to build sth like https://github.com/Dierk/groovyfx/blob/master/groovyfx/src/demo/groovy/AnimationDemo.groovy

But so we have sth to start with.

Thanks a lot
Dierk

sent from:mobile

Am 08.10.2015 um 09:33 schrieb Daniel Kröni notifications@github.com:

In order to use javafx.animation.AnimationTimer you have to subclass it and override its handle method. This is not an option if you want to use it directly from frege. So I implemented a 'builder' where you can just pass the function you want to be called on every frame:

data AnimationTimerBuilder = mutable native graphics.AnimationTimerBuilder where
native from graphics.AnimationTimerBuilder.from :: (Long -> IO ()) -> IO AnimationTimer
import javafx.animation.AnimationTimer;
import frege.prelude.PreludeBase;
import frege.runtime.Lambda;

public class AnimationTimerBuilder {
public static AnimationTimer from(Lambda handler) {
return new AnimationTimer() {
@OverRide
public void handle(long arg0) {
frege.runtime.Delayed.<java.lang.Void>forced(
PreludeBase.TST.performUnsafe(handler.apply(arg0).result().forced())
);
}
};
}
}
Now you can use it like this:

do animTimer <- AnimationTimerBuilder.from $ \time -> do
println "Hi"
println time

animTimer.start
If you could add something similar to your fx utils module, I could drop my version.


Reply to this email directly or view it on GitHub.

I am wondering why this works. Probably because the forced value is not used and hence no cast is actually done.

Certainly, the cast to java.lang.Void doesn't feel right to me. I would've choosen Object, probably.
In fact, an IO () is under the hood a method that returns (), and the type () is an enumeration, which is currently implemented as a short that indicates the constructor value. Since () is the only constrctor of (), it should always be 0.

You are right. No idea what I was thinking. Void is definitely the wrong choice.