Open turion opened 9 months ago
I've actually been working on something like this for Dunai! It's in a very rough condition, but I haven't had tons of time (or motivation) to work on it recently (I really wanted it to compile to the browser, but I think the JS backend needs to mature). The biggest issue with it is sampling rate (my laptop manages to limit the framerate, but on my desktop it burns a core running at max fps). I managed to get user input, graphs, windows, and buttons working in what I think is a decently ergonomic way, but I'm very open to suggestions! The current version of the Dunai library can be found here (everything about it, including the name, is/was WIP and is mostly due to a change in project goals/scope).
I'd happily switch to Rhine, especially with the cleaner user experience, but I'm not entirely confident with the various Rhine datatypes (I get the concept, but I don't know how much the API has changed in terms of UX).
@Cajunvoodoo I'd love to collaborate with you on this!
That sounds great! Since rhine
currently depends on dunai
, a dunai-dear-imgui
library could actually be reused in rhine
. For example, FRP.Rhine.ClSF.Except
is to a large portion a re-export of the corresponding dunai
module, and the other half is just simple lifting functions applied to the dunai
primitives.
If you have a conceptual idea, feel free to open a PR, I'll guide you along. If not, here are some ideas how to design this. I think the central questions have to be "what is the monad" and "what are the clocks".
For the monads, I could imagine something like abstracting the brackets into reader monads that, when run, take care of the brackets. Something like this pseudocode:
{-# LANGUAGE DataKinds #-}
data Backend = OpenGL | SDL
class BackendBracket (b :: Backend) where
type Context b
type Config b
create :: Config b -> IO (Context b)
destroy :: Context b -> IO ()
instance BackendBracket 'OpenGL where
type Context 'OpenGL = OpenGLContext
type Config b = OpenGLConfig
create = createWindow
destroy = destroyWindow
-- Using e.g. vinyl heterogeneous lists
newtype ManagedT (backends :: [Backend]) a = ManagedT (ReaderT (Rec Context backends) IO a)
-- It should be possible to implement such a context like Forall using type families
type family Forall (backends :: [Backend]) (Backend -> Constraint) :: Constraint where
Forall '[] _ = ()
Forall (backend ': backends) f = (f backend, Forall backends f)
runManagedT :: Forall backends BackendBracked => ManagedT backends a -> IO a
runManagedT = ... -- create all contexts and destroy them at the end
This is just a suggestion, possibly heterogeneous lists are overkill and it's better to have e.g. data Backend = OpenGL | SDL | OpenGLAndSDL | ...
to have more fine grained initialisations. Or one does away with the BackendBracket
type class completely and burdens initialisation on the user.
I'm not sure what's the best idea for clocks.
dear-imgui
. Only the renderings are ticks then.I guess it's easiest to start with 3. and once this is done, experiment with 2. or 1. when a few example applications are ready.
It would be great to have bindings for https://hackage.haskell.org/package/dear-imgui, which is a GUI library.