From a4cea190b6169573b4274ee0d8351277ceef367e Mon Sep 17 00:00:00 2001 From: hongfaqiu <951142905@qq.com> Date: Wed, 30 Oct 2024 15:28:45 +0800 Subject: [PATCH] fix: resolve options deep copy issue in deepMerge function --- example/CHANGELOG.md | 7 ++++ example/package.json | 2 +- packages/cesium-wind-layer/CHANGELOG.md | 6 ++++ packages/cesium-wind-layer/package.json | 2 +- packages/cesium-wind-layer/src/index.ts | 30 +++++++++++++++- packages/cesium-wind-layer/src/utils.ts | 34 +++++++++++++++++++ .../src/windParticleSystem.ts | 6 ++-- .../src/windParticlesComputing.ts | 3 +- .../src/windParticlesRendering.ts | 3 +- 9 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 packages/cesium-wind-layer/src/utils.ts diff --git a/example/CHANGELOG.md b/example/CHANGELOG.md index f3ab59a..86b196c 100644 --- a/example/CHANGELOG.md +++ b/example/CHANGELOG.md @@ -1,5 +1,12 @@ # example +## 0.4.3 + +### Patch Changes + +- Updated dependencies + - cesium-wind-layer@0.7.2 + ## 0.4.2 ### Patch Changes diff --git a/example/package.json b/example/package.json index c48ea58..7a4140f 100644 --- a/example/package.json +++ b/example/package.json @@ -1,7 +1,7 @@ { "name": "example", "private": true, - "version": "0.4.2", + "version": "0.4.3", "type": "module", "scripts": { "dev": "vite", diff --git a/packages/cesium-wind-layer/CHANGELOG.md b/packages/cesium-wind-layer/CHANGELOG.md index aa46d7d..a021a37 100644 --- a/packages/cesium-wind-layer/CHANGELOG.md +++ b/packages/cesium-wind-layer/CHANGELOG.md @@ -1,5 +1,11 @@ # cesium-wind-layer +## 0.7.2 + +### Patch Changes + +- fix: resolve options deep copy issue in deepMerge function + ## 0.7.1 ### Patch Changes diff --git a/packages/cesium-wind-layer/package.json b/packages/cesium-wind-layer/package.json index 1fa727d..e6ccd79 100644 --- a/packages/cesium-wind-layer/package.json +++ b/packages/cesium-wind-layer/package.json @@ -1,6 +1,6 @@ { "name": "cesium-wind-layer", - "version": "0.7.1", + "version": "0.7.2", "publishConfig": { "access": "public" }, diff --git a/packages/cesium-wind-layer/src/index.ts b/packages/cesium-wind-layer/src/index.ts index 4556e6e..d7320ff 100644 --- a/packages/cesium-wind-layer/src/index.ts +++ b/packages/cesium-wind-layer/src/index.ts @@ -9,6 +9,7 @@ import { import { WindLayerOptions, WindData, WindDataAtLonLat } from './types'; import { WindParticleSystem } from './windParticleSystem'; +import { deepMerge } from './utils'; export * from './types'; @@ -308,13 +309,17 @@ export class WindLayer { */ updateOptions(options: Partial): void { if (this._isDestroyed) return; - this.options = { ...this.options, ...options }; + this.options = deepMerge(options, this.options); this.particleSystem.changeOptions(options); this.viewer.scene.requestRender(); // Dispatch options change event this.dispatchEvent('optionsChange', this.options); } + /** + * Zoom to the wind data bounds. + * @param {number} [duration=0] - The duration of the zoom animation. + */ zoomTo(duration: number = 0): void { if (this.windData.bounds) { const rectangle = Rectangle.fromDegrees( @@ -330,6 +335,9 @@ export class WindLayer { } } + /** + * Add the wind layer to the scene. + */ add(): void { this.primitives = this.particleSystem.getPrimitives(); this.primitives.forEach(primitive => { @@ -337,6 +345,9 @@ export class WindLayer { }); } + /** + * Remove the wind layer from the scene. + */ remove(): void { this.primitives.forEach(primitive => { this.scene.primitives.remove(primitive); @@ -344,10 +355,17 @@ export class WindLayer { this.primitives = []; } + /** + * Check if the wind layer is destroyed. + * @returns {boolean} - True if the wind layer is destroyed, otherwise false. + */ isDestroyed(): boolean { return this._isDestroyed; } + /** + * Destroy the wind layer and release all resources. + */ destroy(): void { this.remove(); this.removeEventListeners(); @@ -364,6 +382,11 @@ export class WindLayer { }); } + /** + * Add an event listener for the specified event type. + * @param {WindLayerEventType} type - The type of event to listen for. + * @param {WindLayerEventCallback} callback - The callback function to execute when the event occurs. + */ addEventListener(type: WindLayerEventType, callback: WindLayerEventCallback) { if (!this.eventListeners.has(type)) { this.eventListeners.set(type, new Set()); @@ -371,6 +394,11 @@ export class WindLayer { this.eventListeners.get(type)?.add(callback); } + /** + * Remove an event listener for the specified event type. + * @param {WindLayerEventType} type - The type of event to remove. + * @param {WindLayerEventCallback} callback - The callback function to remove. + */ removeEventListener(type: WindLayerEventType, callback: WindLayerEventCallback) { this.eventListeners.get(type)?.delete(callback); } diff --git a/packages/cesium-wind-layer/src/utils.ts b/packages/cesium-wind-layer/src/utils.ts new file mode 100644 index 0000000..9f589d3 --- /dev/null +++ b/packages/cesium-wind-layer/src/utils.ts @@ -0,0 +1,34 @@ +export function deepMerge>(from: Partial, to: T): T { + // Handle null or undefined cases + if (!from) return to; + if (!to) return from as T; + + // Create a new object to avoid modifying the original + const result = { ...to }; + + for (const key in from) { + if (Object.prototype.hasOwnProperty.call(from, key)) { + const fromValue = from[key]; + const toValue = to[key]; + + // Handle array case + if (Array.isArray(fromValue)) { + result[key] = fromValue.slice(); + continue; + } + + // Handle object case + if (fromValue && typeof fromValue === 'object') { + result[key] = deepMerge(fromValue, toValue || {}) as T[Extract]; + continue; + } + + // Handle primitive values + if (fromValue !== undefined) { + result[key] = fromValue; + } + } + } + + return result; +} diff --git a/packages/cesium-wind-layer/src/windParticleSystem.ts b/packages/cesium-wind-layer/src/windParticleSystem.ts index a396fb2..041df9e 100644 --- a/packages/cesium-wind-layer/src/windParticleSystem.ts +++ b/packages/cesium-wind-layer/src/windParticleSystem.ts @@ -3,6 +3,7 @@ import { WindParticlesComputing } from './windParticlesComputing'; import { WindParticlesRendering } from './windParticlesRendering'; import CustomPrimitive from './customPrimitive'; import { ClearCommand, Color, Pass } from 'cesium'; +import { deepMerge } from './utils'; export class WindParticleSystem { computing: WindParticlesComputing; @@ -50,10 +51,7 @@ export class WindParticleSystem { maxParticlesChanged = true; } - const newOptions = { - ...this.options, - ...options - } + const newOptions = deepMerge(options, this.options); if (newOptions.particlesTextureSize < 1) { throw new Error('particlesTextureSize must be greater than 0'); } diff --git a/packages/cesium-wind-layer/src/windParticlesComputing.ts b/packages/cesium-wind-layer/src/windParticlesComputing.ts index 46dff24..ddc3303 100644 --- a/packages/cesium-wind-layer/src/windParticlesComputing.ts +++ b/packages/cesium-wind-layer/src/windParticlesComputing.ts @@ -2,6 +2,7 @@ import { PixelDatatype, PixelFormat, Sampler, Texture, TextureMagnificationFilte import { WindLayerOptions, WindData } from './types'; import { ShaderManager } from './shaderManager'; import CustomPrimitive from './customPrimitive' +import { deepMerge } from './utils'; export class WindParticlesComputing { context: any; @@ -221,7 +222,7 @@ export class WindParticlesComputing { updateOptions(options: Partial) { const needUpdateWindTextures = options.flipY !== this.options.flipY; - this.options = { ...this.options, ...options }; + this.options = deepMerge(options, this.options); if (needUpdateWindTextures) { this.reCreateWindTextures(); } diff --git a/packages/cesium-wind-layer/src/windParticlesRendering.ts b/packages/cesium-wind-layer/src/windParticlesRendering.ts index e37a491..eb04f53 100644 --- a/packages/cesium-wind-layer/src/windParticlesRendering.ts +++ b/packages/cesium-wind-layer/src/windParticlesRendering.ts @@ -3,6 +3,7 @@ import { WindLayerOptions } from './types'; import { WindParticlesComputing } from './windParticlesComputing'; import CustomPrimitive from './customPrimitive'; import { ShaderManager } from './shaderManager'; +import { deepMerge } from './utils'; export class WindParticlesRendering { private context: any; @@ -251,7 +252,7 @@ export class WindParticlesRendering { JSON.stringify(options.colors) !== JSON.stringify(this.options.colors); // Update options first - this.options = { ...this.options, ...options }; + this.options = deepMerge(options, this.options); // Then update color table if needed if (needUpdateColorTable) {