Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to sequence effects with flare UI? #14

Closed
joelgrus opened this issue Mar 22, 2016 · 11 comments
Closed

how to sequence effects with flare UI? #14

joelgrus opened this issue Mar 22, 2016 · 11 comments

Comments

@joelgrus
Copy link

Say I would like a slider to choose a number n and then plot n random points.

I can do this easily if the points are deterministic, but once they're random I need to generate them in an Eff (random :: RANDOM | e) context, and it's not obvious to me how to sequence that with the UI applicative. (I tried a number of things, but none of them worked.)

See example (and non-example): https://gist.github.com/joelgrus/b27c12fc159367ea2440

I hope this is the right venue to ask this kind of question. Thanks!

@sharkdp
Copy link
Owner

sharkdp commented Mar 22, 2016

I hope this is the right venue to ask this kind of question.

Sure!

As you pointed out, the issue is that runFlareDrawing expects a UI Drawing, i.e. some interface that produces a pure value (a Drawing). As you have to run an effectful computation to generate that Drawing, you cannot use runFlareDrawing.

You can solve this by using runFlareWith instead (in your case, a = Int):

runFlareWith :: forall e. ElementId
             -> (a -> Eff (dom :: DOM, channel :: CHANNEL | e) Unit)
             -> UI e a
             -> Eff (dom :: DOM, channel :: CHANNEL | e) Unit

As the second argument, this expects a custom function that can run any effectful computation (for you, eff includes RANDOM and Canvas). You can provide your own rendering function, something like:

drawRandomPoints :: forall eff. Context2D
                 -> Int
                 -> Eff (random :: RANDOM, canvas :: Canvas | eff) Unit
drawRandomPoints ctx n = do
  clearRect ctx { x: 0.0, y: 0.0, w: width, h: height }

  drawing <- randomPoints n
  render ctx drawing

Finally, in your main function, you would call runFlareWith instead:

main = do
  Just canvas <- getCanvasElementById "canvas"
  ctx <- getContext2D canvas

  let ui = intRange "numPoints" 1 100 10

  runFlareWith "controls" (drawRandomPoints ctx) ui

You can try it out here: http://sharkdp.github.io/try-flare/?gist=bdb4548abb6103be3e2a

@sharkdp
Copy link
Owner

sharkdp commented May 8, 2016

@joelgrus
Can this be closed?

@oblitum
Copy link
Contributor

oblitum commented Jun 16, 2016

Question and answer were very helpful.

@oblitum
Copy link
Contributor

oblitum commented Jun 17, 2016

An updated sample for this using latest purescript would be nice to have.

@oblitum
Copy link
Contributor

oblitum commented Jun 17, 2016

I've added it as example 17 in this gist: https://gist.github.com/oblitum/90cbf5338f55321a9d975f0588a711cd

@oblitum
Copy link
Contributor

oblitum commented Jun 21, 2016

I've finished a more complete sample which I incorporated in a blog post, it's still small:

You may feel free to incorporate it to the repository. Consider it public domain.

Notice that for now this one has moved the random computation outside of the controller, example 17 above is more correct in this aspect. Now... it seems I got back to this issue. How can I get the reset button to always reset the random points to a new initial random state instead of a static one... (since I'm managing model's state through usage of foldp, which is UI code, not controller)?

@oblitum
Copy link
Contributor

oblitum commented Jun 23, 2016

I've noticed also that that technique of using foldp to start/reset the animation while having an internal animationFrame seems to turn framerate quiter slower (running just the view instead of the resetView is faster). Sadly I dunno how to do the same (having start and reset state) in a different way (not running animationFrame internally to a foldp).

@sharkdp I'd like to know your judgement regarding this. I'm feeling I'm already hitting the limitations with Flare here (I'm not sure)? I'm just starting in FP again because of PureScript but the way I've done state management of buttons seems a bit contrived, restrictive and resource hungry (foldp with animationFrame). And I really wished to get back to the state of example 17, with a effectful computation (random) as the controller, while also, having the buttons and animation working like they are currently.

@sharkdp
Copy link
Owner

sharkdp commented Aug 5, 2016

Sorry for the late answer.

I've finished a more complete sample which I incorporated in a blog post

Very nice!

You may feel free to incorporate it to the repository. Consider it public domain.

Thanks, I've added a link in the README.

How can I get the reset button to always reset the random points to a new initial random state instead of a static one...

has this been resolved in the mean time?

@oblitum
Copy link
Contributor

oblitum commented Aug 5, 2016

has this been resolved in the mean time?

No, I haven't touched the code since then, but I'd be interested in a flare sample of that, I'm still at #14 (comment) state.

Right now I'm trying to finish "PureScript by Example", so in those samples I touched subjects which I was not familiar with. After the book I'd go about studing other libs and flare to check whether I've hit the limit with flare and it would be more natural using pux, or other lib.

@oblitum
Copy link
Contributor

oblitum commented Aug 5, 2016

Thanks, I've added a link in the README.

Thanks!

@sharkdp
Copy link
Owner

sharkdp commented Aug 7, 2016

Sadly I dunno how to do the same (having start and reset state) in a different way (not running animationFrame internally to a foldp).

Currently, I cannot think of any other way, either. I was thinking about saving a "reset time" every time you press "reset", but that would also require you to pass the animationFrame signal through foldp.

You could probably nest two Flare UIs. The outer one would completely re-start the inner Flare, whenever "reset" is clicked. But ...

I'm feeling I'm already hitting the limitations with Flare here (I'm not sure)?

Quite possible. I encourage you to try out different PureScript UI frameworks. Flare is really only suited for "spreadsheet-like" UIs and the only way to incorporate "mutable state" is by using foldp.

I'm closing this, as the initial issue is resolved, I think. But let me know if you find out something else.

@sharkdp sharkdp closed this as completed Aug 7, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants