Skip to content

Commit

Permalink
Got runtime kinda working
Browse files Browse the repository at this point in the history
  • Loading branch information
tommy-xr committed May 21, 2024
1 parent 172860d commit dd7e0f9
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 44 deletions.
6 changes: 3 additions & 3 deletions examples/Pong/Pong.fs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ let initialState = {
ball = { position = Point2.zero; velocity = Vector2.zero; radius = 0.05 }
}

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

let tick model (tick: Tick.t) =

Expand Down Expand Up @@ -85,8 +85,8 @@ open Fable.Core.Rust
[<OuterAttr("no_mangle")>]
let init (_args: array<string>) =
game
|> Game.draw3d (fun _ -> Graphics.Primitives3D.Sphere)
|> Game.tick tick
|> GameBuilder.draw3d (fun _ -> Graphics.Scene3D.sphere())
|> GameBuilder.tick tick
|> Runtime.runGame


Expand Down
2 changes: 1 addition & 1 deletion runtime/functor-runtime-common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum Scene3D {
Cube,
Sphere,
Expand Down
4 changes: 2 additions & 2 deletions runtime/functor-runtime-desktop/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ pub fn main() {
func(42.0); // Call the function

let init_func: Symbol<fn()> = lib.get(b"init").unwrap(); // Get the function pointer

println!("Got render: {:?}", test_render_func());
println!("Running init.");
init_func();

println!("Got render: {:?}", test_render_func());
}
unsafe {
// Create a context from a WebGL2 context on wasm32 targets
Expand Down
39 changes: 22 additions & 17 deletions src/Functor.Game/Game.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,48 @@ type UpdateFn<'model, 'msg> = 'model -> 'msg -> ('model * effect<'msg>)
type InputFn<'model, 'msg> = 'model -> Input.t -> ('model * effect<'msg>)

type Game<'model, 'msg> = {
state: 'model
initialState: 'model
input: InputFn<'model, 'msg>
tick: TickFn<'model, 'msg>
update: UpdateFn<'model, 'msg>
render2d: 'model -> Graphics.Primitives2D.t
draw3d: 'model -> Graphics.Scene3D
}


open Fable.Core

module Game =
module GameBuilder =

let local initialState =
let update model msg = (model, Effect.none)
let tick model tick = (model, Effect.none)
let render2d model = Graphics.Primitives2D.Square
{ state = initialState; update = update; render2d = render2d; tick = tick }
let draw3d model = Graphics.Scene3D.cube()
let input model input = (model, Effect.none)
{ initialState = initialState; update = update; render2d = render2d; tick = tick; input = input; draw3d = draw3d}

let update<'model, 'msg> (f: UpdateFn<'model, 'msg>) (_game: Game<'model, 'msg>) =
printfn "Hello from Game.update!"
_game

let input<'model, 'msg> (f: InputFn<'model, 'msg>) (_game: Game<'model, 'msg>) =
printfn "Hello from Game.input!"
_game
let update<'model, 'msg> (f: UpdateFn<'model, 'msg>) (game: Game<'model, 'msg>) =
{ game with update = f }

let run<'model, 'msg> (_game: Game<'model, 'msg>) =
printfn "Hello from Game.run!"
()
let input<'model, 'msg> (f: InputFn<'model, 'msg>) (game: Game<'model, 'msg>) =
{ game with input = f }

let draw3d<'model, 'msg> (f: 'model -> Graphics.Primitives3D.t) (_game: Game<'model, 'msg>) =
printfn "Hello from Game.draw3d!"
_game
let draw3d<'model, 'msg> (f: 'model -> Graphics.Scene3D) (game: Game<'model, 'msg>) =
{ game with draw3d = f }

let tick<'model, 'msg> (f: TickFn<'model, 'msg>) (_game: Game<'model, 'msg>) =
printfn "Hello from Game.tick!"
_game



let hello = "Hello from functor game!"
module GameRunner =
let initialState (game: Game<'model, 'msg>) = game.initialState

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

let draw3d<'model, 'msg> (game: Game<'model, 'msg>) (model: 'model) =
game.draw3d model
19 changes: 8 additions & 11 deletions src/Functor.Game/Game.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,9 @@ type InputFn<'model, 'msg> = 'model -> Input.t -> ('model * effect<'msg>)

type TickFn<'model, 'msg> = 'model -> Tick.t -> ('model * effect<'msg>)

type Game<'model, 'msg> = {
state: 'model
tick: TickFn<'model, 'msg>
update: UpdateFn<'model, 'msg>
render2d: 'model -> Graphics.Primitives2D.t
}

module Game =
type Game<'model, 'msg>

module GameBuilder =
// GAME DEFINITION FUNCTIONS

val local : initialState:'model -> Game<'model, 'msg>
Expand All @@ -24,8 +19,10 @@ module Game =

val tick: TickFn<'model, 'msg> -> Game<'model, 'msg> -> Game<'model, 'msg>

val draw3d: ('model -> Graphics.Primitives3D.t) -> Game<'model, 'msg> -> Game<'model, 'msg>
val draw3d: ('model -> Graphics.Scene3D) -> Game<'model, 'msg> -> Game<'model, 'msg>

// GAME EXECUTION FUNCTIONS

val run : Game<'model, 'msg> -> unit
module GameRunner =
val initialState: Game<'model, 'msg> -> 'model
val tick: Game<'model, 'msg> -> 'model -> Tick.t -> ('model * effect<'msg>)
val draw3d: Game<'model, 'msg> -> 'model -> Graphics.Scene3D
19 changes: 12 additions & 7 deletions src/Functor.Game/Runtime.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Runtime

type IRunner =
abstract member tick: unit -> unit
abstract member render: unit -> Scene3D.Scene3D
abstract member render: unit -> Graphics.Scene3D

let mutable currentRunner: Option<IRunner> = None

Expand All @@ -13,26 +13,31 @@ module Runtime
let dynamic_call_from_rust num = printfn "Hello from F# called from Rust! %f" num

[<OuterAttr("no_mangle")>]
let test_render(): Scene3D.Scene3D = Scene3D.cube()
let test_render(): Graphics.Scene3D =
if currentRunner.IsSome then
currentRunner.Value.render()
else
raise (System.Exception("No runner"))

type GameRunner<'Msg, 'Model>(game: Game<'Model, 'Msg>, initialState: 'Model) =
type GameExecutor<'Msg, 'Model>(game: Game<'Model, 'Msg>, initialState: 'Model) =
let myGame = game
let mutable state: 'Model = initialState
do
printfn "Hello from GameRunner!"
interface IRunner with
member this.tick() =
let (newState, effects) = myGame.tick state Tick.initial
let (newState, effects) = GameRunner.tick myGame state Tick.initial
state <- newState
()
member this.render() =
printfn "Hello from GameRunner.render!"
Scene3D.cube()
GameRunner.draw3d myGame state
// printfn "Hello from GameRunner.render!"
// Scene3D.cube()


let runGame<'Msg, 'Model>(game: Game<'Model, 'Msg>) =
printfn "runGame"
let runner = GameRunner<'Msg, 'Model>(game, game.state)
let runner = GameExecutor<'Msg, 'Model>(game, GameRunner.initialState game)
currentRunner <- Some(runner :> IRunner)
()

8 changes: 5 additions & 3 deletions src/Functor.Game/Scene3D.fs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
module Scene3D
open Fable.Core
namespace Graphics

[<Erase; Emit("functor_runtime_common::Scene3D")>] type Scene3D = | Noop
open Fable.Core
[<Erase; Emit("functor_runtime_common::Scene3D")>] type Scene3D = | Noop

module Scene3D =

[<Emit("functor_runtime_common::Scene3D::cube()")>]
let cube(): Scene3D = nativeOnly
Expand Down

0 comments on commit dd7e0f9

Please sign in to comment.