Skip to content

Commit

Permalink
Implement desktop effect queue
Browse files Browse the repository at this point in the history
  • Loading branch information
tommy-xr committed Oct 4, 2024
1 parent 0abfe6e commit be0a7a1
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 1 deletion.
36 changes: 36 additions & 0 deletions runtime/functor-runtime-common/src/effect_queue.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use std::{cell::RefCell, collections::VecDeque, fmt, sync::Arc};

use crate::Effect;

#[derive(Clone)]
pub struct EffectQueue<T: Clone + 'static> {
queue: Arc<RefCell<VecDeque<Effect<T>>>>,
}

impl<T: Clone + 'static> EffectQueue<T> {
pub fn new() -> EffectQueue<T> {
EffectQueue {
queue: Arc::new(RefCell::new(VecDeque::new())),
}
}

pub fn count(effect_queue: &EffectQueue<T>) -> i32 {
effect_queue.queue.borrow().len() as i32
}

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

pub fn dequeue(effect_queue: &EffectQueue<T>) -> Option<Effect<T>> {
effect_queue.queue.borrow_mut().pop_back()
}
}

// Implement Debug manually
impl<T: Clone + 'static> fmt::Debug for EffectQueue<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Build the debug representation
f.debug_struct("EffectQueue").finish()
}
}
2 changes: 2 additions & 0 deletions runtime/functor-runtime-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ impl OpaqueState {
pub mod animation;
pub mod asset;
mod effect;
mod effect_queue;
mod frame_time;
pub mod geometry;
pub mod io;
Expand All @@ -65,6 +66,7 @@ mod shader_program;
pub mod texture;

pub use effect::*;
pub use effect_queue::*;
pub use frame_time::*;
pub use render_context::*;
pub use scene3d::*;
Expand Down
2 changes: 2 additions & 0 deletions runtime/functor-runtime-desktop/src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use functor_runtime_common::{FrameTime, Scene3D};
pub trait Game {
fn check_hot_reload(&mut self, frame_time: FrameTime);

fn tick(&mut self, frame_time: FrameTime);

fn render(&mut self, frame_time: FrameTime) -> Scene3D;

fn quit(&mut self);
Expand Down
8 changes: 8 additions & 0 deletions runtime/functor-runtime-desktop/src/hot_reload_game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ impl Game for HotReloadGame {
}
}

fn tick(&mut self, frame_time: FrameTime) {
unsafe {
let tick_func: Symbol<fn(FrameTime)> =
self.library.as_ref().unwrap().get(b"tick").unwrap();
tick_func(frame_time)
}
}

fn quit(&mut self) {
if let Some(handle) = self.watcher_thread.take() {
handle.join().expect("Failed to join watcher thread");
Expand Down
2 changes: 2 additions & 0 deletions runtime/functor-runtime-desktop/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ pub async fn main() {
}
}

game.tick(time.clone());

gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT);
let radius = 5.0;
let view_matrix: Matrix4<f32> = Matrix4::look_at_rh(
Expand Down
7 changes: 7 additions & 0 deletions runtime/functor-runtime-desktop/src/static_game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ impl Game for StaticGame {
}
}

fn tick(&mut self, frame_time: FrameTime) {
unsafe {
let tick_func: Symbol<fn(FrameTime)> = self.library.get(b"tick").unwrap();
tick_func(frame_time)
}
}

fn quit(&mut self) {
// Noop - nothing to do yet
}
Expand Down
19 changes: 19 additions & 0 deletions src/Functor.Game/EffectQueue.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Functor
open Fable.Core

[<Erase; Emit("functor_runtime_common::EffectQueue<$0>")>] type EffectQueue<'msg> = | Noop


module EffectQueue =

[<Emit("functor_runtime_common::EffectQueue::new()")>]
let empty (): EffectQueue<_> = nativeOnly

[<Emit("functor_runtime_common::EffectQueue::count(&$0)")>]
let count (effectQueue: EffectQueue<'a>): int = nativeOnly

[<Emit("functor_runtime_common::EffectQueue::enqueue(&$1, $0)")>]
let enqueue (eff: effect<'a>) (effectQueue: EffectQueue<'a>) : unit = nativeOnly

[<Emit("functor_runtime_common::EffectQueue::dequeue(&$0)")>]
let dequeue (effectQueue: EffectQueue<'a>): Option<effect<'a>> = nativeOnly
1 change: 1 addition & 0 deletions src/Functor.Game/Functor.Game.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="Effect.fs" />
<Compile Include="EffectQueue.fs" />
<Compile Include="Math/Angle.fs" />
<Compile Include="Math/Vector2.fs" />
<Compile Include="Math/Point2.fs" />
Expand Down
16 changes: 15 additions & 1 deletion src/Functor.Game/Runtime.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Runtime
let mutable currentRunner: Option<IRunner> = None

open Fable.Core.Rust
open System.Collections.Generic

///////////////////////////////
// WebAssembly API
Expand Down Expand Up @@ -87,6 +88,7 @@ module Runtime
type GameExecutor<'Msg, 'Model>(game: Game<'Model, 'Msg>, initialState: 'Model) =
let myGame = game
let mutable state: 'Model = initialState
let mutable effectQueue: EffectQueue<'Msg> = EffectQueue.empty()
do
printfn "Hello from GameRunner!"
interface IRunner with
Expand All @@ -98,9 +100,21 @@ module Runtime

// Todo: If first frame, run 'init'

printfn "Effect count: %d" (EffectQueue.count effectQueue)
// Todo: Run any pending effects
// Print the number of pending effects in the queue

let (newState, effects) = GameRunner.tick myGame state frameTime
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

EffectQueue.enqueue effect effectQueue;

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

// Todo: Run tick effects

Expand Down

0 comments on commit be0a7a1

Please sign in to comment.