Question

I've been comparing pull-only FRP (ie netwire) with push-pull FRP (ie reactive-bannana) in the implementation of games. Are there advantages to one over the other? Things I've notices are:

  • Push events make it easy to have events for mouse clicks / key presses from GLFW or GLUT
  • Arrowized FRP that netwire uses has much less IO floating around, which is always better.
  • It looks like having pull-only responses to things like mouse movement could cause time leaks.

What else have I missed?

Edit, to make this less opinion-based: The main goal is to have something that is as expressive/concise as possible, without time leaks.

Update: A big issue I have found with Netwire is that there doesn't seem to be a convenient way to have more than one framerate, as described in the article "Fix your Timestep."

Update 2: The way i've gotten around this is to make my game simulation wire return a Float -> IO () that takes the alpha value and does all the GL calls with everything interpolated by that alpha. Ideally I should be able to pass this "draw function" into another thread via an MVar and run it in that thread. Man, Haskell is awesome.

Update 3: In the six months since asking this question, I developed a simple rendering engine based around Netwire, and the concept of "entity-component programming." In this process I have actually not found the use of FRP to be terribly helpful. The expressiveness of Wires has actually turned out to be a hindrance in some circumstances. The problem centers around the "identity" of objects. When defining a value of Wire type, it has no identity, i.e. it may be re-used in the overall network multiple times, and represent different physical things each time. This is a huge pain when you want to do something like collision detection, and have no way to traverse the scene graph, because it cannot exist without being fused into a single opaque wire. This problem does not occur in "toy" examples, because it is easy to specify exactly which properties of which objects interact with which other objects in which ways. I believe this is a problem with either type of FRP.

It would be awesome if some Haskell wizard were to prove me wrong on this, but I don't really see a way around it. Also I'm sorry if the explanation isn't great, but it's not really that easy to understand without trying it yourself.

Was it helpful?

Solution

From what I can read here and there, Netwire and reactive-banana have different purposes and goals. Netwire specialises in modeling framed signals, such as a game server, because what a game server typically does is sending its state to client in periodic frames. Reactive-banana would be the better choice for creating a GUI because a GUI is a purely event-driven model and is not tolerant to time leak.

It seems to me you can use both, depending of which aspect you want to implement.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top