Closed jmatsushita closed 9 months ago
I should probably study this https://github.com/turion/rhine/blob/master/rhine-gloss/src/FRP/Rhine/Gloss/IO.hs :)
Thanks for your kind words :) this is a great idea!
I still don't understand the terminal
library well enough to understand the error exactly. What I don't understand at all: withTerminal :: (MonadIO m, MonadMask m) => (System.Terminal.Platform.LocalTerminal -> m a) -> m a
expects a function, but you give it the output of runTerminalT
. So you never use the value of type System.Terminal.Platform.LocalTerminal
. So how do you ensure that the clock and the ClSF
are on the same terminal?
Here is an idea you could try: Don't use TerminalT
(and runTerminalT
) at all in the definition of the Clock
and the ClSF
. Only use the type classes MonadTerminal
and so on. Then use withTerminal
and runTerminalT
at the very end, i.e.:
main = withTerminal $ runTerminalT $ flow mainRhine
If this works then at least we know where the trouble lies. There might be even better solutions which we can think about afterwards.
If you want, you can also submit your code as a PR to this repo here, as a separate library rhine-terminal
. Then we can iterate on it together. (I just have to warn you that I'm a meticulous reviewer ;) )
If you want, you can also submit your code as a PR to this repo here, as a separate library rhine-terminal. Then we can iterate on it together. (I just have to warn you that I'm a meticulous reviewer ;) )
That sounds awesome! I look forward to it and the learning opportunity. Doing as you suggested in the latest revision of the gist works a bit better, with the periodic clock properly displaying, but I can't seem to get terminal events to flow through.
I've managed to make a simple example work with vty
(in this gist) and I suspect that terminal
is less compliant maybe because of threading issues?
I'll take some time to submit both if that sounds like a good idea as rhine-vty
and rhine-terminal
?
Thanks a lot your help :D
I'll take some time to submit both if that sounds like a good idea as
rhine-vty
andrhine-terminal
?
Yes, that's great! If vty
is easier to handle, then it's probably best to start with that. They should be separate libraries then.
Yes, that's great! If vty is easier to handle, then it's probably best to start with that. They should be separate libraries then.
Sounds good!
So how do you ensure that the clock and the ClSF are on the same terminal?
I think my latest revision suffers from the same problem you pointed out above. The terminalSchedule
function also creates it's own terminal instead of reusing the existing one, probably leading to the events being swallowed.
I'll try using glossConcurrently
as a template for a terminalConcurrently
that properly passes the terminal (at first explicitly, then maybe through a ReaderT).
I've got a new version kinda sorta doing what I was looking for (basically the basics of a REPL), except it's excruciatingly slow, probably because my terminalConcurrently
is broken? I think it's using runTerminal
at each tick, which AFAICT should just be runReaderT
but maybe there's something else going on I don't understand. withTerminal
seems to be where the actual work is done, and I'm running this only once at the top-level.
Not sure if I'm missing something, I wonder if the terminal
API is missing some way to pass an existing terminal state (the way haskeline has queryInput), or maybe if the TerminalT
constructor was exported then it would be possible to rewrap the TerminalT
value and use readerSchedule concurrently
? Or maybe there's something about how async
and forkIO
interact? Possibly something @lpeterse could help clarify?
Now that I have something that looks like what I want, however broken at this point, I'll start preparing a PR with a rhine-terminal
backend, and a rhine-example that uses it, so that it can be ran from a repo instead of a gist.
Feel free to open a PR :) I don't understand what the performance problem is.
Hi @turion,
I'm finally spending some time poking at Rhine which I wanted to do for a while. I really love the concept and I'm bumping into some questions and issues that you probably will be able to help me with!
I'm trying to integrate the
haskell-terminal
library with Rhine, trying to replace theStdinClock
with a clock that returns terminal events (and a subclock that filters on key events). As you'll see I'm also trying to compose a periodic clock with an IO event driven clock, as well as printing to screen. I have tried to think about the display/actuator side as a Clock, but I couldn't wrap my head around how to do this (maybe by passing state to the clock and flushing to the terminal periodically?). Anyway that's not really the problem I wanted to ask help for, but I thought I'd also mention this in passing.The issue I'm running into when running this toy program https://gist.github.com/jmatsushita/d94f04479666979b57d99558fcf3f40d/49ac895e92fa620953086cd734cff21af371df68 is that I get the message
I'm a bit confused about how I should go about hoisting the TerminalT monad transformer into IO. I probably have the wrong idea running
withTerminal $ runTerminalT
twice, ininitClock
(which installs theawaitEvent
handler) and inliftTerminal
which tries to hoist the ClSF on the display side, but I've wrestled with it for a while now and I can't wrap my head around how to make this work.Hoping this could be useful as an example of how to use clocks that have effects in transformers, and I realise that hoisting
Rhine
s is a more difficult work in progress, but it doesn't seem like I should need that, but I might be wrong.Anyway, thanks a ton for the awesome paper and library, really looking forward to get unstuck :)
Jun