4

I've made a scene graph functional rendering engine in Haskell and am wondering how to add interaction in to the mixture.

At first, I thought I could just have another Handler node which takes in one of the other nodes and then just apply some IORefs to it. For example, if I had

x,y,z <- IORef 0
KeyboardHandler KeyboardCallBack $ Translate x y z $ Object

When traversing, I would have

KeyboardHandler keyboard drawable -> case drawable of 
Translate x y z _ -> do 
(Char 'q') -> x $~! (-1)
(Char 'w') -> x $~! (+1)
(Char 'a') -> y $~! (-1)
(Char 's') -> y $~! (+1)
(Char 'z') -> z $~! (-1)
(Char 'x') -> z $~! (+1)
render drawable

Is it possible to do something like that or am I going completely the wrong way?

Gentatsu
  • 696
  • 1
  • 6
  • 26

1 Answers1

1

That approach might work, but there are better ways. I particularly liked GLFW-b example that utilized something called TQueue.

TQueue is short for Transactional Queue; it's something you can pass events into from the render thread, and then read them from the drawing thread. That way you can process them as if they were a simple, pure value; a list of events.

In general, Haskell favours pure operation to mutable state. The available rendering frameworks emphasize pure transformation of logical state to stuff on the screen. In this case, something like a State OSG monad would be probably OK, though.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135
  • I'm not sure I get it. So I wouldn't use IORefs then, I'm assuming (Ideally, I'd prefer not to). I'm not sure how I'd use them in my scene graph, though. How would I implement something of the sought? Thanks, btw! – Gentatsu Apr 09 '15 at 15:40
  • 1
    @Gentatsu `TQueue` is, inside, a clever `IORef` wrapper. – Bartek Banachewicz Apr 09 '15 at 16:00
  • I'm still unsure as to how I'd actually use it, though? The GLFW-b example seems quite specific, so I'm not sure as to how I'd abstract it out. – Gentatsu Apr 09 '15 at 16:55