I haven't been on the forum in a while, but I'm still circling around some of these problems...
The worker thing was a total bust by the way! Long story short - even with Transferable objects, worker messages eat up a couple ms or so, plus more time for serialization/deserialization... I don't have the numbers off-hand but using workers added something like 4+ms to every tick
So now I have everything happening on one frame, and it's basically like this (where fireEvent()
is just triggering that pipe()
, basically:
//example of the sort of thing that's plugged into pipe()
const updateCharacter = (stateAndEvent) => {
const {state, event} = stateAndEvent;
return (event.type === "mousemove")
? moveCharacter(stateAndEvent); //will return a new state with moved character
: stateAndEvent;
}
//on every event
stateAndEvent =
pipe([
updateCharacter,
updateSound,
...
])
(stateAndEvent)
//also on every event - but only after `stateAndEvent` is updated
if(event.type === "tick") {
render(state);
}
//Main
const tick = (timestamp) {
fireEvent({type: 'tick', timestamp: timestamp});
requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
window.addEventListener('mousemove', fireEvent);
Now that I have this all working... using lenses to update state (i.e. it's immutable and new copies are passed down to the end), and with clear separation between rendering and state updates, I'm thinking of bringing it back into FRP... but I'm not sure how that would fit, or what advantages it would give me - i.e. if the pipe()
were instead something like:
cStateAndEvent
.map(updateCharacter)
.map(updateSound)
.listen(render)
EDIT: I've cross-posted this question in a slightly different form at https://stackoverflow.com/questions/48109356/frp-vs-state-machine-w-lenses-for-game-loop