Skip to content
This repository was archived by the owner on Jan 10, 2023. It is now read-only.

feat(ui): add a dirty callback for ui updates in js #229

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions crates/core/src/play/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use crate::{
use btreemultimap::{BTreeMultiMap, MultiRange};
use std::collections::HashSet;

#[derive(Debug, Default, Clone)]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen::prelude::wasm_bindgen)]
#[derive(Debug, Default, Clone, Copy)]
#[repr(C)]
pub struct JudgementReport {
pub amazings: u32,
pub perfects: u32,
Expand All @@ -28,9 +30,9 @@ pub struct JudgementReport {
}

pub struct Play<S: PlayState> {
field: Field,
state: S,
settings: Settings,
pub field: Field,
pub state: S,
pub settings: Settings,
}

impl<S: PlayState> Play<S> {
Expand All @@ -51,6 +53,13 @@ pub struct Active {
judgement_report: JudgementReport,
}

impl Active {
#[must_use]
pub fn judgement_report(&self) -> &JudgementReport {
&self.judgement_report
}
}

pub struct Concluded {
turntable: Turntable<turntable::Loaded>,
actions: BTreeMultiMap<RuntimeNote, NoteAction>,
Expand Down
2 changes: 2 additions & 0 deletions crates/head-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ release = ["rrr-head/release", "rrr-head/web"]

[dependencies]
anyhow = "1.0.65"
js-sys = "0.3.60"
log = { version = "0.4.17" }
rrr-head = { path = "../head", default-features = false }
console_error_panic_hook = "0.1.7"
console_log = { version = "0.2.0", features = ["color"] }
wasm-bindgen = "0.2.83"
wasm-bindgen-futures = "0.4.33"
winit = { version = "0.27.3", default-features = false }

[dependencies.web-sys]
version = "0.3.60"
Expand Down
2 changes: 2 additions & 0 deletions crates/head-wasm/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
131 changes: 113 additions & 18 deletions crates/head-wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,131 @@
use anyhow::Error;
use rrr_head::prelude::winit::{
#![feature(cfg_eval)]
#![feature(type_alias_impl_trait)]

use anyhow::{Error, Result};
use js_sys::Function;
use rrr_head::prelude::play;
use rrr_head::{platform::platform::time::Time, query};
use std::rc::Rc;
use wasm_bindgen::{prelude::*, JsCast};
use winit::error::OsError;

#[cfg_attr(feature = "wasm-bindgen", wasm_bindgen)]
use winit::{
self,
dpi::PhysicalSize,
event_loop::EventLoop,
platform::web::WindowBuilderExtWebSys,
window::{Window, WindowBuilder},
};
use rrr_head::{platform::platform::time::Time, query};
use std::rc::Rc;
use wasm_bindgen::{closure::Closure, prelude::wasm_bindgen, JsCast};

use web_sys::HtmlCanvasElement;

pub fn build_window(
event_loop: &EventLoop<()>,
canvas: Option<HtmlCanvasElement>,
size: PhysicalSize<u32>,
) -> Result<winit::window::Window, winit::error::OsError> {
{
log::debug!("Inner Size {:?}", size);
WindowBuilder::new()
#[cfg_eval]
#[cfg_attr(feature = "wasm-bindgen", wasm_bindgen)]
pub struct Engine {
#[cfg_attr(feature = "wasm-bindgen", wasm_bindgen(skip))]
event_loop: EventLoop<()>,
window: Window,
}

#[wasm_bindgen]
impl Engine {
#[inline]
pub(crate) fn new(engine: EngineComponents) -> Result<Engine> {
Self::init(engine)
}

fn init(engine: EngineComponents) -> Result<Self> {
let event_loop = EventLoop::new();

let size = PhysicalSize {
width: engine.width,
height: engine.height,
};
let window = WindowBuilder::new()
.with_title("Rust Rust Revolution")
.with_canvas(canvas)
.with_canvas(engine.canvas)
.with_inner_size(size)
.with_resizable(false)
.with_max_inner_size(size)
.with_min_inner_size(size)
.build(event_loop)
.build(&event_loop)?;

Ok(Engine { event_loop, window })
}
}

#[derive(Debug, Default, Clone)]
#[wasm_bindgen]
pub struct EngineBuilder {
pub(crate) engine: EngineComponents,
}

/// Components to use when building an Engine instance.
#[derive(Debug, Clone)]
pub(crate) struct EngineComponents {
pub canvas: Option<HtmlCanvasElement>,
pub width: u32,
pub height: u32,
pub ui_callback: Option<Function>,
}

impl Default for EngineComponents {
#[inline]
fn default() -> EngineComponents {
EngineComponents {
canvas: None,
width: 512,
height: 768,
ui_callback: None,
}
}
}

impl EngineBuilder {
/// Initializes builder with default values.
#[inline]
pub fn new() -> Self {
Default::default()
}

#[inline]
pub fn with_canvas(mut self, canvas: HtmlCanvasElement) -> Self {
self.engine.canvas.replace(canvas);
self
}

#[inline]
pub fn with_judgement_callback(mut self, callback: Function) -> Self {
self.engine.ui_callback.replace(callback);
self
}

#[inline]
pub fn build(self) -> Engine {
if let Ok(engine) = Engine::new(self.engine) {
engine
} else {
panic!("no good")
}
}
}

pub fn build_window(
event_loop: &EventLoop<()>,
canvas: Option<HtmlCanvasElement>,
size: PhysicalSize<u32>,
) -> Result<Window, OsError> {
WindowBuilder::new()
.with_title("Rust Rust Revolution")
.with_canvas(canvas)
.with_inner_size(size)
.with_resizable(false)
.with_max_inner_size(size)
.with_min_inner_size(size)
.build(event_loop)
}

#[wasm_bindgen(start)]
pub fn initialize() {
console_log::init().unwrap();
Expand All @@ -48,7 +145,7 @@ pub fn play(canvas: Option<HtmlCanvasElement>, width: u32, height: u32) {
let mut game = rrr_head::Game::<Time>::new(None, width, height);
game.with_settings(extracted_settings);

rrr_head::run_game_loop(window, size, event_loop, game).await;
let _ = rrr_head::run_game_loop(window, size, event_loop, game).await;
}
});
}
Expand Down Expand Up @@ -104,8 +201,6 @@ async fn initialize_window(
}

pub fn register_on_visibility_change_listener(window: &web_sys::Window) {
use wasm_bindgen::JsCast;

let closure = Closure::wrap(Box::new(move || {
let window = web_sys::window().unwrap();
let document = window.document().unwrap();
Expand Down
26 changes: 26 additions & 0 deletions crates/head/src/engine.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/// Metadata Fetcher
///
/// Fetches data from a stream, therefore must be polled to come to completion.
///

/// Metadata Container
///
/// Holds metadata such as Charts, Songs, Playlists, Scores, Player Data, etc...
///

/// Chart Simulator
///
/// The engine is polled with a delta and progresses audio views and/or note views.
///

/// Web Head
///
/// Initializes the Metadata Container, Metadata Fetcher, and Chart Simulator as needed.
/// Has platform specific requirements for interfacing with each of these libraries.
///

/// Native Head
///
/// Initializes the Metadata Container, Metadata Fetcher, and Chart Simulator as needed.
/// Has platform specific requirements for interfacing with each of these libraries.
///
13 changes: 13 additions & 0 deletions crates/head/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,19 @@ use winit::{
window::WindowBuilder,
};

#[cfg_attr(
target_arch = "wasm32",
wasm_bindgen::prelude::wasm_bindgen(module = "\\/src\\/judgement.js")
)]
extern "C" {
fn update_judgement(judgement_report: play::JudgementReport);
}

pub mod prelude {
pub use anyhow;
pub use futures;
pub use log;
pub use rrr_core::play;
pub use winit;
}

Expand Down Expand Up @@ -446,6 +455,10 @@ where
self.screen_height,
);
}

unsafe {
update_judgement(*play.state.judgement_report());
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
</div>
<script type="module">
import init, { play, Engine, SettingsMerge } from "./bin/rrr.js";

async function run() {
await init();

Expand Down
3 changes: 3 additions & 0 deletions web/src/judgement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function update_judgement(report) {
console.log("Perfects: ", report.perfects);
}