Skip to content
Snippets Groups Projects
Verified Commit 6ffd97ce authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

feat: added frame event trigger

parent 0563c1a5
No related branches found
No related tags found
1 merge request!9Version 0.4.0 🍾
Pipeline #1366 passed
import { Emulator, PixelFormat, startApp } from "./react/app"; import { Emulator, Observable, PixelFormat, startApp } from "./react/app";
import { default as _wasm, GameBoy, PadKey, PpuMode } from "./lib/boytacean.js"; import { default as _wasm, GameBoy, PadKey, PpuMode } from "./lib/boytacean.js";
import info from "./package.json"; import info from "./package.json";
...@@ -48,7 +48,7 @@ const ROM_PATH = require("../../res/roms/20y.gb"); ...@@ -48,7 +48,7 @@ const ROM_PATH = require("../../res/roms/20y.gb");
* and "joins" all the elements together to bring input/output * and "joins" all the elements together to bring input/output
* of the associated machine. * of the associated machine.
*/ */
class GameboyEmulator implements Emulator { class GameboyEmulator extends Observable implements Emulator {
/** /**
* The Game Boy engine (probably coming from WASM) that * The Game Boy engine (probably coming from WASM) that
* is going to be used for the emulation. * is going to be used for the emulation.
...@@ -218,6 +218,7 @@ class GameboyEmulator implements Emulator { ...@@ -218,6 +218,7 @@ class GameboyEmulator implements Emulator {
this.gameBoy!.frame_buffer_eager(), this.gameBoy!.frame_buffer_eager(),
PixelFormat.RGB PixelFormat.RGB
); );
this.trigger("frame");
lastFrame = this.gameBoy!.ppu_frame(); lastFrame = this.gameBoy!.ppu_frame();
} }
} }
......
...@@ -22,12 +22,36 @@ import { ...@@ -22,12 +22,36 @@ import {
import "./app.css"; import "./app.css";
export type Callback<T> = (owner: T) => void;
/**
* Abstract class that implements the basic functionality
* part of the definition of the observable pattern.
*
* @see {@link https://en.wikipedia.org/wiki/Observer_pattern}
*/
export class Observable {
private events: Record<string, [Callback<this>]> = {};
bind(event: string, callback: Callback<this>) {
const callbacks = this.events[event] ?? [];
if (callbacks.includes(callback)) return;
callbacks.push(callback);
this.events[event] = callbacks;
}
trigger(event: string) {
const callbacks = this.events[event] ?? [];
callbacks.forEach((c) => c(this));
}
}
/** /**
* Top level interface that declares the main abstract * Top level interface that declares the main abstract
* interface of an emulator structured entity. * interface of an emulator structured entity.
* Should allow typical hardware operations to be performed. * Should allow typical hardware operations to be performed.
*/ */
export interface Emulator { export interface Emulator extends Observable {
getName(): string; getName(): string;
getVersion(): string; getVersion(): string;
getVersionUrl(): string; getVersionUrl(): string;
...@@ -80,9 +104,10 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => { ...@@ -80,9 +104,10 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => {
}; };
const onDrawHandler = (handler: DrawHandler) => { const onDrawHandler = (handler: DrawHandler) => {
if (intervalRef.current) return; if (intervalRef.current) return;
intervalRef.current = setInterval(() => { intervalRef.current = 1;
emulator.bind("frame", () => {
handler(emulator.getImageBuffer(), PixelFormat.RGB); handler(emulator.getImageBuffer(), PixelFormat.RGB);
}, 1000); });
}; };
useEffect(() => { useEffect(() => {
document.body.style.backgroundColor = `#${getBackground()}`; document.body.style.backgroundColor = `#${getBackground()}`;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment