Skip to content

Commit

Permalink
Hook up basic effect handling
Browse files Browse the repository at this point in the history
  • Loading branch information
tommy-xr committed Oct 6, 2024
1 parent 71e6a22 commit f443cd5
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 10 deletions.
5 changes: 5 additions & 0 deletions examples/hello/hello.fs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ type Msg =

let game: Game<Model, Msg> = GameBuilder.local Model.initial

let update model msg =
printfn "Running update"
(model, Effect.none())

let tick model (tick: Time.FrameTime) =

let applyVelocity (tick: Time.FrameTime) ball =
Expand Down Expand Up @@ -111,5 +115,6 @@ let init (_args: array<string>) =
|> Transform.translateZ ((sin (frameTime.tts * 5.0f)) * 1.0f)
|])
)
|> GameBuilder.update update
|> GameBuilder.tick tick
|> Runtime.runGame
16 changes: 15 additions & 1 deletion runtime/functor-runtime-common/src/effect.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use fable_library_rust::Native_::Func1;
use fable_library_rust::{NativeArray_, Native_::Func1};

#[derive(Clone)]
pub enum Effect<T: Clone + 'static> {
Expand All @@ -7,6 +7,13 @@ pub enum Effect<T: Clone + 'static> {
}

impl<T: Clone + 'static> Effect<T> {
pub fn is_none(effect: &Effect<T>) -> bool {
match effect {
Effect::None => true,
_ => false,
}
}

pub fn none() -> Effect<T> {
Effect::None
}
Expand All @@ -21,4 +28,11 @@ impl<T: Clone + 'static> Effect<T> {
Effect::Wrapped(v) => Effect::Wrapped(mapping(v)),
}
}

pub fn run(effect: Effect<T>) -> NativeArray_::Array<T> {
match effect {
Effect::None => NativeArray_::array_from(vec![]),
Effect::Wrapped(v) => NativeArray_::array_from(vec![v]),
}
}
}
4 changes: 3 additions & 1 deletion runtime/functor-runtime-common/src/effect_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ impl<T: Clone + 'static> EffectQueue<T> {
}

pub fn enqueue(effect_queue: &EffectQueue<T>, effect: Effect<T>) {
effect_queue.queue.borrow_mut().push_front(effect);
if !Effect::is_none(&effect) {
effect_queue.queue.borrow_mut().push_front(effect);
}
}

pub fn dequeue(effect_queue: &EffectQueue<T>) -> Option<Effect<T>> {
Expand Down
8 changes: 7 additions & 1 deletion src/Functor.Game/Effect.fs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,10 @@ module Effect =
let wrapped (a: 'a) : effect<'a> = nativeOnly

[<Emit("functor_runtime_common::Effect::map($0, $1)")>]
let map (fn: 'a -> 'b) (eff: effect<'a>) : effect<'b> = nativeOnly
let map (fn: 'a -> 'b) (eff: effect<'a>) : effect<'b> = nativeOnly


// TODO: These should live elsewhere because they aren't user space

[<Emit("functor_runtime_common::Effect::run($0)")>]
let run (eff: effect<'a>) : 'a array = nativeOnly
4 changes: 4 additions & 0 deletions src/Functor.Game/Game.fs
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,9 @@ module GameRunner =
let (newModel, effect) = game.tick model tick
(newModel, effect)

let update<'model, 'msg> (game: Game<'model, 'msg>) (model: 'model) (msg: 'msg) =
let (newModel, effect) = game.update model msg
(newModel, effect)

let draw3d<'model, 'msg> (game: Game<'model, 'msg>) (model: 'model) (tick: Time.FrameTime) =
game.draw3d model tick
1 change: 1 addition & 0 deletions src/Functor.Game/Game.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ module GameBuilder =
module GameRunner =
val initialState: Game<'model, 'msg> -> 'model
val tick: Game<'model, 'msg> -> 'model -> Time.FrameTime -> ('model * effect<'msg>)
val update: Game<'model, 'msg> -> 'model -> 'msg -> ('model * effect<'msg>)
val draw3d: Game<'model, 'msg> -> 'model -> Time.FrameTime -> Graphics.Scene3D
22 changes: 15 additions & 7 deletions src/Functor.Game/Runtime.fs
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,24 @@ module Runtime

let maybe_effect = EffectQueue.dequeue effectQueue;

match maybe_effect with
| None -> printfn "No effect"
| Some _e -> printfn "Got effect"

let (newState, effect) = GameRunner.tick myGame state frameTime
let finalState =
match maybe_effect with
| None ->
printfn "No effect"
state
| Some _e ->
let arr: 'Msg array = Effect.run _e

Array.fold (fun (currentState) msg ->
let (newState, effect) = GameRunner.update myGame state msg
EffectQueue.enqueue effect effectQueue
newState
) (state) arr

let (newState, effect) = GameRunner.tick myGame finalState frameTime

EffectQueue.enqueue effect effectQueue;

// effectQueue <- Array.insertAt effectQueue.Length effect effectQueue

// Todo: Run tick effects

state <- newState
Expand Down

0 comments on commit f443cd5

Please sign in to comment.