浏览代码

[ts] Closes #2370, added SpineCanvas.dispose and callback.

Mario Zechner 2 年之前
父节点
当前提交
c198203695
共有 2 个文件被更改,包括 18 次插入5 次删除
  1. 2 1
      CHANGELOG.md
  2. 16 4
      spine-ts/spine-webgl/src/SpineCanvas.ts

+ 2 - 1
CHANGELOG.md

@@ -104,7 +104,7 @@
   * Tint Black: Added support for [Tint Black](http://en.esotericsoftware.com/spine-slots#Tint-black) functionality at all Spine URP shaders (2D and 3D shaders) and at all standard pipeline `Spine/Sprite` shaders. This feature can be enabled via the `Tint Black` material parameter in the Inspector. Note: The URP Sprite shaders provided in the Spine URP Shaders extension UPM package require the latest version of the spine-unity runtime (package version 4.1.12, 2023-05-31 or newer) to display the added material parameters in the Inspector GUI.
   * Added `SkeletonGraphic.MeshScale` property to allow access to calculated mesh scale. `MeshScale` is based on (1) Canvas pixels per unit, and (2) `RectTransform` bounds when using `Layout Scale Mode` other than `None` at `SkeletonGraphic` which scales the skeleton mesh to fit the parent `RectTransform` bounds accordingly.
   * Added `updateSeparatorPartScale` property to `SkeletonGraphic` to let render separator parts follow the scale (lossy scale) of the `SkeletonGraphic` GameObject. Defaults to `false` to maintain existing behaviour.
-  * Added experimental `EditorSkeletonPlayer` component to allow Editor playback of the initial animation set at `SkeletonAnimation` or `SkeletonGraphic` components. Add this component to your skeleton GameObject to enable the in-editor animation preview. Allows configurations for continuous playback when selected, deselected, and alternative single-frame preview by setting `Fixed Track Time` to any value other than 0. Limitations: At skeletons with variable material count the Inspector preview may be too unresponsive. It is then recommended to disable the `EditorSkeletonPlayer` component (at the top of the Inspector) to make it responsive again, then you can disable `Play When Selected` and re-enable the component to preview playback only when deselected. 
+  * Added experimental `EditorSkeletonPlayer` component to allow Editor playback of the initial animation set at `SkeletonAnimation` or `SkeletonGraphic` components. Add this component to your skeleton GameObject to enable the in-editor animation preview. Allows configurations for continuous playback when selected, deselected, and alternative single-frame preview by setting `Fixed Track Time` to any value other than 0. Limitations: At skeletons with variable material count the Inspector preview may be too unresponsive. It is then recommended to disable the `EditorSkeletonPlayer` component (at the top of the Inspector) to make it responsive again, then you can disable `Play When Selected` and re-enable the component to preview playback only when deselected.
   * Added example component `RenderCombinedMesh` to render a combined mesh of multiple meshes or submeshes. This is required by `OutlineOnly` shaders to render a combined outline when using `SkeletonRenderSeparator` or multiple atlas pages which would normally lead to outlines around individual parts. To add a combined outline to your SkeletenRenderer:
     1) Add a child GameObject and move it a bit back (e.g. position Z = 0.01).
     2) Add a `RenderCombinedMesh` component, provided in the `Spine Examples/Scripts/Sample Components` directory.
@@ -168,6 +168,7 @@
 ### WebGL backend
   * `PolygonBatcher` can now disable culling automatically if the static variable `PolygonBatcher.disableCulling` is set to true.
   * Added `SpineCanvas`, a simpler way to render a scene via spine-webgl. See `spine-ts/spine-webgl/examples/barebones.html` and `spine-ts/spine-webgl/examples/mix-and-match.html`.
+  * Added `SpineCanavs.dispose()` to halt the updating and rendering of the canvas.
 
 ### Canvas backend
   * Improved example.

+ 16 - 4
spine-ts/spine-webgl/src/SpineCanvas.ts

@@ -32,12 +32,12 @@ import { TimeKeeper, AssetManager, ManagedWebGLRenderingContext, SceneRenderer,
 /** An app running inside a {@link SpineCanvas}. The app life-cycle
  * is as follows:
  *
- * 1. `loadAssets()` is called. The app can queue assets for loading via {@link SpineCanvas#assetManager}.
+ * 1. `loadAssets()` is called. The app can queue assets for loading via {@link SpineCanvas.assetManager}.
  * 2. `initialize()` is called when all assets are loaded. The app can setup anything it needs to enter the main application logic.
  * 3. `update()` is called periodically at screen refresh rate. The app can update its state.
- * 4. `render()` is called periodically at screen refresh rate. The app can render its state via {@link SpineCanvas#renderer} or directly via the WebGL context in {@link SpineCanvas.gl}`
+ * 4. `render()` is called periodically at screen refresh rate. The app can render its state via {@link SpineCanvas.renderer} or directly via the WebGL context in {@link SpineCanvas.gl}.
  *
- * The `error()` method is called in case the assets could not be loaded.
+ * The `error()` method is called in case the assets could not be loaded. The `dispose()` method is called in case the canvas has been disposed via {@link SpineCanvas.dispose}.
  */
 export interface SpineCanvasApp {
 	loadAssets?(canvas: SpineCanvas): void;
@@ -45,6 +45,7 @@ export interface SpineCanvasApp {
 	update?(canvas: SpineCanvas, delta: number): void;
 	render?(canvas: SpineCanvas): void;
 	error?(canvas: SpineCanvas, errors: StringMap<string>): void;
+	dispose?(canvas: SpineCanvas): void;
 }
 
 /** Configuration passed to the {@link SpineCanvas} constructor */
@@ -75,8 +76,10 @@ export class SpineCanvas {
 	/** The input processor used to listen to mouse, touch, and keyboard events. */
 	readonly input: Input;
 
+	private disposed = false;
+
 	/** Constructs a new spine canvas, rendering to the provided HTML canvas. */
-	constructor (canvas: HTMLCanvasElement, config: SpineCanvasConfig) {
+	constructor (canvas: HTMLCanvasElement, private config: SpineCanvasConfig) {
 		if (!config.pathPrefix) config.pathPrefix = "";
 		if (!config.app) config.app = {
 			loadAssets: () => { },
@@ -84,6 +87,7 @@ export class SpineCanvas {
 			update: () => { },
 			render: () => { },
 			error: () => { },
+			dispose: () => { },
 		}
 		if (config.webglConfig) config.webglConfig = { alpha: true };
 
@@ -97,6 +101,7 @@ export class SpineCanvas {
 		if (config.app.loadAssets) config.app.loadAssets(this);
 
 		let loop = () => {
+			if (this.disposed) return;
 			requestAnimationFrame(loop);
 			this.time.update();
 			if (config.app.update) config.app.update(this, this.time.delta);
@@ -104,6 +109,7 @@ export class SpineCanvas {
 		}
 
 		let waitForAssets = () => {
+			if (this.disposed) return;
 			if (this.assetManager.isLoadingComplete()) {
 				if (this.assetManager.hasErrors()) {
 					if (config.app.error) config.app.error(this, this.assetManager.getErrors());
@@ -123,4 +129,10 @@ export class SpineCanvas {
 		this.gl.clearColor(r, g, b, a);
 		this.gl.clear(this.gl.COLOR_BUFFER_BIT);
 	}
+
+	/** Disposes the app, so the update() and render() functions are no longer called. Calls the dispose() callback.*/
+	dispose() {
+		if (this.config.app.dispose) this.config.app.dispose(this);
+		this.disposed = true;
+	}
 }