diff --git a/Cargo.toml b/Cargo.toml index a93f5f83afc39966ec180d0d03e0eeb6529ac2ff..1273cacc36549ea3959370e761bd9ad110d706b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ description = "A Game Boy emulator that is written in Rust." version = "0.5.1" authors = ["João Magalhães <joamag@gmail.com>"] license = "Apache-2.0" -repository = "https://gitlab.stage.hive.pt/joamag/boytacean" +repository = "https://github.com/joamag/boytacean" keywords = ["gameboy", "emulator", "rust"] edition = "2018" diff --git a/examples/web/gb.ts b/examples/web/gb.ts index c627f11d2f747f820d0161853ebea1272a6037a2..229873bf5eefcde68782a4b630a7ce4ce39b3ded 100644 --- a/examples/web/gb.ts +++ b/examples/web/gb.ts @@ -1,6 +1,7 @@ import { Emulator, EmulatorBase, + Entry, Feature, PixelFormat, RomInfo @@ -349,36 +350,25 @@ export class GameboyEmulator extends EmulatorBase implements Emulator { return "Boytacean"; } - get device(): string { - return "Game Boy"; - } - - get deviceUrl(): string { - return "https://en.wikipedia.org/wiki/Game_Boy"; - } - - get engines() { - return ["neo"]; - } - - get engine() { - return this._engine; - } - - get version(): string { - return info.version; - } - - get versionUrl(): string { - return "https://github.com/joamag/boytacean/blob/master/CHANGELOG.md"; + get device(): Entry { + return { + text: "Game Boy", + url: "https://en.wikipedia.org/wiki/Game_Boy" + }; } - get repository(): string | undefined { - return "GitHub"; + get version(): Entry | undefined { + return { + text: info.version, + url: "https://github.com/joamag/boytacean/blob/master/CHANGELOG.md" + }; } - get repositoryUrl(): string | undefined { - return "https://github.com/joamag/boytacean"; + get repository(): Entry { + return { + text: "GitHub", + url: "https://github.com/joamag/boytacean" + }; } get features(): Feature[] { @@ -391,6 +381,14 @@ export class GameboyEmulator extends EmulatorBase implements Emulator { ]; } + get engines() { + return ["neo"]; + } + + get engine() { + return this._engine; + } + get romExts(): string[] { return ["gb"]; } diff --git a/examples/web/package.json b/examples/web/package.json index 13ea909080eb45bdab74173f21ec16dac34e2b4f..14aa788992e522f6952467d4d25e7c682bc9ce26 100644 --- a/examples/web/package.json +++ b/examples/web/package.json @@ -4,7 +4,7 @@ "description": "The web version of Boytacean", "repository": { "type": "git", - "url": "git+https://gitlab.stage.hive.pt/joamag/boytacean.git" + "url": "git+https://github.com/joamag/boytacean.git" }, "license": "Apache-2.0", "scripts": { diff --git a/examples/web/react/app.tsx b/examples/web/react/app.tsx index 0a0229a97d8939867d4812f63a4f5dbecf81bdcd..eaf26070a80e78520c336c61f4e113a8f7ee02ad 100644 --- a/examples/web/react/app.tsx +++ b/examples/web/react/app.tsx @@ -204,7 +204,7 @@ export const App: FC<AppProps> = ({ const fileExtension = file.name.split(".").pop() ?? ""; if (!emulator.romExts.includes(fileExtension)) { showToast( - `This is probably not a ${emulator.device} ROM file!`, + `This is probably not a ${emulator.device.text} ROM file!`, true ); return; @@ -287,7 +287,7 @@ export const App: FC<AppProps> = ({ const onEngineChange = (engine: string) => { emulator.boot({ engine: engine.toLowerCase() }); showToast( - `${emulator.device} running in engine "${engine}" from now on!` + `${emulator.device.text} running in engine "${engine}" from now on!` ); }; const onFrequencyChange = (value: number) => { @@ -374,21 +374,19 @@ export const App: FC<AppProps> = ({ </Section> <Title text={emulator.name} - version={emulator.version} - versionUrl={ - emulator.versionUrl ? emulator.versionUrl : undefined - } + version={emulator.version?.text} + versionUrl={emulator.version?.url} iconSrc={require("../res/thunder.png")} ></Title> <Section> <Paragraph> This is a{" "} - {emulator.deviceUrl ? ( - <Link href={emulator.deviceUrl} target="_blank"> - {emulator.device} + {emulator.device.url ? ( + <Link href={emulator.device.url} target="_blank"> + {emulator.device.text} </Link> ) : ( - emulator.device + emulator.device.text )}{" "} emulator built using the{" "} <Link href="https://www.rust-lang.org" target="_blank"> @@ -403,15 +401,15 @@ export const App: FC<AppProps> = ({ {emulator.repository && ( <Paragraph> You can check the source code of it at{" "} - {emulator.repositoryUrl ? ( + {emulator.repository.url ? ( <Link - href={emulator.repositoryUrl} + href={emulator.repository.url} target="_blank" > - {emulator.repository} + {emulator.repository.text} </Link> ) : ( - <>{emulator.repository}</> + <>{emulator.repository.text}</> )} . </Paragraph> diff --git a/examples/web/react/structs.ts b/examples/web/react/structs.ts index 714d6f423cad3cfc03f478253b2e5423da44a853..465ff0a49b295c6ae5e2222ee63124b96c7a228b 100644 --- a/examples/web/react/structs.ts +++ b/examples/web/react/structs.ts @@ -2,36 +2,6 @@ export const FREQUENCY_DELTA = 100000; export type Callback<T> = (owner: T, params?: any) => void; -/** - * Abstract class that implements the basic functionality - * part of the definition of the Observer 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; - } - - unbind(event: string, callback: Callback<this>) { - const callbacks = this.events[event] ?? []; - if (!callbacks.includes(callback)) return; - const index = callbacks.indexOf(callback); - callbacks.splice(index, 1); - this.events[event] = callbacks; - } - - trigger(event: string, params?: any) { - const callbacks = this.events[event] ?? []; - callbacks.forEach((c) => c(this, params)); - } -} - export type RomInfo = { name?: string; data?: Uint8Array; @@ -46,6 +16,16 @@ export type BenchmarkResult = { frequency_mhz: number; }; +export type Entry = { + text: string; + url?: string; +}; + +/** + * Enumeration to be used to describe the set of + * features that a certain emulator supports, this + * is going to condition its runtime execution. + */ export enum Feature { Debug = 1, Palettes, @@ -82,34 +62,27 @@ export interface Emulator extends ObservableI { get name(): string; /** - * The name of the the hardware that is being emulated - * by the emulator (eg: Super Nintendo). + * The information on the hardware that is being emulated + * by the emulator (eg: Super Nintendo), can contain a URL + * that describes the device that is being emulated by + * the emulator (eg: Wikipedia link). */ - get device(): string; - - /** - * A URL to a website that describes the device that is - * being emulated by the emulator (eg: Wikipedia link). - */ - get deviceUrl(): string | undefined; + get device(): Entry; /** * A semantic version string for the current version - * of the emulator. + * of the emulator, can include a URL pointing to a + * changelog or equivalent document. * * @see {@link https://semver.org} */ - get version(): string; + get version(): Entry | undefined; /** - * The URL to the page describing the current version - * of the emulator. + * Information about the source code repository where + * the emulator source code is being stored. */ - get versionUrl(): string | undefined; - - get repository(): string | undefined; - - get repositoryUrl(): string | undefined; + get repository(): Entry | undefined; /** * The features available and compatible with the emulator, @@ -236,20 +209,42 @@ export interface Emulator extends ObservableI { benchmark?: { (count?: number): BenchmarkResult }; } -export class EmulatorBase extends Observable { - get deviceUrl(): string | undefined { - return undefined; +/** + * Abstract class that implements the basic functionality + * part of the definition of the Observer 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; } - get versionUrl(): string | undefined { - return undefined; + unbind(event: string, callback: Callback<this>) { + const callbacks = this.events[event] ?? []; + if (!callbacks.includes(callback)) return; + const index = callbacks.indexOf(callback); + callbacks.splice(index, 1); + this.events[event] = callbacks; + } + + trigger(event: string, params?: any) { + const callbacks = this.events[event] ?? []; + callbacks.forEach((c) => c(this, params)); } +} - get repository(): string | undefined { +export class EmulatorBase extends Observable { + get version(): Entry | undefined { return undefined; } - get repositoryUrl(): string | undefined { + get repository(): Entry | undefined { return undefined; }