Added a Display struct and animation frames
This commit is contained in:
@@ -1,16 +1,25 @@
|
|||||||
import React, { useState, useCallback, useEffect, useRef } from 'react'
|
import React, { useCallback, useEffect, useRef } from 'react'
|
||||||
import { WasmCPU } from '../pkg/vweb.js'
|
import { WasmCPU, Display } from '../pkg/vweb.js'
|
||||||
|
|
||||||
export default function({}) {
|
export default function({}) {
|
||||||
const canvas = useRef(null)
|
const canvas = useRef(null)
|
||||||
const [ctx, setCtx] = useState(null)
|
const cpu = useRef(new WasmCPU())
|
||||||
const [cpu, _setCpu] = useState(new WasmCPU())
|
const ctx = useRef(null)
|
||||||
|
const display = useRef(null)
|
||||||
|
const request = useRef(null)
|
||||||
|
|
||||||
|
const drawFrame = useCallback(() => {
|
||||||
|
display.current.draw(cpu.current, ctx.current)
|
||||||
|
request.current = requestAnimationFrame(drawFrame)
|
||||||
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const c = canvas.current.getContext('2d')
|
ctx.current = canvas.current.getContext('2d')
|
||||||
setCtx(c)
|
display.current = new Display()
|
||||||
cpu.draw_frame(c)
|
request.current = requestAnimationFrame(drawFrame)
|
||||||
|
return () => cancelAnimationFrame(request.current)
|
||||||
}, [canvas.current])
|
}, [canvas.current])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<canvas ref={canvas} width={640} height={480}></canvas>
|
<canvas ref={canvas} width={640} height={480}></canvas>
|
||||||
)
|
)
|
||||||
|
|||||||
+23
-10
@@ -25,6 +25,10 @@ impl NovaForth {
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct WasmCPU(CPU);
|
pub struct WasmCPU(CPU);
|
||||||
|
|
||||||
|
// This has to contain a Box or else it'll use up all the wasm_bindgen stack space
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub struct Display(Box<[u8; 640 * 480 * 4]>);
|
||||||
|
|
||||||
#[wasm_bindgen(inspectable, getter_with_clone)]
|
#[wasm_bindgen(inspectable, getter_with_clone)]
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct JsVasmError {
|
pub struct JsVasmError {
|
||||||
@@ -68,9 +72,9 @@ pub fn source_map(snippet: String) -> JsValue {
|
|||||||
impl WasmCPU {
|
impl WasmCPU {
|
||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new() -> WasmCPU {
|
pub fn new() -> WasmCPU {
|
||||||
let mut cpu = WasmCPU(CPU::new_random());
|
let mut cpu = CPU::new_random();
|
||||||
display::init_gfx(&mut cpu.0);
|
display::init_gfx(&mut cpu);
|
||||||
cpu
|
WasmCPU(cpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_data(&mut self, data: i32) {
|
pub fn push_data(&mut self, data: i32) {
|
||||||
@@ -162,11 +166,20 @@ impl WasmCPU {
|
|||||||
pub fn tick(&mut self) {
|
pub fn tick(&mut self) {
|
||||||
self.0.tick()
|
self.0.tick()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_frame(&self, ctx: &CanvasRenderingContext2d) -> Result<(), JsValue> {
|
|
||||||
let mut buf = [0u8; 640 * 480 * 4];
|
|
||||||
display::draw(&self.0, &mut buf);
|
|
||||||
let image_data = ImageData::new_with_u8_clamped_array(Clamped(&buf), 640)?;
|
|
||||||
ctx.put_image_data(&image_data, 0.0, 0.0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl Display {
|
||||||
|
#[wasm_bindgen(constructor)]
|
||||||
|
pub fn new() -> Display {
|
||||||
|
Display([0u8; 640 * 480 * 4].into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(&mut self, cpu: &WasmCPU, ctx: &CanvasRenderingContext2d) -> Result<(), JsValue> {
|
||||||
|
display::draw(&cpu.0, self.0.as_mut());
|
||||||
|
let image_data = ImageData::new_with_u8_clamped_array(Clamped(self.0.as_mut()), 640)?;
|
||||||
|
ctx.put_image_data(&image_data, 0.0, 0.0);
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user