Custom Subject in Rocket.jl (for mouse events from GLFW)

Hello I am trying to use the Rocket.jl - reactive programming and I do not understand how to create custom Observable/Subject I have an GLFW function that gives back information when user use scroll and in this case prints either +1 or -1 depending on the direction;

So obviously function acts as a producer of infinite stream - in theory perfect for reactive programming yet I do not have any idea How to connect it - how to create Observable/Subject that will “produce +1 and -1” in order to attach actors that will invoke approriate functions on mouse scroll.

GLFW.SetScrollCallback(window, (_, xoff, yoff) → print(yoff) )

cc @bvdmitri :point_up_2:

1 Like

Hey! Thank you for trying out Rocket.jl

My approach would be something like:


using Rocket
using GLFW

mutable struct ScrollCallbackSubscribable <: Subscribable{Int}
    xoff_previous :: Float64
    yoff_previous :: Float64
    subject :: Subject{Int}

    ScrollCallbackSubscribable() = new(0.0, 0.0, Subject(Int))
end

function Rocket.on_subscribe!(handler::ScrollCallbackSubscribable, actor)
    return subscribe!(handler.subject, actor)
end

function (handler::ScrollCallbackSubscribable)(_, xoff, yoff)
      # I'm not sure how GLFW represents offsets so it might be wrong here
      # here you actually need to implement your scrolling logic
      if handler.yoff_previous > yoff
          next!(handler.subject, 1)
      else
          next!(handler.subject, -1)
      end 
      handler.xoff_previous = xoff
      handler.yoff_previous = yoff
end

const scrollback = ScrollCallbackSubscribable()

GLFW.SetScrollCallback(window, (a, xoff, yoff) -> scrollback(a, xoff, yoff))

# Than later in your application you can do smth like

subscription = subscribe!(scrollback, (direction) -> println(direction))

For example:

function main()
   # Create a window and its OpenGL context
    window = GLFW.CreateWindow(640, 480, "GLFW.jl")

    # Make the window's context current
    GLFW.MakeContextCurrent(window)
    
    GLFW.SetScrollCallback(window, (a, xoff, yoff) -> scrollback(a, xoff, yoff))
    
    subscription = subscribe!(scrollback, (direction) -> println(direction))
    
    # Loop until the user closes the window
    while !GLFW.WindowShouldClose(window)

        # Render here

        # Swap front and back buffers
        GLFW.SwapBuffers(window)

        # Poll for and process events
        GLFW.PollEvents()
    end
    
    unsubscribe!(subscription)
    
    GLFW.DestroyWindow(window) 
end

It’s not complete, but I think you get the idea. Also please you can find something useful in the Rocket.jl documentation about Subjects.

1 Like