From 6db356ba7fb76ed305ce753e7abe3c6c2cef9100 Mon Sep 17 00:00:00 2001 From: Theodore Kruczek Date: Fri, 29 Dec 2023 18:21:16 -0500 Subject: [PATCH 1/3] refactor: :recycle: refactor Events to use enum and better type checking There was a problem with the onHover event that led me down a rabbit hole. With multiple developers it seems almost a necessity to use an enum for events to make sure we aren't doing the same thing with different string names. I also added better typing for the fireEvent method to make sure you are passing the correct data. Sorry this is a large change. --- src/common/interfaces/EventData.ts | 27 +++++++++++++++++++ src/common/interfaces/Events.ts | 17 ++++++++++++ .../interfaces/SatelliteObject.ts | 0 src/constants.ts | 14 +--------- src/hud/HudWindow.ts | 10 ++++--- src/hud/index.ts | 23 +++++++++------- src/utils/event-manager.ts | 7 ++--- src/viewer/index.ts | 22 ++++++++++----- 8 files changed, 83 insertions(+), 37 deletions(-) create mode 100644 src/common/interfaces/EventData.ts create mode 100644 src/common/interfaces/Events.ts rename src/{viewer => common}/interfaces/SatelliteObject.ts (100%) diff --git a/src/common/interfaces/EventData.ts b/src/common/interfaces/EventData.ts new file mode 100644 index 0000000..0d58dd8 --- /dev/null +++ b/src/common/interfaces/EventData.ts @@ -0,0 +1,27 @@ +import { SatelliteObject } from '@/common/interfaces/SatelliteObject'; +import Events from './Events'; + +/** + * Represents the data structure for various events in the application. + * + * Based on the enum Events passed in, the data structure will change. + * This ensures that the data the listener is expecting is the same as + * the data the firing code is sending. + */ +type EventData = { + [Events.satHover]: { + satellite: SatelliteObject | undefined; + satId: number; + satX: number; + satY: number; + }; + [Events.satMovementChange]: undefined; + [Events.selectedSatChange]: SatelliteObject | undefined; + [Events.satDataLoaded]: SatelliteObject[]; + [Events.closeWindow]: undefined; + [Events.cruncherReady]: undefined; + [Events.open]: undefined; + [Events.close]: undefined; +}; + +export default EventData; diff --git a/src/common/interfaces/Events.ts b/src/common/interfaces/Events.ts new file mode 100644 index 0000000..c7e8573 --- /dev/null +++ b/src/common/interfaces/Events.ts @@ -0,0 +1,17 @@ +/** + * Enum representing the various custom events used in the application. + * + * The string value MUST be lowercase. + */ +const enum Events { + satMovementChange = 'satmovementchange', + selectedSatChange = 'selectedsatchange', + satHover = 'sathover', + satDataLoaded = 'satdataloaded', + closeWindow = 'closewindow', + cruncherReady = 'cruncherready', + open = 'open', + close = 'close', +} + +export default Events; diff --git a/src/viewer/interfaces/SatelliteObject.ts b/src/common/interfaces/SatelliteObject.ts similarity index 100% rename from src/viewer/interfaces/SatelliteObject.ts rename to src/common/interfaces/SatelliteObject.ts diff --git a/src/constants.ts b/src/constants.ts index eb7f132..7345020 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,16 +1,4 @@ /* eslint-disable import/prefer-default-export */ const R2D = 80 / Math.PI; -const Events = { - satMovementChange: 'satMovementChange', - selectedSatChange: 'selectedSatChange', - satHover: 'sathoverChange', - satDataLoaded: 'satdataloaded', - closeWindow: 'closeWindow', - cruncherReady: 'cruncherReady' -}; - -export { - R2D, - Events -}; +export { R2D }; diff --git a/src/hud/HudWindow.ts b/src/hud/HudWindow.ts index 9e8d2fe..ec1e8f4 100644 --- a/src/hud/HudWindow.ts +++ b/src/hud/HudWindow.ts @@ -1,8 +1,10 @@ +import Events from '@/common/interfaces/Events'; + class Window { element?: HTMLElement; id: string; options?: Record; - listeners: Record void>> ={}; + listeners: Record void>> = {}; firstOpen = true; windowManager: any; @@ -29,7 +31,7 @@ class Window { this.element.classList.add('visible'); this.element.classList.remove('hidden'); this.windowManager.bringWindowToFront(this); - this.fireEvent('open', {}); + this.fireEvent(Events.open); } close () { @@ -40,7 +42,7 @@ class Window { this.element.classList.remove('active'); this.element.classList.remove('visible'); this.element.classList.add('hidden'); - this.fireEvent('close', {}); + this.fireEvent(Events.close); } isOpen () { @@ -106,7 +108,7 @@ class Window { } } - fireEvent (eventName: string, data: any) { + fireEvent (eventName: Events, data?: any) { if (this.listeners[eventName]) { const listenerSet = this.listeners[eventName]; listenerSet.forEach((listener) => { diff --git a/src/hud/index.ts b/src/hud/index.ts index 91f0f72..6e5b78a 100644 --- a/src/hud/index.ts +++ b/src/hud/index.ts @@ -1,9 +1,11 @@ -/* eslint-disable no-loop-func */ -import { R2D, Events } from '@/constants'; +import { R2D } from '@/constants'; import SatelliteGroup from '@satellite-viewer/SatelliteGroup'; import { Viewer } from '@satellite-viewer/index'; import HudWindowManager from './HudWindowManager'; import searchBox from './SearchBox'; +import { SatelliteObject } from '@/common/interfaces/SatelliteObject'; +import Events from '@/common/interfaces/Events'; +import EventData from '@/common/interfaces/EventData'; const supporteEvents: string[] = []; const windowManager = new HudWindowManager(); @@ -67,7 +69,7 @@ function setHtml (selector: string, html: string) { } } -function onSelectedSatChange (satellite: Record) { +function onSelectedSatChange (satellite: SatelliteObject | undefined) { if (satellite) { document.querySelector('#sat-infobox')?.classList.add('visible'); setHtml('#sat-info-title', satellite.OBJECT_NAME); @@ -82,12 +84,13 @@ function onSelectedSatChange (satellite: Record) { } } -function onSatHover (event: any) { - const { - satId, satX, satY, satellite - } = event; - - if (!satId || satId === -1) { +function onSatHover ({ + satId, + satX, + satY, + satellite, +}: EventData[Events.satHover]) { + if (!satellite || !satId || satId === -1) { setHtml('#sat-hoverbox', '(none)'); let element = document.querySelector('#sat-hoverbox') as HTMLElement; if (element) { @@ -324,5 +327,5 @@ export default { setLoading, init, getSupportedEvents, - getCurrentSearch + getCurrentSearch, }; diff --git a/src/utils/event-manager.ts b/src/utils/event-manager.ts index 6ff75a7..02cf226 100644 --- a/src/utils/event-manager.ts +++ b/src/utils/event-manager.ts @@ -1,3 +1,6 @@ +import EventData from '@/common/interfaces/EventData'; +import Events from '@/common/interfaces/Events'; + class EventManager { listeners: Record> = {}; supportedEvents: string[] | undefined; @@ -28,13 +31,11 @@ class EventManager { } } - fireEvent (eventName: string, data: any) { + fireEvent (eventName: E, data: EventData[E]) { if (!eventName) { throw new Error('undefined eventName'); } - eventName = eventName.toLowerCase(); - if (this.listeners[eventName]) { const listenerSet = this.listeners[eventName]; listenerSet.forEach((listener) => { diff --git a/src/viewer/index.ts b/src/viewer/index.ts index 73a1540..b685805 100644 --- a/src/viewer/index.ts +++ b/src/viewer/index.ts @@ -16,6 +16,8 @@ import SatelliteGroup from './SatelliteGroup'; import ShaderStore from './ShaderStore'; import logger from '@/utils/logger'; import { ArrowHelper, Raycaster, Vector2, Vector3 } from 'three'; +import { SatelliteObject } from '../common/interfaces/SatelliteObject'; +import Events from '@/common/interfaces/Events'; class Viewer { config: Record = { @@ -100,8 +102,8 @@ class Viewer { } } - private onSatDataLoaded (satData: Record) { - this.eventManager.fireEvent('satdataloaded', satData); + private onSatDataLoaded (satData: SatelliteObject[]) { + this.eventManager.fireEvent(Events.satDataLoaded, satData); this.ready = true; } @@ -171,7 +173,8 @@ class Viewer { } private isValidTarget (satelliteIdx: number): boolean { - const satelliteGroup = this.satellites?.getSatellitegroup() as SatelliteGroup; + const satelliteGroup = + this.satellites?.getSatellitegroup() as SatelliteGroup; if (satelliteGroup) { return satelliteGroup.hasSat(satelliteIdx); @@ -193,7 +196,7 @@ class Viewer { }); let satIdx = -1; - let satellite; + let satellite: SatelliteObject | undefined; if (satelliteIds && satelliteIds.length > 0) { // This is the first possible satellite, it is the closest to the camera satIdx = satelliteIds[0]; @@ -203,7 +206,7 @@ class Viewer { this.selectedSatelliteIdx = satIdx; this.satellites?.setSelectedSatellite(satIdx); this.orbits?.setSelectedSatellite(satIdx); - this.eventManager.fireEvent('selectedSatChange', satellite); + this.eventManager.fireEvent(Events.selectedSatChange, satellite); } onMouseMove () { @@ -244,7 +247,12 @@ class Viewer { this.satellites?.setHoverSatellite(satIdx); this.orbits?.setHoverSatellite(satIdx); - this.eventManager.fireEvent('sathoverChange', satellite); + this.eventManager.fireEvent(Events.satHover, { + satellite, + satId: satIdx, + satX: event.clientX, + satY: event.clientY, + }); this.mouseMoved = true; } @@ -285,7 +293,7 @@ class Viewer { this.context.satelliteStore = this.satelliteStore; this.context.shaderStore = this.shaderStore; - this.satelliteStore.addEventListener('satdataloaded', this.onSatDataLoaded.bind(this)); + this.satelliteStore.addEventListener(Events.satDataLoaded, this.onSatDataLoaded.bind(this)); this.earth = new Earth(); await this.registerSceneComponent('earth', this.earth); From 9468b1ba6497ba8045c4c3361a840400afb8efef Mon Sep 17 00:00:00 2001 From: Theodore Kruczek Date: Fri, 29 Dec 2023 18:38:05 -0500 Subject: [PATCH 2/3] refactor: :recycle: add event files from SatelliteStore Missed these when trying to commit changes only related to the events --- src/viewer/SatelliteStore.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/viewer/SatelliteStore.ts b/src/viewer/SatelliteStore.ts index 33663fc..45c5e5f 100644 --- a/src/viewer/SatelliteStore.ts +++ b/src/viewer/SatelliteStore.ts @@ -1,7 +1,8 @@ import axios from 'axios'; import EventManager from '../utils/event-manager'; import logger from '../utils/logger'; -import { SatelliteObject } from './interfaces/SatelliteObject'; +import { SatelliteObject } from '../common/interfaces/SatelliteObject'; +import Events from '@/common/interfaces/Events'; const config = { baseUrl: import.meta.env.BASE_URL @@ -58,7 +59,7 @@ class SatelliteStore { } } - this.eventManager.fireEvent('satdataloaded', this.satData); + this.eventManager.fireEvent(Events.satDataLoaded, this.satData); this.loaded = true; } catch (error) { logger.error('error loading TLE data', error); @@ -78,7 +79,7 @@ class SatelliteStore { this.gotExtraData = includesExtraData; if (includesExtraData) { - this.eventManager.fireEvent('satextradataloaded', this.satData); + this.eventManager.fireEvent(Events.satDataLoaded, this.satData); } } From 79b260db4a833b5986b0a4de86f78ee6fca8d67e Mon Sep 17 00:00:00 2001 From: Theodore Kruczek Date: Mon, 8 Jan 2024 21:06:59 -0500 Subject: [PATCH 3/3] refactor: :truck: move enum to enum folder --- src/common/{interfaces => enums}/Events.ts | 0 src/common/interfaces/EventData.ts | 2 +- src/hud/HudWindow.ts | 2 +- src/hud/index.ts | 2 +- src/utils/event-manager.ts | 2 +- src/viewer/SatelliteStore.ts | 2 +- src/viewer/index.ts | 2 +- 7 files changed, 6 insertions(+), 6 deletions(-) rename src/common/{interfaces => enums}/Events.ts (100%) diff --git a/src/common/interfaces/Events.ts b/src/common/enums/Events.ts similarity index 100% rename from src/common/interfaces/Events.ts rename to src/common/enums/Events.ts diff --git a/src/common/interfaces/EventData.ts b/src/common/interfaces/EventData.ts index 0d58dd8..645cb46 100644 --- a/src/common/interfaces/EventData.ts +++ b/src/common/interfaces/EventData.ts @@ -1,5 +1,5 @@ import { SatelliteObject } from '@/common/interfaces/SatelliteObject'; -import Events from './Events'; +import Events from '../enums/Events'; /** * Represents the data structure for various events in the application. diff --git a/src/hud/HudWindow.ts b/src/hud/HudWindow.ts index ec1e8f4..399551d 100644 --- a/src/hud/HudWindow.ts +++ b/src/hud/HudWindow.ts @@ -1,4 +1,4 @@ -import Events from '@/common/interfaces/Events'; +import Events from '@/common/enums/Events'; class Window { element?: HTMLElement; diff --git a/src/hud/index.ts b/src/hud/index.ts index 2c46f9c..17c0fb1 100644 --- a/src/hud/index.ts +++ b/src/hud/index.ts @@ -4,7 +4,7 @@ import { Viewer } from '@satellite-viewer/index'; import HudWindowManager from './HudWindowManager'; import searchBox from './SearchBox'; import { SatelliteObject } from '@/common/interfaces/SatelliteObject'; -import Events from '@/common/interfaces/Events'; +import Events from '@/common/enums/Events'; import EventData from '@/common/interfaces/EventData'; const supporteEvents: string[] = []; diff --git a/src/utils/event-manager.ts b/src/utils/event-manager.ts index 02cf226..0b2676a 100644 --- a/src/utils/event-manager.ts +++ b/src/utils/event-manager.ts @@ -1,5 +1,5 @@ import EventData from '@/common/interfaces/EventData'; -import Events from '@/common/interfaces/Events'; +import Events from '@/common/enums/Events'; class EventManager { listeners: Record> = {}; diff --git a/src/viewer/SatelliteStore.ts b/src/viewer/SatelliteStore.ts index 45c5e5f..2c6ac60 100644 --- a/src/viewer/SatelliteStore.ts +++ b/src/viewer/SatelliteStore.ts @@ -2,7 +2,7 @@ import axios from 'axios'; import EventManager from '../utils/event-manager'; import logger from '../utils/logger'; import { SatelliteObject } from '../common/interfaces/SatelliteObject'; -import Events from '@/common/interfaces/Events'; +import Events from '@/common/enums/Events'; const config = { baseUrl: import.meta.env.BASE_URL diff --git a/src/viewer/index.ts b/src/viewer/index.ts index a959003..c9bbde8 100644 --- a/src/viewer/index.ts +++ b/src/viewer/index.ts @@ -17,7 +17,7 @@ import ShaderStore from './ShaderStore'; import logger from '@/utils/logger'; import { ArrowHelper, Raycaster, Vector2, Vector3 } from 'three'; import { SatelliteObject } from '../common/interfaces/SatelliteObject'; -import Events from '@/common/interfaces/Events'; +import Events from '@/common/enums/Events'; class Viewer { config: Record = {