How Data Layers Are Registered and Managed in God’s Eye View
God’s Eye View centralizes all overlay logic in a DataLayerManager class that stores layers in an internal Map, seals the registry with finalizeRegistrations, and exposes deterministic APIs for toggling, enabling, and refreshing each source.
The bilawalsidhu/gods-eye-view repository relies on this manager to coordinate real-time data overlays such as flights, earthquakes, and CCTV feeds. Understanding how data layers are registered and managed in God’s Eye View is essential for anyone extending the codebase or debugging layer state issues.
The DataLayerManager Core
At the heart of the system is the DataLayerManager class defined in src/data/manager.js. The manager maintains a private this.layers structure—specifically a Map—where each entry tracks the layer module, its visibility state, lifecycle metadata, refresh timers, and event listeners. This single source of truth is initialized in the class constructor around lines 18–26 of src/data/manager.js.
Step 1: Registering Data Layers
Bootstrap Registration in main.js
Layer registration begins during application bootstrap inside src/main.js. Each data source is implemented as a module that exports a stable id. These modules are passed to DataLayerManager.register() for production builds, or to registerForQa() when running in development mode, as shown in lines 9–26 of src/main.js.
Internal Map Storage
Once register() is invoked, the manager inserts a record into this.layers. The record holds the module reference, default visibility flags, and placeholders for lifecycle state. You can inspect this initialization logic in the DataLayerManager constructor in src/data/manager.js at lines 18–26.
Step 2: Finalizing the Registry
After all production layers have been added, the bootstrap sequence calls DataLayerManager.finalizeRegistrations() with a static LAYER_STATE_REGISTRY. This step performs a strict consistency check: every registered layer must declare a serialization disposition, and no stray identifiers are permitted. Only after this call succeeds are the layers considered sealed and usable by the rest of the application. See the implementation in src/data/manager.js, lines 18–38.
Step 3: Runtime Visibility and Lifecycle Control
Toggling Layers with toggle()
The toggle(layerId, options) method flips a layer’s enabled state. It is designed to respect any ongoing lifecycle work by queueing the request rather than interrupting in-flight transitions, which prevents race conditions. This logic resides in src/data/manager.js, lines 40–52.
Deterministic State Changes with setEnabled()
For explicit control—whether from UI clicks, voice commands, or scene scripts—the manager exposes setEnabled(layerId, shouldEnable, options). This deterministic helper internally delegates to _setEnabledWithIntent(), which creates an intent epoch, records the request, and serializes the lifecycle transition so that overlapping calls do not corrupt state. Review this flow in src/data/manager.js, lines 58–71.
Lifecycle States and UI Synchronization
Every layer moves through well-defined states: enabling, enabled, disabling, and disabled. The manager drives these transitions by invoking the layer’s own init(), enable(), update(), and disable() methods at the appropriate times. After a transition completes, the manager synchronizes the toggle panel via _refreshTogglePanel() and notifies detection consumers through markDetectionSourcesChanged(). These mechanisms are implemented in src/data/manager.js, lines 89–106 and 137–148.
Periodic Refresh and Event Broadcasting
For layers that specify a refreshInterval, the manager arms a timer via setInterval that triggers _runPeriodicUpdate(). The refresh loop updates the layer data, requests a render, and then notifies listeners of success or failure. Timer setup appears around lines 22–33 of src/data/manager.js, while the update and notification logic spans lines 88–100.
State changes emit structured events such as visibility-will-change, visibility, refresh, and refresh-failed. UI components and voice handlers subscribe to these events through dataManager.subscribe(), as shown in lines 84–92 of src/data/manager.js.
Code Example: Registering and Controlling a Layer
The following pattern demonstrates the full registration and management sequence used throughout the codebase:
// 1️⃣ Register a custom layer (e.g., a new satellite feed)
import { DataLayerManager } from './data/manager.js';
import mySatelliteLayer from './layers/mySatelliteLayer.js';
const dataManager = new DataLayerManager(viewer);
dataManager.register(mySatelliteLayer); // ← adds to internal Map
// 2️⃣ Finalize the registration set (usually done once at startup)
dataManager.finalizeRegistrations(LAYER_STATE_REGISTRY);
// 3️⃣ Enable the layer via UI or script
await dataManager.setEnabled('my-satellite', true, {
origin: 'user', // marks the intent source
notificationToken: 'ui-click' // optional token for UI correlation
});
// 4️⃣ Toggle a layer (e.g., user clicks the “Traffic” checkbox)
await dataManager.toggle('traffic', {
origin: 'user',
notificationToken: 'traffic-checkbox'
});
// 5️⃣ Force a fresh refresh (useful for voice commands like “refresh flights”)
await dataManager.refreshLayer('flights');
All calls above ultimately route through src/data/manager.js, where intent epochs, lifecycle transitions, and periodic updates are handled.
Summary
DataLayerManagerinsrc/data/manager.jsis the single authority for layer state.- Layers are registered during bootstrap in
src/main.jsand stored in an internalMap. finalizeRegistrations()seals the registry by validating every layer againstLAYER_STATE_REGISTRY.toggle()andsetEnabled()provide deterministic, race-safe visibility control.- Lifecycle methods (
init,enable,update,disable) and periodic refresh timers keep overlays current. - Structured events broadcast state changes to UI, voice, and scene subsystems.
Frequently Asked Questions
What class is responsible for data layer registration and management in God’s Eye View?
The DataLayerManager class defined in src/data/manager.js is responsible. It exposes register(), finalizeRegistrations(), toggle(), setEnabled(), and refreshLayer() to coordinate every overlay’s lifecycle.
How does God’s Eye View prevent race conditions when toggling layers?
The manager queues toggle requests rather than allowing them to interrupt active lifecycle transitions. The setEnabled() path uses _setEnabledWithIntent() to create an intent epoch, which serializes overlapping calls and guarantees deterministic state.
Why is finalizeRegistrations required before layers can be used?
finalizeRegistrations() performs a consistency check against LAYER_STATE_REGISTRY to ensure every registered layer has a valid serialization disposition and that no stray IDs exist. This step seals the registry so that runtime code operates on a validated, immutable layer set.
Which other modules integrate with DataLayerManager?
Beyond the core src/data/manager.js implementation, src/main.js handles bootstrap registration, src/ui.js wires checkboxes and menus to toggle() and setEnabled(), src/voice/gevActions.js enables voice-driven layer control, and src/scenes/director.js manipulates layers during scripted scene playback.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →