Ответ 1
Для этого обсуждения часть меня больше всего интересует, так что вызов физическому движку (вызов для интеграции) всегда выполняется с помощью dt. Может ли реактивно-банановый пользователь писать этот цикл стиля?
Да, реактивный банан может это сделать.
Идея заключается в том, что вы пишете настраиваемый цикл событий и включаете в него реактивный банан. Библиотека не делает никаких предположений относительно того, откуда вы получаете свои события, она "только" решает проблему аккуратного описания новых событий с точки зрения существующих. В частности, вы можете использовать функцию newAddHandler
для создания двух функций обратного вызова, вызываемых в соответствующих местах цикла событий. По сути, реактивный банан - просто умопомрачительный метод для написания обычных функций обратного вызова, которые поддерживают состояние. Когда и как вы называете эти функции, зависит от вас.
Здесь общий контур:
-- set up callback functions
(renderEvent, render) <- newAddHandler
(stateUpdateEvent, stateUpdate) <- newAddHandler
-- make the callback functions do something interesting
let networkDescription = do
eRender <- fromAddHandler renderEvent
eStateUpdate <- fromAddHandler stateUpdateEvent
...
-- functionality here
actuate =<< compile networkDescription
-- event loop
while (! quit)
{
...
while (accumulator >= dt)
{
stateUpdate (t,dt) -- call one callback
t += dt
accumulator -= dt
}
...
render () -- call another callback
}
Фактически, я написал пример игрового цикла в этом стиле для более старой версии реактивного банана, но не стал полировать и публиковать его о взломе. Важными вещами, которые я хотел бы увидеть, являются:
- Выберите графический движок, который легко установить и работает в GHCi. Концепция использует SDL, но это действительно довольно неудобно, поскольку она не может использоваться из GHCi. Что-то вроде OpenGL + GLFW было бы хорошо.
- Предложите небольшую абстракцию, чтобы упростить запись фазы интерполяции. Вероятно, всего две вещи: событие
eTimer :: Event t ()
, которое представляет регулярные обновления физики и поведениеbSinceLastTimer :: Behavior t TimeDiff
, которое измеряет время с момента последних обновлений физики, которое можно использовать для выполнения интерполяции. (Это поведение вместо события, поэтому внутренние "нарисовать это!" Обновления прозрачны.)
Андреас Бернстайн blackout clone, использующий реактивный банан, может стать отличным примером для реализации в этом стиле.