From 16fa0aa5a631d2dcff22e823bca87036ed0c4b54 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Mon, 14 Nov 2022 11:50:11 +0000
Subject: [PATCH] refactor: extracted structs out of main file

---
 examples/web/gb.ts                            |   2 +-
 examples/web/react/app.tsx                    | 271 +-----------------
 .../web/react/components/display/display.tsx  |   2 +-
 examples/web/react/components/tiles/tiles.tsx |   2 +-
 examples/web/react/structs.ts                 | 263 +++++++++++++++++
 5 files changed, 273 insertions(+), 267 deletions(-)
 create mode 100644 examples/web/react/structs.ts

diff --git a/examples/web/gb.ts b/examples/web/gb.ts
index 6f5199d3..c627f11d 100644
--- a/examples/web/gb.ts
+++ b/examples/web/gb.ts
@@ -4,7 +4,7 @@ import {
     Feature,
     PixelFormat,
     RomInfo
-} from "./react/app";
+} from "./react/structs";
 import { PALETTES } from "./palettes";
 
 import {
diff --git a/examples/web/react/app.tsx b/examples/web/react/app.tsx
index 89ab434a..0a0229a9 100644
--- a/examples/web/react/app.tsx
+++ b/examples/web/react/app.tsx
@@ -1,8 +1,6 @@
 import React, { FC, useEffect, useRef, useState } from "react";
 import ReactDOM from "react-dom/client";
 
-const FREQUENCY_DELTA = 100000;
-
 declare const require: any;
 
 import {
@@ -29,271 +27,16 @@ import {
     Title,
     Toast
 } from "./components";
+import {
+    Emulator,
+    Feature,
+    FREQUENCY_DELTA,
+    PixelFormat,
+    RomInfo
+} from "./structs";
 
 import "./app.css";
 
-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;
-    size?: number;
-    extra?: Record<string, string | undefined>;
-};
-
-export type BenchmarkResult = {
-    delta: number;
-    count: number;
-    cycles: number;
-    frequency_mhz: number;
-};
-
-export enum Feature {
-    Debug = 1,
-    Palettes,
-    Benchmark,
-    Keyboard,
-    KeyboardChip8,
-    KeyboardGB
-}
-
-export interface ObservableI {
-    bind(event: string, callback: Callback<this>): void;
-    unbind(event: string, callback: Callback<this>): void;
-    trigger(event: string): void;
-}
-
-/**
- * Top level interface that declares the main abstract
- * interface of an emulator structured entity.
- * Should allow typical hardware operations to be performed.
- */
-export interface Emulator extends ObservableI {
-    /**
-     * The descriptive name of the emulator.
-     */
-    get name(): string;
-
-    /**
-     * The name of the the hardware that is being emulated
-     * by the emulator (eg: Super Nintendo).
-     */
-    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;
-
-    /**
-     * A semantic version string for the current version
-     * of the emulator.
-     *
-     * @see {@link https://semver.org}
-     */
-    get version(): string;
-
-    /**
-     * The URL to the page describing the current version
-     * of the emulator.
-     */
-    get versionUrl(): string | undefined;
-
-    get repository(): string | undefined;
-
-    get repositoryUrl(): string | undefined;
-
-    /**
-     * The features available and compatible with the emulator,
-     * these values will influence the associated GUIs.
-     */
-    get features(): Feature[];
-
-    /**
-     * The complete set of engine names that can be used
-     * in the re-boot operation.
-     */
-    get engines(): string[];
-
-    /**
-     * The name of the current execution engine being used
-     * by the emulator.
-     */
-    get engine(): string | null;
-
-    /**
-     * The complete set of file extensions that this emulator
-     * supports.
-     */
-    get romExts(): string[];
-
-    /**
-     * The pixel format of the emulator's display
-     * image buffer (eg: RGB).
-     */
-    get pixelFormat(): PixelFormat;
-
-    /**
-     * Gets the complete image buffer as a sequence of
-     * bytes that respects the current pixel format from
-     * `getPixelFormat()`. This method returns an in memory
-     * pointer to the heap and not a copy.
-     */
-    get imageBuffer(): Uint8Array;
-
-    /**
-     * Gets information about the ROM that is currently
-     * loaded in the emulator, using a structure containing
-     * the information about the ROM that is currently
-     * loaded in the emulator.
-     */
-    get romInfo(): RomInfo;
-
-    /**
-     * The current CPU frequency (logic) of the emulator,
-     * should impact other elements of the emulator.
-     */
-    get frequency(): number;
-    set frequency(value: number);
-
-    /**
-     * The recommended frequency delta in hertz for scale up
-     * and scale down operations in the CPU frequency.
-     */
-    get frequencyDelta(): number | null;
-
-    /**
-     * The current logic framerate of the running emulator.
-     */
-    get framerate(): number;
-
-    /**
-     * A dictionary that contains the register names associated
-     * with their value either as strings or numbers.
-     */
-    get registers(): Record<string, string | number>;
-
-    /**
-     * Obtains the pixel buffer for the VRAM tile at the given
-     * index.
-     *
-     * @param index The index of the tile to obtain pixel buffer.
-     * @returns The pixel buffer of the tile at the given index.
-     */
-    getTile(index: number): Uint8Array;
-
-    /**
-     * Boot (or reboots) the emulator according to the provided
-     * set of options.
-     *
-     * @param options The options that are going to be used for
-     * the booting operation of the emulator.
-     */
-    boot(options: any): void;
-
-    /**
-     * Toggle the running state of the emulator between paused
-     * and running, prevents consumers from the need to access
-     * the current running state of the emulator to implement
-     * a logic toggle.
-     */
-    toggleRunning(): void;
-    pause(): void;
-    resume(): void;
-
-    /**
-     * Resets the emulator machine to the start state and
-     * re-loads the ROM that is currently set in the emulator.
-     */
-    reset(): void;
-
-    keyPress(key: string): void;
-
-    keyLift(key: string): void;
-
-    /**
-     * Changes the palette of the emulator to the "next" one.
-     */
-    changePalette?: { (): void };
-
-    /**
-     * Runs a benchmark operation in the emulator, effectively
-     * measuring the performance of it.
-     *
-     * @param count The number of benchmark iterations to be
-     * run, increasing this value will make the benchmark take
-     * more time to be executed.
-     * @returns The result metrics from the benchmark run.
-     */
-    benchmark?: { (count?: number): BenchmarkResult };
-}
-
-export class EmulatorBase extends Observable {
-    get deviceUrl(): string | undefined {
-        return undefined;
-    }
-
-    get versionUrl(): string | undefined {
-        return undefined;
-    }
-
-    get repository(): string | undefined {
-        return undefined;
-    }
-
-    get repositoryUrl(): string | undefined {
-        return undefined;
-    }
-
-    get features(): Feature[] {
-        return [];
-    }
-
-    get frequencyDelta(): number | null {
-        return FREQUENCY_DELTA;
-    }
-}
-
-/**
- * Enumeration that describes the multiple pixel
- * formats and the associated size in bytes.
- */
-export enum PixelFormat {
-    RGB = 3,
-    RGBA = 4
-}
-
 type AppProps = {
     emulator: Emulator;
     fullscreen?: boolean;
diff --git a/examples/web/react/components/display/display.tsx b/examples/web/react/components/display/display.tsx
index 3aacfda2..4180efb4 100644
--- a/examples/web/react/components/display/display.tsx
+++ b/examples/web/react/components/display/display.tsx
@@ -1,5 +1,5 @@
 import React, { FC, useState, useRef, useEffect } from "react";
-import { PixelFormat } from "../../app";
+import { PixelFormat } from "../../structs";
 
 import "./display.css";
 
diff --git a/examples/web/react/components/tiles/tiles.tsx b/examples/web/react/components/tiles/tiles.tsx
index 78b340e1..c1b6f7b5 100644
--- a/examples/web/react/components/tiles/tiles.tsx
+++ b/examples/web/react/components/tiles/tiles.tsx
@@ -1,5 +1,5 @@
 import React, { FC, useEffect, useRef } from "react";
-import { PixelFormat } from "../../app";
+import { PixelFormat } from "../../structs";
 import Canvas, { CanvasStructure } from "../canvas/canvas";
 
 import "./tiles.css";
diff --git a/examples/web/react/structs.ts b/examples/web/react/structs.ts
new file mode 100644
index 00000000..714d6f42
--- /dev/null
+++ b/examples/web/react/structs.ts
@@ -0,0 +1,263 @@
+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;
+    size?: number;
+    extra?: Record<string, string | undefined>;
+};
+
+export type BenchmarkResult = {
+    delta: number;
+    count: number;
+    cycles: number;
+    frequency_mhz: number;
+};
+
+export enum Feature {
+    Debug = 1,
+    Palettes,
+    Benchmark,
+    Keyboard,
+    KeyboardChip8,
+    KeyboardGB
+}
+
+/**
+ * Enumeration that describes the multiple pixel
+ * formats and the associated size in bytes.
+ */
+export enum PixelFormat {
+    RGB = 3,
+    RGBA = 4
+}
+
+export interface ObservableI {
+    bind(event: string, callback: Callback<this>): void;
+    unbind(event: string, callback: Callback<this>): void;
+    trigger(event: string): void;
+}
+
+/**
+ * Top level interface that declares the main abstract
+ * interface of an emulator structured entity.
+ * Should allow typical hardware operations to be performed.
+ */
+export interface Emulator extends ObservableI {
+    /**
+     * The descriptive name of the emulator.
+     */
+    get name(): string;
+
+    /**
+     * The name of the the hardware that is being emulated
+     * by the emulator (eg: Super Nintendo).
+     */
+    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;
+
+    /**
+     * A semantic version string for the current version
+     * of the emulator.
+     *
+     * @see {@link https://semver.org}
+     */
+    get version(): string;
+
+    /**
+     * The URL to the page describing the current version
+     * of the emulator.
+     */
+    get versionUrl(): string | undefined;
+
+    get repository(): string | undefined;
+
+    get repositoryUrl(): string | undefined;
+
+    /**
+     * The features available and compatible with the emulator,
+     * these values will influence the associated GUIs.
+     */
+    get features(): Feature[];
+
+    /**
+     * The complete set of engine names that can be used
+     * in the re-boot operation.
+     */
+    get engines(): string[];
+
+    /**
+     * The name of the current execution engine being used
+     * by the emulator.
+     */
+    get engine(): string | null;
+
+    /**
+     * The complete set of file extensions that this emulator
+     * supports.
+     */
+    get romExts(): string[];
+
+    /**
+     * The pixel format of the emulator's display
+     * image buffer (eg: RGB).
+     */
+    get pixelFormat(): PixelFormat;
+
+    /**
+     * Gets the complete image buffer as a sequence of
+     * bytes that respects the current pixel format from
+     * `getPixelFormat()`. This method returns an in memory
+     * pointer to the heap and not a copy.
+     */
+    get imageBuffer(): Uint8Array;
+
+    /**
+     * Gets information about the ROM that is currently
+     * loaded in the emulator, using a structure containing
+     * the information about the ROM that is currently
+     * loaded in the emulator.
+     */
+    get romInfo(): RomInfo;
+
+    /**
+     * The current CPU frequency (logic) of the emulator,
+     * should impact other elements of the emulator.
+     */
+    get frequency(): number;
+    set frequency(value: number);
+
+    /**
+     * The recommended frequency delta in hertz for scale up
+     * and scale down operations in the CPU frequency.
+     */
+    get frequencyDelta(): number | null;
+
+    /**
+     * The current logic framerate of the running emulator.
+     */
+    get framerate(): number;
+
+    /**
+     * A dictionary that contains the register names associated
+     * with their value either as strings or numbers.
+     */
+    get registers(): Record<string, string | number>;
+
+    /**
+     * Obtains the pixel buffer for the VRAM tile at the given
+     * index.
+     *
+     * @param index The index of the tile to obtain pixel buffer.
+     * @returns The pixel buffer of the tile at the given index.
+     */
+    getTile(index: number): Uint8Array;
+
+    /**
+     * Boot (or reboots) the emulator according to the provided
+     * set of options.
+     *
+     * @param options The options that are going to be used for
+     * the booting operation of the emulator.
+     */
+    boot(options: any): void;
+
+    /**
+     * Toggle the running state of the emulator between paused
+     * and running, prevents consumers from the need to access
+     * the current running state of the emulator to implement
+     * a logic toggle.
+     */
+    toggleRunning(): void;
+    pause(): void;
+    resume(): void;
+
+    /**
+     * Resets the emulator machine to the start state and
+     * re-loads the ROM that is currently set in the emulator.
+     */
+    reset(): void;
+
+    keyPress(key: string): void;
+
+    keyLift(key: string): void;
+
+    /**
+     * Changes the palette of the emulator to the "next" one.
+     */
+    changePalette?: { (): void };
+
+    /**
+     * Runs a benchmark operation in the emulator, effectively
+     * measuring the performance of it.
+     *
+     * @param count The number of benchmark iterations to be
+     * run, increasing this value will make the benchmark take
+     * more time to be executed.
+     * @returns The result metrics from the benchmark run.
+     */
+    benchmark?: { (count?: number): BenchmarkResult };
+}
+
+export class EmulatorBase extends Observable {
+    get deviceUrl(): string | undefined {
+        return undefined;
+    }
+
+    get versionUrl(): string | undefined {
+        return undefined;
+    }
+
+    get repository(): string | undefined {
+        return undefined;
+    }
+
+    get repositoryUrl(): string | undefined {
+        return undefined;
+    }
+
+    get features(): Feature[] {
+        return [];
+    }
+
+    get frequencyDelta(): number | null {
+        return FREQUENCY_DELTA;
+    }
+}
-- 
GitLab