Merge branch '4.1' into 4.2-beta

# Conflicts:
#	spine-ts/package-lock.json
#	spine-ts/package.json
#	spine-ts/spine-canvas/package.json
#	spine-ts/spine-core/package.json
#	spine-ts/spine-phaser/package.json
#	spine-ts/spine-pixi/package.json
#	spine-ts/spine-player/package.json
#	spine-ts/spine-threejs/package.json
#	spine-ts/spine-webgl/package.json
This commit is contained in:
Mario Zechner 2023-09-22 16:06:38 +02:00
commit 1e657e8cac
4 changed files with 23 additions and 10 deletions

View File

@ -235,6 +235,7 @@
### WebGL backend ### WebGL backend
* `PolygonBatcher` can now disable culling automatically if the static variable `PolygonBatcher.disableCulling` is set to true. * `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 `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 ### Canvas backend
* Improved example. * Improved example.

View File

@ -29,7 +29,7 @@
import { TextureAtlas } from "@esotericsoftware/spine-core"; import { TextureAtlas } from "@esotericsoftware/spine-core";
import { SpineTexture } from "../SpineTexture"; import { SpineTexture } from "../SpineTexture";
import type { AssetExtension, LoadAsset, Loader } from "@pixi/assets"; import type { AssetExtension, Loader } from "@pixi/assets";
import { LoaderParserPriority, checkExtension } from "@pixi/assets"; import { LoaderParserPriority, checkExtension } from "@pixi/assets";
import type { Texture } from "@pixi/core"; import type { Texture } from "@pixi/core";
import { ExtensionType, settings, utils, BaseTexture, extensions } from "@pixi/core"; import { ExtensionType, settings, utils, BaseTexture, extensions } from "@pixi/core";
@ -58,7 +58,7 @@ const spineTextureAtlasLoader: AssetExtension<RawAtlas | TextureAtlas, ISpineAtl
return txt; return txt;
}, },
testParse(asset: unknown, options: LoadAsset): Promise<boolean> { testParse(asset: unknown, options: {src: string}): Promise<boolean> {
const isExtensionRight = checkExtension(options.src, ".atlas"); const isExtensionRight = checkExtension(options.src, ".atlas");
const isString = typeof asset === "string"; const isString = typeof asset === "string";
@ -69,7 +69,7 @@ const spineTextureAtlasLoader: AssetExtension<RawAtlas | TextureAtlas, ISpineAtl
atlas.dispose(); atlas.dispose();
}, },
async parse(asset: RawAtlas, options: LoadAsset, loader: Loader): Promise<TextureAtlas> { async parse(asset: RawAtlas, options: {src: string, data: ISpineAtlasMetadata}, loader: Loader): Promise<TextureAtlas> {
const metadata: ISpineAtlasMetadata = options.data || {}; const metadata: ISpineAtlasMetadata = options.data || {};
let basePath = utils.path.dirname(options.src); let basePath = utils.path.dirname(options.src);

View File

@ -27,7 +27,7 @@
* SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
import type { AssetExtension, LoadAsset } from "@pixi/assets"; import type { AssetExtension } from "@pixi/assets";
import { LoaderParserPriority, checkExtension } from "@pixi/assets"; import { LoaderParserPriority, checkExtension } from "@pixi/assets";
import { ExtensionType, settings, extensions } from "@pixi/core"; import { ExtensionType, settings, extensions } from "@pixi/core";
@ -62,7 +62,7 @@ const spineLoaderExtension: AssetExtension<SkeletonJsonAsset | SkeletonBinaryAss
return buffer; return buffer;
}, },
testParse(asset: unknown, options: LoadAsset): Promise<boolean> { testParse(asset: unknown, options: {src: string}): Promise<boolean> {
const isJsonSpineModel = checkExtension(options.src, ".json") && isJson(asset); const isJsonSpineModel = checkExtension(options.src, ".json") && isJson(asset);
const isBinarySpineModel = checkExtension(options.src, ".skel") && isBuffer(asset); const isBinarySpineModel = checkExtension(options.src, ".skel") && isBuffer(asset);

View File

@ -32,12 +32,12 @@ import { TimeKeeper, AssetManager, ManagedWebGLRenderingContext, SceneRenderer,
/** An app running inside a {@link SpineCanvas}. The app life-cycle /** An app running inside a {@link SpineCanvas}. The app life-cycle
* is as follows: * 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. * 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. * 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 { export interface SpineCanvasApp {
loadAssets?(canvas: SpineCanvas): void; loadAssets?(canvas: SpineCanvas): void;
@ -45,6 +45,7 @@ export interface SpineCanvasApp {
update?(canvas: SpineCanvas, delta: number): void; update?(canvas: SpineCanvas, delta: number): void;
render?(canvas: SpineCanvas): void; render?(canvas: SpineCanvas): void;
error?(canvas: SpineCanvas, errors: StringMap<string>): void; error?(canvas: SpineCanvas, errors: StringMap<string>): void;
dispose?(canvas: SpineCanvas): void;
} }
/** Configuration passed to the {@link SpineCanvas} constructor */ /** 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. */ /** The input processor used to listen to mouse, touch, and keyboard events. */
readonly input: Input; readonly input: Input;
private disposed = false;
/** Constructs a new spine canvas, rendering to the provided HTML canvas. */ /** 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.pathPrefix) config.pathPrefix = "";
if (!config.app) config.app = { if (!config.app) config.app = {
loadAssets: () => { }, loadAssets: () => { },
@ -84,6 +87,7 @@ export class SpineCanvas {
update: () => { }, update: () => { },
render: () => { }, render: () => { },
error: () => { }, error: () => { },
dispose: () => { },
} }
if (!config.webglConfig) config.webglConfig = { alpha: true }; if (!config.webglConfig) config.webglConfig = { alpha: true };
@ -97,6 +101,7 @@ export class SpineCanvas {
if (config.app.loadAssets) config.app.loadAssets(this); if (config.app.loadAssets) config.app.loadAssets(this);
let loop = () => { let loop = () => {
if (this.disposed) return;
requestAnimationFrame(loop); requestAnimationFrame(loop);
this.time.update(); this.time.update();
if (config.app.update) config.app.update(this, this.time.delta); if (config.app.update) config.app.update(this, this.time.delta);
@ -104,6 +109,7 @@ export class SpineCanvas {
} }
let waitForAssets = () => { let waitForAssets = () => {
if (this.disposed) return;
if (this.assetManager.isLoadingComplete()) { if (this.assetManager.isLoadingComplete()) {
if (this.assetManager.hasErrors()) { if (this.assetManager.hasErrors()) {
if (config.app.error) config.app.error(this, this.assetManager.getErrors()); 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.clearColor(r, g, b, a);
this.gl.clear(this.gl.COLOR_BUFFER_BIT); 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;
}
} }