diff --git a/.github/workflows/build-wasm-libs.yml b/.github/workflows/build-wasm-libs.yml index 6fcd7121304..dfabe4e0f75 100644 --- a/.github/workflows/build-wasm-libs.yml +++ b/.github/workflows/build-wasm-libs.yml @@ -40,6 +40,15 @@ jobs: fi which ninja + - name: Apply emscripten patches + run: | + echo "--------------------------------- Save bind.cpp ---------------------------------" + cp $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp.bak + echo "--------------------------------- Apply embind bind.cpp patches ---------------------------------" + cp -f .github/workflows/emscripten-patches/embind/bind.cpp $EMSDK/upstream/emscripten/system/lib/embind/ + echo "--------------------------------- Apply patches DONE! ---------------------------------" + cat $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp + - name: Build Spine WASM run: | cd ./native/cocos/editor-support/spine-wasm @@ -72,3 +81,11 @@ jobs: with: name: spine-emscripten path: dist + + - name: Restore patches + run: | + echo "-------------------------- Restore patches ---------------------------------" + rm $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp + mv $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp.bak $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp + echo "-------------------------- Restore patches DONE! ---------------------------------" + cat $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp diff --git a/.github/workflows/web-interface-check.yml b/.github/workflows/web-interface-check.yml index 22dfeee8df8..f28a6968a23 100644 --- a/.github/workflows/web-interface-check.yml +++ b/.github/workflows/web-interface-check.yml @@ -20,6 +20,28 @@ jobs: with: node-version: '18.x' + - name: Setup emsdk + uses: dumganhar/setup-emsdk@997d2cde2deabda085a11f98e86e842915b0e846 + with: + version: 3.1.41 + actions-cache-folder: 'emsdk-cache-3.1.41' + + - name: Verify + run: | + which emcc + emcc -v + + - name: Install ninja + run: | + if ! command -v ninja &> /dev/null; then + echo "Ninja not found, installing..." + # sudo apt update + sudo apt install ninja-build + else + echo "Ninja is already installed." + fi + which ninja + - uses: actions/checkout@v4 name: Checkout Base Ref with: @@ -43,6 +65,51 @@ jobs: ref: "${{ env.EXT_VERSION }}" fetch-depth: 1 + - name: Apply emscripten patches (BASE) + run: | + echo "--------------------------------- Save bind.cpp ---------------------------------" + cp $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp.bak + echo "--------------------------------- Apply embind bind.cpp patches ---------------------------------" + cp -f ./engine/.github/workflows/emscripten-patches/embind/bind.cpp $EMSDK/upstream/emscripten/system/lib/embind/ + echo "--------------------------------- Apply patches DONE! ---------------------------------" + cat $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp + + - name: Build Spine WASM (BASE) + run: | + cd ./engine/native/cocos/editor-support/spine-wasm + mkdir build-wasm + cd build-wasm + emcmake cmake .. -GNinja + ninja + ls -l + + - name: Build Spine ASMJS (BASE) + run: | + cd ./engine/native/cocos/editor-support/spine-wasm + sed -i 's/set(BUILD_WASM 1)/set(BUILD_WASM 0)/g' CMakeLists.txt + mkdir build-asmjs + cd build-asmjs + emcmake cmake .. -GNinja + ninja + ls -l + + - name: Copy files to external directory (BASE) + run: | + rm -rf dist + mkdir dist + cp ./engine/native/cocos/editor-support/spine-wasm/build-wasm/spine.wasm ./dist/ + cp ./engine/native/cocos/editor-support/spine-wasm/build-wasm/spine.js ./dist/spine.wasm.js + cp ./engine/native/cocos/editor-support/spine-wasm/build-asmjs/spine.js.mem ./dist/ + cp ./engine/native/cocos/editor-support/spine-wasm/build-asmjs/spine.js ./dist/spine.asm.js + echo "-------- Before replace spine wasm -----------" + ls -l ./engine/native/external/emscripten/spine/ + cp -f ./dist/* ./engine/native/external/emscripten/spine/ + echo "-------- After replace spine wasm ------------" + ls -l ./engine/native/external/emscripten/spine/ + echo "-----------------------------------------------" + cd ./engine/native/external + git status + - name: Build Base Declarations working-directory: ./engine run: | @@ -51,6 +118,14 @@ jobs: node ./.github/workflows/package-size-check.js fi + - name: Restore patches (BASE) + run: | + echo "-------------------------- Restore patches ---------------------------------" + rm $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp + mv $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp.bak $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp + echo "-------------------------- Restore patches DONE! ---------------------------------" + cat $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp + - name: Clear npm Cache run: | npm cache clean --force @@ -99,18 +174,7 @@ jobs: ref: "${{ env.EXT_VERSION_HEAD }}" fetch-depth: 1 - - name: Setup emsdk - uses: dumganhar/setup-emsdk@997d2cde2deabda085a11f98e86e842915b0e846 - with: - version: 3.1.41 - actions-cache-folder: 'emsdk-cache-3.1.41' - - - name: Verify - run: | - which emcc - emcc -v - - - name: Apply emscripten patches + - name: Apply emscripten patches (HEAD) run: | echo "--------------------------------- Save bind.cpp ---------------------------------" cp $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp.bak @@ -119,18 +183,7 @@ jobs: echo "--------------------------------- Apply patches DONE! ---------------------------------" cat $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp - - name: Install ninja - run: | - if ! command -v ninja &> /dev/null; then - echo "Ninja not found, installing..." - # sudo apt update - sudo apt install ninja-build - else - echo "Ninja is already installed." - fi - which ninja - - - name: Build Spine WASM + - name: Build Spine WASM (HEAD) run: | cd ./engine-HEAD/native/cocos/editor-support/spine-wasm mkdir build-wasm @@ -139,7 +192,7 @@ jobs: ninja ls -l - - name: Build Spine ASMJS + - name: Build Spine ASMJS (HEAD) run: | cd ./engine-HEAD/native/cocos/editor-support/spine-wasm sed -i 's/set(BUILD_WASM 1)/set(BUILD_WASM 0)/g' CMakeLists.txt @@ -149,8 +202,9 @@ jobs: ninja ls -l - - name: Copy files to external directory + - name: Copy files to external directory (HEAD) run: | + rm -rf dist mkdir dist cp ./engine-HEAD/native/cocos/editor-support/spine-wasm/build-wasm/spine.wasm ./dist/ cp ./engine-HEAD/native/cocos/editor-support/spine-wasm/build-wasm/spine.js ./dist/spine.wasm.js @@ -162,6 +216,8 @@ jobs: echo "-------- After replace spine wasm ------------" ls -l ./engine-HEAD/native/external/emscripten/spine/ echo "-----------------------------------------------" + cd ./engine-HEAD/native/external + git status - name: Upload Artifact uses: actions/upload-artifact@v4 @@ -175,7 +231,7 @@ jobs: npm install node ./.github/workflows/package-size-check.js - - name: Restore patches + - name: Restore patches (HEAD) run: | echo "-------------------------- Restore patches ---------------------------------" rm $EMSDK/upstream/emscripten/system/lib/embind/bind.cpp diff --git a/cocos/2d/event/pointer-event-dispatcher.ts b/cocos/2d/event/pointer-event-dispatcher.ts index ec4e08f3354..b113538cf38 100644 --- a/cocos/2d/event/pointer-event-dispatcher.ts +++ b/cocos/2d/event/pointer-event-dispatcher.ts @@ -56,10 +56,10 @@ class PointerEventDispatcher implements IEventDispatcher { constructor () { input._registerEventDispatcher(this); - - NodeEventProcessor.callbacksInvoker.on(DispatcherEventType.ADD_POINTER_EVENT_PROCESSOR, this.addPointerEventProcessor, this); - NodeEventProcessor.callbacksInvoker.on(DispatcherEventType.REMOVE_POINTER_EVENT_PROCESSOR, this.removePointerEventProcessor, this); - NodeEventProcessor.callbacksInvoker.on(DispatcherEventType.MARK_LIST_DIRTY, this._markListDirty, this); + const callbacksInvoker = NodeEventProcessor.callbacksInvoker; + callbacksInvoker.on(DispatcherEventType.ADD_POINTER_EVENT_PROCESSOR, this.addPointerEventProcessor, this); + callbacksInvoker.on(DispatcherEventType.REMOVE_POINTER_EVENT_PROCESSOR, this.removePointerEventProcessor, this); + callbacksInvoker.on(DispatcherEventType.MARK_LIST_DIRTY, this._markListDirty, this); } onThrowException (): void { diff --git a/cocos/root.jsb.ts b/cocos/root.jsb.ts index c35e8f1d10e..f95fc5cdc68 100644 --- a/cocos/root.jsb.ts +++ b/cocos/root.jsb.ts @@ -22,10 +22,10 @@ THE SOFTWARE. */ -import { legacyCC } from './core/global-exports'; +import { cclegacy } from './core/global-exports'; import { DataPoolManager } from './3d/skeletal-animation/data-pool-manager'; import { Device, deviceManager } from './gfx'; -import { settings, Settings, warnID, Pool, macro, log, cclegacy } from './core'; +import { settings, Settings, warnID, Pool, macro, log } from './core'; import { PipelineEventProcessor } from './rendering/pipeline-event'; import type { Root as JsbRoot } from './root'; @@ -55,8 +55,8 @@ export interface IRootInfo { const rootProto: any = Root.prototype; rootProto._createBatcher2D = function () { - if (!this._batcher && legacyCC.internal.Batcher2D) { - this._batcher = new legacyCC.internal.Batcher2D(this); + if (!this._batcher && cclegacy.internal.Batcher2D) { + this._batcher = new cclegacy.internal.Batcher2D(this); if (!this._batcher!.initialize()) { this._batcher = null; this.destroy(); @@ -92,7 +92,7 @@ Object.defineProperty(rootProto, 'pipelineEvent', { rootProto._ctor = function (device: Device) { this._device = device; - this._dataPoolMgr = legacyCC.internal.DataPoolManager && new legacyCC.internal.DataPoolManager(device) as DataPoolManager; + this._dataPoolMgr = cclegacy.internal.DataPoolManager && new cclegacy.internal.DataPoolManager(device) as DataPoolManager; this._modelPools = new Map(); this._lightPools = new Map(); this._batcher = null; @@ -201,19 +201,19 @@ rootProto.recycleLight = function (l) { }; rootProto._onDirectorBeforeCommit = function () { - legacyCC.director.emit(legacyCC.Director.EVENT_BEFORE_COMMIT); + cclegacy.director.emit(cclegacy.Director.EVENT_BEFORE_COMMIT); }; rootProto._onDirectorBeforeRender = function () { - legacyCC.director.emit(legacyCC.Director.EVENT_BEFORE_RENDER); + cclegacy.director.emit(cclegacy.Director.EVENT_BEFORE_RENDER); }; rootProto._onDirectorAfterRender = function () { - legacyCC.director.emit(legacyCC.Director.EVENT_AFTER_RENDER); + cclegacy.director.emit(cclegacy.Director.EVENT_AFTER_RENDER); }; rootProto._onDirectorPipelineChanged = function () { - const scene = legacyCC.director.getScene(); + const scene = cclegacy.director.getScene(); if (scene) { scene._activate(); } @@ -222,25 +222,25 @@ rootProto._onDirectorPipelineChanged = function () { const oldOnGlobalPipelineStateChanged = rootProto.onGlobalPipelineStateChanged; rootProto.onGlobalPipelineStateChanged = function() { oldOnGlobalPipelineStateChanged.call(this); - const builder = legacyCC.rendering.getCustomPipeline(macro.CUSTOM_PIPELINE_NAME); + const builder = cclegacy.rendering.getCustomPipeline(macro.CUSTOM_PIPELINE_NAME); if (builder) { if (typeof builder.onGlobalPipelineStateChanged === 'function') { builder.onGlobalPipelineStateChanged(); } - legacyCC.rendering.forceResizeAllWindows(); + cclegacy.rendering.forceResizeAllWindows(); } } const oldFrameMove = rootProto.frameMove; rootProto.frameMove = function (deltaTime: number) { - oldFrameMove.call(this, deltaTime, legacyCC.director.getTotalFrames()); + oldFrameMove.call(this, deltaTime, cclegacy.director.getTotalFrames()); }; const oldSetPipeline = rootProto.setRenderPipeline; rootProto.setRenderPipeline = function (customPipeline: boolean) { let ppl; if (customPipeline) { - legacyCC.rendering.createCustomPipeline(); + cclegacy.rendering.createCustomPipeline(); ppl = oldSetPipeline.call(this, null); log(`Using custom pipeline: ${macro.CUSTOM_PIPELINE_NAME}`); } else { diff --git a/cocos/scene-graph/node-event-processor.ts b/cocos/scene-graph/node-event-processor.ts index da4c3875535..e4b7bb464d6 100644 --- a/cocos/scene-graph/node-event-processor.ts +++ b/cocos/scene-graph/node-event-processor.ts @@ -25,8 +25,8 @@ import { CallbacksInvoker } from '../core/event/callbacks-invoker'; import { Event, EventMouse, EventTouch, Touch } from '../input/types'; import { Vec2 } from '../core/math/vec2'; -import { Node } from './node'; -import { legacyCC } from '../core/global-exports'; +import type { Node } from './node'; +import { cclegacy } from '../core/global-exports'; import { Component } from './component'; import { NodeEventType } from './node-event'; import { InputEventType, SystemEventTypeUnion } from '../input/types/event-enum'; @@ -63,6 +63,8 @@ export enum DispatcherEventType { MARK_LIST_DIRTY, } +const globalCallbacksInvoker = new CallbacksInvoker(); + /** * @en The event processor for Node * @zh 节点事件类。 @@ -75,7 +77,7 @@ export class NodeEventProcessor { /** * @internal */ - public static callbacksInvoker = new CallbacksInvoker(); + public static callbacksInvoker = globalCallbacksInvoker; /** * Whether the node event is enabled @@ -159,7 +161,7 @@ export class NodeEventProcessor { if (value) { this._attachMask(); } - NodeEventProcessor.callbacksInvoker.emit(DispatcherEventType.MARK_LIST_DIRTY); + globalCallbacksInvoker.emit(DispatcherEventType.MARK_LIST_DIRTY); if (recursive && children.length > 0) { for (let i = 0; i < children.length; ++i) { const child = children[i]; @@ -169,12 +171,11 @@ export class NodeEventProcessor { } public reattach (): void { - let currentMaskList: IMask[] | null; this.node.walk((node) => { - if (!currentMaskList) { - currentMaskList = this._searchComponentsInParent(NodeEventProcessor._maskComp); - } - node.eventProcessor.maskList = currentMaskList; + const eventProcessor = node.eventProcessor; + // NOTE: When reattaching the current node, the masks of all its descendants need to be recalculated + const currentMaskList = eventProcessor._searchComponentsInParent(NodeEventProcessor._maskComp); + eventProcessor.maskList = currentMaskList; }); } @@ -185,7 +186,7 @@ export class NodeEventProcessor { if (this.capturingTarget) this.capturingTarget.clear(); if (this.bubblingTarget) this.bubblingTarget.clear(); - NodeEventProcessor.callbacksInvoker.emit(DispatcherEventType.REMOVE_POINTER_EVENT_PROCESSOR, this); + globalCallbacksInvoker.emit(DispatcherEventType.REMOVE_POINTER_EVENT_PROCESSOR, this); if (this._dispatchingTouch) { // Dispatch touch cancel event when node is destroyed. const cancelEvent = new EventTouch([this._dispatchingTouch], true, InputEventType.TOUCH_CANCEL); @@ -245,7 +246,7 @@ export class NodeEventProcessor { this.shouldHandleEventMouse = false; } if (!this._hasPointerListeners()) { - NodeEventProcessor.callbacksInvoker.emit(DispatcherEventType.REMOVE_POINTER_EVENT_PROCESSOR, this); + globalCallbacksInvoker.emit(DispatcherEventType.REMOVE_POINTER_EVENT_PROCESSOR, this); } } @@ -364,7 +365,7 @@ export class NodeEventProcessor { } public onUpdatingSiblingIndex (): void { - NodeEventProcessor.callbacksInvoker.emit(DispatcherEventType.MARK_LIST_DIRTY); + globalCallbacksInvoker.emit(DispatcherEventType.MARK_LIST_DIRTY); } private _searchComponentsInParent (ctor: Constructor | null): IMask[] | null { @@ -372,7 +373,7 @@ export class NodeEventProcessor { if (ctor) { let index = 0; let list: IMask[] = []; - for (let curr: Node | null = node; curr && Node.isNode(curr); curr = curr.parent, ++index) { + for (let curr: Node | null = node; curr && cclegacy.Node.isNode(curr); curr = curr.parent, ++index) { const comp = curr.getComponent(ctor); if (comp) { const next = { @@ -445,7 +446,7 @@ export class NodeEventProcessor { this.shouldHandleEventMouse = true; } if ((isTouchEvent || isMouseEvent) && !this._hasPointerListeners()) { - NodeEventProcessor.callbacksInvoker.emit(DispatcherEventType.ADD_POINTER_EVENT_PROCESSOR, this); + globalCallbacksInvoker.emit(DispatcherEventType.ADD_POINTER_EVENT_PROCESSOR, this); } } @@ -464,7 +465,7 @@ export class NodeEventProcessor { this.shouldHandleEventMouse = false; } if (!this._hasPointerListeners()) { - NodeEventProcessor.callbacksInvoker.emit(DispatcherEventType.REMOVE_POINTER_EVENT_PROCESSOR, this); + globalCallbacksInvoker.emit(DispatcherEventType.REMOVE_POINTER_EVENT_PROCESSOR, this); } }); return callbacksInvoker; @@ -693,4 +694,4 @@ export class NodeEventProcessor { // #endregion handle touch event } -legacyCC.NodeEventProcessor = NodeEventProcessor; +cclegacy.NodeEventProcessor = NodeEventProcessor; diff --git a/cocos/scene-graph/node.jsb.ts b/cocos/scene-graph/node.jsb.ts index 4b99c37f42b..a6585a8ba4a 100644 --- a/cocos/scene-graph/node.jsb.ts +++ b/cocos/scene-graph/node.jsb.ts @@ -21,7 +21,7 @@ */ import { EDITOR, EDITOR_NOT_IN_PREVIEW } from 'internal:constants'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core/global-exports'; import { errorID, getError } from '../core/platform/debug'; import { Component } from './component'; import { NodeEventType } from './node-event'; @@ -38,14 +38,16 @@ import { nodePolyfill } from './node-dev'; import * as js from '../core/utils/js'; import { patch_cc_Node } from '../native-binding/decorators'; import type { Node as JsbNode } from './node'; +import { DispatcherEventType, NodeEventProcessor } from './node-event-processor'; const reserveContentsForAllSyncablePrefabTag = Symbol('ReserveContentsForAllSyncablePrefab'); declare const jsb: any; +declare const EditorExtends: any; export const Node: typeof JsbNode = jsb.Node; export type Node = JsbNode; -legacyCC.Node = Node; +cclegacy.Node = Node; const NodeCls: any = Node; @@ -81,6 +83,7 @@ const TRANSFORMBIT_TRS = TransformBit.TRS; const nodeProto: any = jsb.Node.prototype; export const TRANSFORM_ON = 1 << 0; +const ACTIVE_ON = 1 << 1; const Destroying = CCObject.Flags.Destroying; // TODO: `_setTempFloatArray` is only implemented on Native platforms. @dumganhar @@ -162,7 +165,7 @@ nodeProto.addComponent = function (typeOrClassName) { if (typeof typeOrClassName === 'string') { constructor = getClassByName(typeOrClassName); if (!constructor) { - if (legacyCC._RF.peek()) { + if (cclegacy._RF.peek()) { errorID(3808, typeOrClassName); } throw TypeError(getError(3807, typeOrClassName)); @@ -221,7 +224,7 @@ nodeProto.addComponent = function (typeOrClassName) { } this.emit(NodeEventType.COMPONENT_ADDED, component); if (this._activeInHierarchy) { - legacyCC.director._nodeActivator.activateComp(component); + cclegacy.director._nodeActivator.activateComp(component); } if (EDITOR_NOT_IN_PREVIEW) { component.resetInEditor?.(); @@ -419,7 +422,7 @@ nodeProto._onEditorAttached = function (attached: boolean) { }; nodeProto._onRemovePersistRootNode = function () { - legacyCC.game.removePersistRootNode(this); + cclegacy.game.removePersistRootNode(this); }; nodeProto._onDestroyComponents = function () { @@ -496,11 +499,17 @@ nodeProto._onSiblingOrderChanged = function () { }; nodeProto._onActivateNode = function (shouldActiveNow) { - legacyCC.director._nodeActivator.activateNode(this, shouldActiveNow); + cclegacy.director._nodeActivator.activateNode(this, shouldActiveNow); }; nodeProto._onPostActivated = function (active: boolean) { - this._eventProcessor.setEnabled(active); + const eventProcessor = this._eventProcessor; + if (eventProcessor.isEnabled === active) { + NodeEventProcessor.callbacksInvoker.emit(DispatcherEventType.MARK_LIST_DIRTY); + } + + eventProcessor.setEnabled(active); + if (active) { // in case transform updated during deactivated period this.invalidateChildren(TransformBit.TRS); @@ -598,7 +607,7 @@ NodeCls._findChildComponents = function (children, constructor, components) { // @ts-ignore NodeCls.isNode = function (obj: unknown): obj is jsb.Node { // @ts-ignore - return obj instanceof jsb.Node && (obj.constructor === jsb.Node || !(obj instanceof legacyCC.Scene)); + return obj instanceof jsb.Node && (obj.constructor === jsb.Node || !(obj instanceof cclegacy.Scene)); }; let _tempQuat = new Quat(); @@ -1259,7 +1268,7 @@ nodeProto[serializeTag] = function (serializationOutput: SerializationOutput, co }; nodeProto._onActiveNode = function (shouldActiveNow: boolean) { - legacyCC.director._nodeActivator.activateNode(this, shouldActiveNow); + cclegacy.director._nodeActivator.activateNode(this, shouldActiveNow); }; nodeProto._onBatchCreated = function (dontSyncChildPrefab: boolean) { @@ -1323,7 +1332,7 @@ nodeProto._onLocalPositionRotationScaleUpdated = function (px, py, pz, rx, ry, r nodeProto._instantiate = function (cloned: Node, isSyncedNode: boolean) { if (!cloned) { - cloned = legacyCC.instantiate._clone(this, this); + cloned = cclegacy.instantiate._clone(this, this); } // TODO(PP_Pro): after we support editorOnly tag, we could remove this any type assertion. @@ -1372,7 +1381,7 @@ nodeProto._ctor = function (name?: string) { this.__editorExtras__ = { editorOnly: true }; this._components = []; - this._eventProcessor = new legacyCC.NodeEventProcessor(this); + this._eventProcessor = new NodeEventProcessor(this); this._uiProps = new NodeUIProperties(this); const sharedArrayBuffer = this._initAndReturnSharedBuffer(); diff --git a/cocos/scene-graph/node.ts b/cocos/scene-graph/node.ts index c3710626f84..6865fba97dc 100644 --- a/cocos/scene-graph/node.ts +++ b/cocos/scene-graph/node.ts @@ -26,7 +26,7 @@ import { ccclass, editable, serializable, type } from 'cc.decorator'; import { DEV, DEBUG, EDITOR, EDITOR_NOT_IN_PREVIEW } from 'internal:constants'; import { Layers } from './layers'; import { NodeUIProperties } from './node-ui-properties'; -import { legacyCC } from '../core/global-exports'; +import { cclegacy } from '../core/global-exports'; import { nodePolyfill } from './node-dev'; import { ISchedulable } from '../core/scheduler'; import { approx, EPSILON, Mat3, mat4, Mat4, quat, Quat, v3, Vec3 } from '../core/math'; @@ -36,11 +36,14 @@ import { errorID, warnID, error, log, getError } from '../core/platform/debug'; import { Component } from './component'; import { property } from '../core/data/decorators/property'; import { CCObject, js } from '../core'; -import type { Scene } from './scene'; import { PrefabInfo, PrefabInstance } from './prefab/prefab-info'; import { NodeEventType } from './node-event'; import { Event } from '../input/types'; -import type { NodeEventProcessor } from './node-event-processor'; +import { DispatcherEventType, NodeEventProcessor } from './node-event-processor'; + +import type { Scene } from './scene'; +import type { Director } from '../game/director'; +import type { Game } from '../game/game'; const Destroying = CCObject.Flags.Destroying; const DontDestroy = CCObject.Flags.DontDestroy; @@ -191,7 +194,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { if (parent) { const couldActiveInScene = parent._activeInHierarchy; if (couldActiveInScene) { - legacyCC.director._nodeActivator.activateNode(this, isActive); + (cclegacy.director as Director)._nodeActivator.activateNode(this, isActive); } } } @@ -382,7 +385,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { public set id (v: string) { this._id = v; } protected _id: string = idGenerator.getNewId(); - protected _eventProcessor: NodeEventProcessor = new (legacyCC.NodeEventProcessor as typeof NodeEventProcessor)(this); + protected _eventProcessor: NodeEventProcessor = new NodeEventProcessor(this); protected _eventMask = 0; protected _siblingIndex = 0; @@ -974,7 +977,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { if (typeof typeOrClassName === 'string') { constructor = js.getClassByName(typeOrClassName) as Constructor | undefined; if (!constructor) { - if (legacyCC._RF.peek()) { + if (cclegacy._RF.peek()) { errorID(3808, typeOrClassName); } throw TypeError(getError(3807, typeOrClassName)); @@ -991,7 +994,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { if (typeof constructor !== 'function') { throw TypeError(getError(3809)); } - if (!js.isChildClassOf(constructor, legacyCC.Component)) { + if (!js.isChildClassOf(constructor, cclegacy.Component)) { throw TypeError(getError(3810)); } @@ -1038,7 +1041,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { } this.emit(NodeEventType.COMPONENT_ADDED, component); if (this._activeInHierarchy) { - legacyCC.director._nodeActivator.activateComp(component); + (cclegacy.director as Director)._nodeActivator.activateComp(component); } if (EDITOR_NOT_IN_PREVIEW) { component.resetInEditor?.(); @@ -1329,7 +1332,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { protected _instantiate (cloned?: Node | null, isSyncedNode: boolean = false): Node { if (!cloned) { - cloned = legacyCC.instantiate._clone(this, this) as Node; + cloned = cclegacy.instantiate._clone(this, this) as Node; } const newPrefabInfo = cloned._prefab; @@ -1353,15 +1356,15 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { protected _onHierarchyChangedBase (oldParent: this | null): void { const newParent = this._parent; - if (this._persistNode && !(newParent instanceof legacyCC.Scene)) { - legacyCC.game.removePersistRootNode(this); + if (this._persistNode && !(newParent instanceof cclegacy.Scene)) { + cclegacy.game.removePersistRootNode(this); if (EDITOR) { warnID(1623); } } if (EDITOR) { - const scene = legacyCC.director.getScene() as this | null; + const scene = (cclegacy.director as Director).getScene() as this | null; const inCurrentSceneBefore = oldParent && oldParent.isChildOf(scene); const inCurrentSceneNow = newParent && newParent.isChildOf(scene); if (!inCurrentSceneBefore && inCurrentSceneNow) { @@ -1382,7 +1385,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { const shouldActiveNow = this._active && !!(newParent && newParent._activeInHierarchy); if (this._activeInHierarchy !== shouldActiveNow) { - legacyCC.director._nodeActivator.activateNode(this, shouldActiveNow); + (cclegacy.director as Director)._nodeActivator.activateNode(this, shouldActiveNow); } } @@ -1401,7 +1404,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { // remove from persist if (this._persistNode) { - legacyCC.game.removePersistRootNode(this); + (cclegacy.game as Game).removePersistRootNode(this); } if (!destroyByParent) { @@ -1560,7 +1563,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { * @zh 指定对象是否是普通的节点?如果传入 [[Scene]] 会返回 false。 */ public static isNode (obj: unknown): obj is Node { - return obj instanceof Node && (obj.constructor === Node || !(obj instanceof legacyCC.Scene)); + return obj instanceof Node && (obj.constructor === Node || !(obj instanceof cclegacy.Scene)); } protected _onPreDestroy (): boolean { @@ -1934,7 +1937,23 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { this.emit(NodeEventType.ACTIVE_CHANGED, this, active); } - this._eventProcessor.setEnabled(active); + const eventProcessor = this._eventProcessor; + // If the 'enable' state of event processor is equal to the node's active state, we should mark the list dirty for the global callback invoker + // which will trigger re-sorting logic in PointerEventDispatcher._sortPointerEventProcessorList. + // Otherwise, pointerEventProcessorList will not be sorted correctly since the 'enable' state may not change and the following + // eventProcessor.setEnabled(active) may return directly. + // Think of the case: + // this.node.pauseSystemEvents(true); // child's eventProcessor will be disabled. + // child.active = false; // child's active state is false and its eventProcessor keeps disabled. + // this.node.resumeSystemEvents(true); // child's eventProcessor will be enabled, MARK_LIST_DIRTY will be emitted, + // but the node is not active, so the resorting logic will take the child to the end of the list, + // see PointerEventDispatcher._sortByPriority. + // child.active = true; // child's eventProcessor has already been enabled, eventProcessor.setEnabled(true) will do nothing. + if (eventProcessor.isEnabled === active) { + NodeEventProcessor.callbacksInvoker.emit(DispatcherEventType.MARK_LIST_DIRTY); + } + + eventProcessor.setEnabled(active); if (active) { // activated // in case transform updated during deactivated period @@ -2684,7 +2703,7 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { public getPathInHierarchy (): string { let result = this.name; let curNode: Node | null = this.parent; - while (curNode && !(curNode instanceof legacyCC.Scene)) { + while (curNode && !(curNode instanceof cclegacy.Scene)) { result = `${curNode.name}/${result}`; curNode = curNode.parent; } @@ -2695,4 +2714,4 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable { nodePolyfill(Node); -legacyCC.Node = Node; +cclegacy.Node = Node; diff --git a/cocos/spine/assembler/simple.ts b/cocos/spine/assembler/simple.ts index 98d1e128d21..c3ef40763dc 100644 --- a/cocos/spine/assembler/simple.ts +++ b/cocos/spine/assembler/simple.ts @@ -169,14 +169,14 @@ function realTimeTraverse (comp: Skeleton): void { for (let i = 0; i < ic; i++) ibuf[i] += chunkOffset; const data = model.getData(); + const textures = model.getTextures(); const count = data.size(); let indexOffset = 0; let indexCount = 0; - for (let i = 0; i < count; i += 6) { + for (let i = 0; i < count; i += 5) { indexCount = data.get(i + 3); const material = _getSlotMaterial(data.get(i + 4) as number, comp); - const textureID: number = data.get(i + 5); - comp.requestDrawData(material, textureID, indexOffset, indexCount); + comp.requestDrawData(material, textures.get(i / 5), indexOffset, indexCount); indexOffset += indexCount; } @@ -321,7 +321,7 @@ function cacheTraverse (comp: Skeleton): void { const material = _getSlotMaterial(mesh.blendMode as number, comp); const textureID = mesh.textureID; indexCount = mesh.iCount; - comp.requestDrawData(material, textureID as number, indexOffset, indexCount); + comp.requestDrawData(material, textureID, indexOffset, indexCount); indexOffset += indexCount; } diff --git a/cocos/spine/lib/spine-core.d.ts b/cocos/spine/lib/spine-core.d.ts index 6bcf725f17e..7fdd2f506d8 100644 --- a/cocos/spine/lib/spine-core.d.ts +++ b/cocos/spine/lib/spine-core.d.ts @@ -1208,16 +1208,17 @@ declare namespace spine { setDebugMode(debug: boolean); getDebugShapes(); resizeSlotRegion(slotName: string, width: number, height: number, createNew: boolean); - setSlotTexture(slotName: string, index: number); + setSlotTexture(slotName: string, uuid: string); } class wasmUtil { static spineWasmInit(): void; static spineWasmDestroy(): void; - static queryStoreMemory(size: number): number; + static freeStoreMemory(): void; + static createStoreMemory(size: number): number; static querySpineSkeletonDataByUUID(uuid: string): SkeletonData; - static createSpineSkeletonDataWithJson(jsonStr: string, atlasText: string): SkeletonData; - static createSpineSkeletonDataWithBinary(byteSize: number, atlasText: string): SkeletonData; + static createSpineSkeletonDataWithJson(jsonStr: string, atlasText: string, textureNames: string[], textureUUIDs: string[]): SkeletonData; + static createSpineSkeletonDataWithBinary(byteSize: number, atlasText: string, textureNames: string[], textureUUIDs: string[]): SkeletonData; static registerSpineSkeletonDataWithUUID(data: SkeletonData, uuid: string); static destroySpineSkeletonDataWithUUID(uuid: string); static destroySpineSkeleton(skeleton: Skeleton): void; diff --git a/cocos/spine/skeleton-cache.ts b/cocos/spine/skeleton-cache.ts index e10ba8224ae..a02690b3892 100644 --- a/cocos/spine/skeleton-cache.ts +++ b/cocos/spine/skeleton-cache.ts @@ -189,12 +189,13 @@ export class AnimationCache { modelData.iData = iUint16Buf; const data = model.getData(); + const textures = model.getTextures(); const count = data.size(); - for (let i = 0; i < count; i += 6) { + for (let i = 0; i < count; i += 5) { const meshData = new SpineDrawItem(); meshData.iCount = data.get(i + 3); meshData.blendMode = data.get(i + 4); - meshData.textureID = data.get(i + 5); + meshData.textureID = textures.get(i / 5); modelData.meshes.push(meshData); } @@ -466,7 +467,7 @@ class SkeletonCache { delete animationPool[key]; } } - let skeletonInfo = this._skeletonCache[uuid]; + const skeletonInfo = this._skeletonCache[uuid]; const skeleton = skeletonInfo && skeletonInfo.skeleton; if (skeleton) { spine.wasmUtil.destroySpineSkeleton(skeleton); diff --git a/cocos/spine/skeleton-data.ts b/cocos/spine/skeleton-data.ts index d872fd1ccc2..5378b51d70e 100644 --- a/cocos/spine/skeleton-data.ts +++ b/cocos/spine/skeleton-data.ts @@ -212,19 +212,26 @@ export class SkeletonData extends Asset { const spData = spine.wasmUtil.querySpineSkeletonDataByUUID(uuid); if (spData) { this._skeletonCache = spData; - } else if (this._skeletonJson) { - this._skeletonCache = spine.wasmUtil.createSpineSkeletonDataWithJson(this.skeletonJsonStr, this._atlasText); - spine.wasmUtil.registerSpineSkeletonDataWithUUID(this._skeletonCache, uuid); } else { - const rawData = new Uint8Array(this._nativeAsset); - const byteSize = rawData.length; - const ptr = spine.wasmUtil.queryStoreMemory(byteSize); - const wasmMem = spine.wasmUtil.wasm.HEAPU8.subarray(ptr, ptr + byteSize); - wasmMem.set(rawData); - this._skeletonCache = spine.wasmUtil.createSpineSkeletonDataWithBinary(byteSize, this._atlasText); - spine.wasmUtil.registerSpineSkeletonDataWithUUID(this._skeletonCache, uuid); + const size = this.textures.length; + const textureUUIDs: string[] = []; + for (let i = 0; i < size; ++i) { + textureUUIDs.push(this.textures[i].uuid); + } + if (this._skeletonJson) { + this._skeletonCache = spine.wasmUtil.createSpineSkeletonDataWithJson(this.skeletonJsonStr, this._atlasText, this.textureNames, textureUUIDs); + spine.wasmUtil.registerSpineSkeletonDataWithUUID(this._skeletonCache, uuid); + } else { + const rawData = new Uint8Array(this._nativeAsset); + const byteSize = rawData.length; + const ptr = spine.wasmUtil.createStoreMemory(byteSize); + const wasmMem = spine.wasmUtil.wasm.HEAPU8.subarray(ptr, ptr + byteSize); + wasmMem.set(rawData); + this._skeletonCache = spine.wasmUtil.createSpineSkeletonDataWithBinary(byteSize, this._atlasText, this.textureNames, textureUUIDs); + spine.wasmUtil.registerSpineSkeletonDataWithUUID(this._skeletonCache, uuid); + spine.wasmUtil.freeStoreMemory(); + } } - return this._skeletonCache; } diff --git a/cocos/spine/skeleton.ts b/cocos/spine/skeleton.ts index f3204a22f71..85f6bf70a45 100644 --- a/cocos/spine/skeleton.ts +++ b/cocos/spine/skeleton.ts @@ -33,7 +33,7 @@ import { Graphics, UIRenderer } from '../2d'; import { Batcher2D } from '../2d/renderer/batcher-2d'; import { BlendFactor, BlendOp } from '../gfx'; import { MaterialInstance } from '../render-scene'; -import { builtinResMgr } from '../asset/asset-manager'; +import { assetManager, builtinResMgr } from '../asset/asset-manager'; import { legacyCC } from '../core/global-exports'; import { SkeletonSystem } from './skeleton-system'; import { RenderEntity, RenderEntityType } from '../2d/renderer/render-entity'; @@ -45,8 +45,6 @@ import { TrackEntryListeners } from './track-entry-listeners'; import { setPropertyEnumType } from '../core/internal-index'; const CachedFrameTime = 1 / 60; -const CUSTOM_SLOT_TEXTURE_BEGIN = 10000; -let _slotTextureID = CUSTOM_SLOT_TEXTURE_BEGIN; type TrackListener = (x: spine.TrackEntry) => void; type TrackListener2 = (x: spine.TrackEntry, ev: spine.Event | number) => void; @@ -310,10 +308,7 @@ export class Skeleton extends UIRenderer { */ public _endSlotIndex; - private _slotTextures: Map | null = null; - private _customMaterialInstance: MaterialInstance | null = null; - _vLength = 0; _vBuffer: Uint8Array | null = null; _iLength = 0; @@ -715,9 +710,6 @@ export class Skeleton extends UIRenderer { this._vBuffer = null; this._iBuffer = null; this.attachUtil.reset(); - //this._textures.length = 0; - this._slotTextures?.clear(); - this._slotTextures = null; this._cachedSockets.clear(); this._socketNodes.clear(); //if (this._cacheMode == SpineAnimationCacheMode.PRIVATE_CACHE) this._animCache?.destroy(); @@ -1174,15 +1166,10 @@ export class Skeleton extends UIRenderer { /** * @engineInternal */ - public requestDrawData (material: Material, textureID: number, indexOffset: number, indexCount: number): SkeletonDrawData { + public requestDrawData (material: Material, textureUUID: string, indexOffset: number, indexCount: number): SkeletonDrawData { const draw = this._drawList.add(); draw.material = material; - if (textureID < CUSTOM_SLOT_TEXTURE_BEGIN) { - draw.texture = this._textures[textureID]; - } else { - const texture = this._slotTextures?.get(textureID); - if (texture) draw.texture = texture; - } + draw.texture = assetManager.assets.get(textureUUID) as Texture2D; draw.indexOffset = indexOffset; draw.indexCount = indexCount; return draw; @@ -1871,16 +1858,7 @@ export class Skeleton extends UIRenderer { const height = tex2d.height; const createNewAttachment = createNew || false; this._instance!.resizeSlotRegion(slotName, width, height, createNewAttachment); - if (!this._slotTextures) this._slotTextures = new Map(); - let textureID = 0; - this._slotTextures.forEach((value, key) => { - if (value === tex2d) textureID = key; - }); - if (textureID === 0) { - textureID = ++_slotTextureID; - this._slotTextures.set(textureID, tex2d); - } - this._instance!.setSlotTexture(slotName, textureID); + this._instance!.setSlotTexture(slotName, tex2d.uuid); } private _destroySkeletonInfo (skeletonCache: SkeletonCache | null): void { diff --git a/editor/inspector/contributions/node.js b/editor/inspector/contributions/node.js index d22430299a8..c6bc17952bd 100644 --- a/editor/inspector/contributions/node.js +++ b/editor/inspector/contributions/node.js @@ -503,7 +503,7 @@ const Elements = { }, 100, { leading: false, trailing: true }); panel.__nodeChanged__ = (uuid) => { - if (Array.isArray(panel.uuidList) && panel.uuidList.includes(uuid)) { + if (panel.throttleUpdate && Array.isArray(panel.uuidList) && panel.uuidList.includes(uuid)) { panel.throttleUpdate(); } }; @@ -548,7 +548,9 @@ const Elements = { } }, 100, { leading: false, trailing: true }); - Profile.on('change', panel.__throttleProfileChanged__); + if (panel.__throttleProfileChanged__) { + Profile.on('change', panel.__throttleProfileChanged__); + } // 识别拖入脚本资源 panel.$.container.addEventListener('dragover', (event) => { @@ -645,15 +647,19 @@ const Elements = { close() { const panel = this; - panel.throttleUpdate.cancel(); + if (panel.throttleUpdate) { + panel.throttleUpdate.cancel(); + } panel.throttleUpdate = undefined; Editor.Message.removeBroadcastListener('scene:change-node', panel.__nodeChanged__); Editor.Message.removeBroadcastListener('scene:animation-time-change', panel.__animationTimeChange__); Editor.Message.removeBroadcastListener('project:setting-change', panel.__projectSettingChanged__); - Profile.removeListener('change', panel.__throttleProfileChanged__); - panel.__throttleProfileChanged__.cancel(); + if (panel.__throttleProfileChanged__) { + Profile.removeListener('change', panel.__throttleProfileChanged__); + panel.__throttleProfileChanged__.cancel(); + } panel.__throttleProfileChanged__ = undefined; }, }, diff --git a/native/cocos/editor-support/MiddlewareManager.cpp b/native/cocos/editor-support/MiddlewareManager.cpp index 21e66aaca80..d50d85ed86a 100644 --- a/native/cocos/editor-support/MiddlewareManager.cpp +++ b/native/cocos/editor-support/MiddlewareManager.cpp @@ -54,20 +54,22 @@ MeshBuffer *MiddlewareManager::getMeshBuffer(int format) { return mb; } -void MiddlewareManager::clearRemoveList() { - for (auto *editor : _removeList) { - auto it = std::find(_updateList.begin(), _updateList.end(), editor); - if (it != _updateList.end()) { +void MiddlewareManager::updateOperateCache() { + for (auto &iter: _operateCacheMap) { + auto it = std::find(_updateList.begin(), _updateList.end(), iter.first); + if (iter.second) { + if (it == _updateList.end()) { + _updateList.push_back(iter.first); + } + } else if (it != _updateList.end()) { _updateList.erase(it); } } - - _removeList.clear(); + _operateCacheMap.clear(); } void MiddlewareManager::update(float dt) { - isUpdating = true; - + updateOperateCache(); _attachInfo.reset(); auto *attachBuffer = _attachInfo.getBuffer(); if (attachBuffer) { @@ -76,23 +78,8 @@ void MiddlewareManager::update(float dt) { for (size_t i = 0, len = _updateList.size(); i < len; ++i) { auto *editor = _updateList[i]; - if (!_removeList.empty()) { - auto removeIt = std::find(_removeList.begin(), _removeList.end(), editor); - if (removeIt == _removeList.end()) { - if (editor) { - editor->update(dt); - } - } - } else { - if (editor) { - editor->update(dt); - } - } + editor->update(dt); } - - isUpdating = false; - - clearRemoveList(); } void MiddlewareManager::render(float dt) { @@ -103,22 +90,12 @@ void MiddlewareManager::render(float dt) { } } - isRendering = true; for (size_t i = 0, len = _updateList.size(); i < len; ++i) { auto *editor = _updateList[i]; - if (!_removeList.empty()) { - auto removeIt = std::find(_removeList.begin(), _removeList.end(), editor); - if (removeIt == _removeList.end()) { - editor->render(dt); - } - } else { - editor->render(dt); - } + editor->render(dt); } - isRendering = false; - for (auto it : _mbMap) { auto *buffer = it.second; if (buffer) { @@ -138,32 +115,14 @@ void MiddlewareManager::render(float dt) { } batch2d->syncMeshBuffersToNative(accID, std::move(uiMeshArray)); } - - clearRemoveList(); } void MiddlewareManager::addTimer(IMiddleware *editor) { - auto it0 = std::find(_updateList.begin(), _updateList.end(), editor); - if (it0 != _updateList.end()) { - return; - } - - auto it1 = std::find(_removeList.begin(), _removeList.end(), editor); - if (it1 != _removeList.end()) { - _removeList.erase(it1); - } - _updateList.push_back(editor); + _operateCacheMap[editor] = true; } void MiddlewareManager::removeTimer(IMiddleware *editor) { - if (isUpdating || isRendering) { - _removeList.push_back(editor); - } else { - auto it = std::find(_updateList.begin(), _updateList.end(), editor); - if (it != _updateList.end()) { - _updateList.erase(it); - } - } + _operateCacheMap[editor] = false; } se_object_ptr MiddlewareManager::getVBTypedArray(int format, int bufferPos) { diff --git a/native/cocos/editor-support/MiddlewareManager.h b/native/cocos/editor-support/MiddlewareManager.h index 9c326dbb30f..75b697e834b 100644 --- a/native/cocos/editor-support/MiddlewareManager.h +++ b/native/cocos/editor-support/MiddlewareManager.h @@ -24,7 +24,7 @@ #pragma once -#include +#include #include #include "MeshBuffer.h" #include "MiddlewareMacro.h" @@ -83,13 +83,13 @@ class MiddlewareManager { void render(float dt); /** - * @brief Third party module add in _updateMap,it will update perframe. + * @brief Mark the add flag to _operateCacheMap, and perform the update in the next frame * @param[in] editor Module must implement IMiddleware interface. */ void addTimer(IMiddleware *editor); /** - * @brief Third party module remove from _updateMap,it will stop update. + * @brief Mark the remove flag to _operateCacheMap, and perform the update in the next frame * @param[in] editor Module must implement IMiddleware interface. */ void removeTimer(IMiddleware *editor); @@ -108,16 +108,12 @@ class MiddlewareManager { MiddlewareManager(); ~MiddlewareManager(); - // If manager is traversing _updateMap, will set the flag untill traverse is finished. - bool isRendering = false; - bool isUpdating = false; - private: - void clearRemoveList(); + void updateOperateCache(); ccstd::vector _updateList; - ccstd::vector _removeList; - std::map _mbMap; + ccstd::unordered_map _operateCacheMap; + ccstd::unordered_map _mbMap; SharedBufferManager _renderInfo; SharedBufferManager _attachInfo; diff --git a/native/cocos/editor-support/dragonbones-creator-support/CCArmatureCacheDisplay.cpp b/native/cocos/editor-support/dragonbones-creator-support/CCArmatureCacheDisplay.cpp index cc832e7ba9f..529d95aba91 100644 --- a/native/cocos/editor-support/dragonbones-creator-support/CCArmatureCacheDisplay.cpp +++ b/native/cocos/editor-support/dragonbones-creator-support/CCArmatureCacheDisplay.cpp @@ -141,7 +141,6 @@ void CCArmatureCacheDisplay::render(float /*dt*/) { if (!frameData) return; auto *mgr = MiddlewareManager::getInstance(); - if (!mgr->isRendering) return; auto *entity = _entity; entity->clearDynamicRenderDrawInfos(); diff --git a/native/cocos/editor-support/dragonbones-creator-support/CCArmatureDisplay.cpp b/native/cocos/editor-support/dragonbones-creator-support/CCArmatureDisplay.cpp index 5033b2dcd0a..fdd28e3fca0 100644 --- a/native/cocos/editor-support/dragonbones-creator-support/CCArmatureDisplay.cpp +++ b/native/cocos/editor-support/dragonbones-creator-support/CCArmatureDisplay.cpp @@ -108,7 +108,6 @@ void CCArmatureDisplay::dbRender() { entity->clearDynamicRenderDrawInfos(); auto *mgr = MiddlewareManager::getInstance(); - if (!mgr->isRendering) return; auto *attachMgr = mgr->getAttachInfoMgr(); auto *attachInfo = attachMgr->getBuffer(); diff --git a/native/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.cpp b/native/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.cpp index fd5ca483c1d..b65d6a736d1 100644 --- a/native/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.cpp +++ b/native/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.cpp @@ -165,7 +165,6 @@ void SkeletonCacheAnimation::render(float /*dt*/) { if (segments.empty() || colors.empty()) return; auto *mgr = MiddlewareManager::getInstance(); - if (!mgr->isRendering) return; _sharedBufferOffset->reset(); _sharedBufferOffset->clear(); diff --git a/native/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp b/native/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp index 2411f9604ad..21d248e932a 100644 --- a/native/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp +++ b/native/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp @@ -266,7 +266,6 @@ void SkeletonRenderer::render(float /*deltaTime*/) { // avoid other place call update. auto *mgr = MiddlewareManager::getInstance(); - if (!mgr->isRendering) return; auto *attachMgr = mgr->getAttachInfoMgr(); auto *attachInfo = attachMgr->getBuffer(); diff --git a/native/cocos/editor-support/spine-wasm/AtlasAttachmentLoaderExtension.cpp b/native/cocos/editor-support/spine-wasm/AtlasAttachmentLoaderExtension.cpp index 5ca9d9d9ea1..f41e3d92dd4 100644 --- a/native/cocos/editor-support/spine-wasm/AtlasAttachmentLoaderExtension.cpp +++ b/native/cocos/editor-support/spine-wasm/AtlasAttachmentLoaderExtension.cpp @@ -5,13 +5,13 @@ using namespace spine; static uint16_t quadTriangles[6] = {0, 1, 2, 2, 3, 0}; -AttachmentVertices::AttachmentVertices(int verticesCount, uint16_t *triangles, int trianglesCount, uint32_t textureId) { +AttachmentVertices::AttachmentVertices(int verticesCount, uint16_t *triangles, int trianglesCount, const spine::String& textureUUID) { _triangles = new Triangles(); _triangles->verts = new V3F_T2F_C4B[verticesCount]; _triangles->vertCount = verticesCount; _triangles->indices = triangles; _triangles->indexCount = trianglesCount; - _textureId = textureId; + _textureId = textureUUID; } AttachmentVertices::~AttachmentVertices() { @@ -38,7 +38,7 @@ void AtlasAttachmentLoaderExtension::configureAttachment(Attachment *attachment) auto *regionAttachment = static_cast(attachment); auto &pages = _atlasCache->getPages(); auto *region = static_cast(regionAttachment->getRendererObject()); - auto *attachmentVertices = new AttachmentVertices(4, quadTriangles, 6, pages.indexOf(region->page)); + auto *attachmentVertices = new AttachmentVertices(4, quadTriangles, 6, region->page->name); V3F_T2F_C4B *vertices = attachmentVertices->_triangles->verts; const auto &uvs = regionAttachment->getUVs(); for (int i = 0, ii = 0; i < 4; ++i, ii += 2) { @@ -51,7 +51,7 @@ void AtlasAttachmentLoaderExtension::configureAttachment(Attachment *attachment) auto &pages = _atlasCache->getPages(); auto *region = static_cast(meshAttachment->getRendererObject()); auto *attachmentVertices = new AttachmentVertices( - static_cast(meshAttachment->getWorldVerticesLength() >> 1), meshAttachment->getTriangles().buffer(), static_cast(meshAttachment->getTriangles().size()), pages.indexOf(region->page)); + static_cast(meshAttachment->getWorldVerticesLength() >> 1), meshAttachment->getTriangles().buffer(), static_cast(meshAttachment->getTriangles().size()), region->page->name); V3F_T2F_C4B *vertices = attachmentVertices->_triangles->verts; const auto &uvs = meshAttachment->getUVs(); for (size_t i = 0, ii = 0, nn = meshAttachment->getWorldVerticesLength(); ii < nn; ++i, ii += 2) { diff --git a/native/cocos/editor-support/spine-wasm/AtlasAttachmentLoaderExtension.h b/native/cocos/editor-support/spine-wasm/AtlasAttachmentLoaderExtension.h index 256f72d99b6..0e6c415de3c 100644 --- a/native/cocos/editor-support/spine-wasm/AtlasAttachmentLoaderExtension.h +++ b/native/cocos/editor-support/spine-wasm/AtlasAttachmentLoaderExtension.h @@ -5,11 +5,11 @@ class AttachmentVertices { public: - AttachmentVertices(int verticesCount, uint16_t *triangles, int trianglesCount, uint32_t textureId); + AttachmentVertices(int verticesCount, uint16_t *triangles, int trianglesCount, const spine::String& textureUUID); virtual ~AttachmentVertices(); AttachmentVertices *copy(); Triangles *_triangles = nullptr; - uint32_t _textureId = 0; + spine::String _textureId; }; class AtlasAttachmentLoaderExtension : public spine::AtlasAttachmentLoader { diff --git a/native/cocos/editor-support/spine-wasm/spine-model.cpp b/native/cocos/editor-support/spine-wasm/spine-model.cpp index e44fc15a492..fd7093ed8cc 100644 --- a/native/cocos/editor-support/spine-wasm/spine-model.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-model.cpp @@ -11,20 +11,20 @@ void SpineModel::addSlotMesh(SlotMesh& mesh, bool needMerge) { bool canMerge = false; auto count = _data.size(); if (needMerge && count > 0) { - if (_data[count - 2] == mesh.blendMode && _data[count - 1] == mesh.textureID) { + if (_data[count - 1] == mesh.blendMode && _textures[count / 5 - 1] == mesh.textureID) { canMerge = true; - _data[count-4] += mesh.vCount; - _data[count-3] += mesh.iCount; + _data[count-3] += mesh.vCount; + _data[count-2] += mesh.iCount; } } if (!canMerge) { - _data.setSize(count + 6, 0); + _data.setSize(count + 5, 0); _data[count] = (uint32_t)mesh.vBuf; _data[count + 1] = (uint32_t)mesh.iBuf; _data[count + 2] = mesh.vCount; _data[count + 3] = mesh.iCount; _data[count + 4] = mesh.blendMode; - _data[count + 5] = mesh.textureID; + _textures.add(mesh.textureID); } auto indexCount = mesh.iCount; @@ -45,6 +45,7 @@ void SpineModel::addSlotMesh(SlotMesh& mesh, bool needMerge) { void SpineModel::clearMeshes() { _data.setSize(0, 0); + _textures.setSize(0, ""); vCount = 0; iCount = 0; } diff --git a/native/cocos/editor-support/spine-wasm/spine-model.h b/native/cocos/editor-support/spine-wasm/spine-model.h index 6921fd592e9..d42a0bcbf53 100644 --- a/native/cocos/editor-support/spine-wasm/spine-model.h +++ b/native/cocos/editor-support/spine-wasm/spine-model.h @@ -19,7 +19,7 @@ class SlotMesh { uint32_t vCount{}; uint32_t iCount{}; uint32_t blendMode{}; - uint32_t textureID{}; + spine::String textureID; }; class SpineModel { @@ -31,8 +31,10 @@ class SpineModel { void setBufferPtr(uint8_t* vp, uint16_t* ip); spine::Vector* getData(); + inline spine::Vector* getTextures() { return &_textures; } private: spine::Vector _data; + spine::Vector _textures; public: uint32_t vCount{}; uint32_t iCount{}; diff --git a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp index ed4bc3a85e8..48d60da09e3 100644 --- a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp @@ -503,11 +503,11 @@ void SpineSkeletonInstance::resizeSlotRegion(const spine::String &slotName, uint } } -void SpineSkeletonInstance::setSlotTexture(const spine::String &slotName, uint32_t textureID) { +void SpineSkeletonInstance::setSlotTexture(const spine::String &slotName, const spine::String& textureUuid) { if (!_skeleton) return; auto* slot = _skeleton->findSlot(slotName); if (!slot) return; _userData.useSlotTexture = true; - _slotTextureSet.put(slot, textureID); + _slotTextureSet.put(slot, textureUuid); } \ No newline at end of file diff --git a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h index 2743a0e799f..f370bd1932c 100644 --- a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h +++ b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h @@ -54,7 +54,7 @@ class SpineSkeletonInstance { void onTrackEntryEvent(spine::TrackEntry *entry, spine::EventType type, spine::Event *event); inline spine::Vector &getDebugShapes() { return _debugShapes; } void resizeSlotRegion(const spine::String &slotName, uint32_t width, uint32_t height, bool createNew = false); - void setSlotTexture(const spine::String &slotName, uint32_t index); + void setSlotTexture(const spine::String &slotName, const spine::String& textureUuid); void destroy(); bool isCache{false}; bool enable{true}; @@ -74,5 +74,5 @@ class SpineSkeletonInstance { uint32_t _trackEntryListenerID = 0; UserData _userData; spine::Vector _debugShapes{}; - spine::HashMap _slotTextureSet{}; + spine::HashMap _slotTextureSet{}; }; diff --git a/native/cocos/editor-support/spine-wasm/spine-type-export.cpp b/native/cocos/editor-support/spine-wasm/spine-type-export.cpp index ac34fbc3f01..499e6c5aa85 100644 --- a/native/cocos/editor-support/spine-wasm/spine-type-export.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-type-export.cpp @@ -1341,6 +1341,7 @@ EMSCRIPTEN_BINDINGS(spine) { .property("iCount", &SpineModel::iCount) .property("vPtr", &SpineModel::vPtr) .property("iPtr", &SpineModel::iPtr) + .function("getTextures", &SpineModel::getTextures, allow_raw_pointers()) .function("getData", &SpineModel::getData, allow_raw_pointer()); class_("SpineDebugShape") @@ -1382,10 +1383,33 @@ EMSCRIPTEN_BINDINGS(cocos_spine) { class_("SpineWasmUtil") .class_function("spineWasmInit", &SpineWasmUtil::spineWasmInit) .class_function("spineWasmDestroy", &SpineWasmUtil::spineWasmDestroy) - .class_function("queryStoreMemory", &SpineWasmUtil::queryStoreMemory) + .class_function("createStoreMemory", &SpineWasmUtil::createStoreMemory) + .class_function("freeStoreMemory", &SpineWasmUtil::freeStoreMemory) .class_function("querySpineSkeletonDataByUUID", &SpineWasmUtil::querySpineSkeletonDataByUUID, allow_raw_pointers()) - .class_function("createSpineSkeletonDataWithJson", &SpineWasmUtil::createSpineSkeletonDataWithJson, allow_raw_pointers()) - .class_function("createSpineSkeletonDataWithBinary", &SpineWasmUtil::createSpineSkeletonDataWithBinary, allow_raw_pointers()) + .class_function("createSpineSkeletonDataWithJson", optional_override([](String jsonStr, String atlasStr, emscripten::val nameArray, emscripten::val uuidArray){ + unsigned count = nameArray["length"].as(); + Vector names; + Vector ids; + names.setSize(count, ""); + ids.setSize(count, ""); + for (int i = 0; i < count; i++) { + names[i] = nameArray[i].as(); + ids[i] = uuidArray[i].as(); + } + return SpineWasmUtil::createSpineSkeletonDataWithJson(jsonStr, atlasStr, names, ids); + }), allow_raw_pointers()) + .class_function("createSpineSkeletonDataWithBinary", optional_override([](uint32_t byteSize, String atlasStr, emscripten::val nameArray, emscripten::val uuidArray){ + unsigned count = nameArray["length"].as(); + Vector names; + Vector ids; + names.setSize(count, ""); + ids.setSize(count, ""); + for (int i = 0; i < count; i++) { + names[i] = nameArray[i].as(); + ids[i] = uuidArray[i].as(); + } + return SpineWasmUtil::createSpineSkeletonDataWithBinary(byteSize, atlasStr, names, ids); + }), allow_raw_pointers()) .class_function("registerSpineSkeletonDataWithUUID", &SpineWasmUtil::registerSpineSkeletonDataWithUUID, allow_raw_pointers()) .class_function("destroySpineSkeletonDataWithUUID", &SpineWasmUtil::destroySpineSkeletonDataWithUUID) .class_function("destroySpineSkeleton", &SpineWasmUtil::destroySpineSkeleton, allow_raw_pointers()) diff --git a/native/cocos/editor-support/spine-wasm/spine-wasm.cpp b/native/cocos/editor-support/spine-wasm/spine-wasm.cpp index cc486db5c5a..18024fa31e2 100644 --- a/native/cocos/editor-support/spine-wasm/spine-wasm.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-wasm.cpp @@ -4,10 +4,59 @@ #include "util-function.h" #include "wasmSpineExtension.h" +#include +#include + +#include "spine/HashMap.h" + using namespace spine; +static void logToConsole(const char* message) { + EM_ASM({ + console.log(UTF8ToString($0)); + }, message); +} + namespace { HashMap skeletonDataMap{}; + + static void updateAttachmentVerticesTextureId(SkeletonData* skeletonData, const spine::Vector& textureNames, const spine::Vector& textureUUIDs) { + spine::HashMap textureMap{}; + int textureSize = textureNames.size(); + for (int i = 0; i < textureSize; ++i) { + textureMap.put(textureNames[i], textureUUIDs[i]); + } + + auto& skins = skeletonData->getSkins(); + auto skinSize = skins.size(); + for (int i = 0; i < skinSize; ++i) { + auto* skin = skins[i]; + auto entries = skin->getAttachments(); + while (entries.hasNext()) { + Skin::AttachmentMap::Entry& entry = entries.next(); + AttachmentVertices* attachmentVertices; + auto* attachment = entry._attachment; + if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) { + auto* meshAttachment = static_cast(attachment); + attachmentVertices = static_cast(meshAttachment->getRendererObject()); + } else { + auto* regionAttachment = static_cast(attachment); + attachmentVertices = static_cast(regionAttachment->getRendererObject()); + } + if (attachmentVertices) { + auto& textureName = attachmentVertices->_textureId; + if (textureMap.containsKey(textureName)) { + attachmentVertices->_textureId = textureMap[textureName]; + } else { + spine::String logInfo(attachment->getName()); + logInfo.append(" attachment's texture doesn`t exist "); + logInfo.append(textureName); + logToConsole(logInfo.buffer()); + } + } + } + } + } } uint32_t SpineWasmUtil::s_listenerID = 0; @@ -15,7 +64,6 @@ EventType SpineWasmUtil::s_currentType = EventType_Event; TrackEntry* SpineWasmUtil::s_currentEntry = nullptr; Event* SpineWasmUtil::s_currentEvent = nullptr; uint8_t* SpineWasmUtil::s_mem = nullptr; -uint32_t SpineWasmUtil::s_memSize = 0; void SpineWasmUtil::spineWasmInit() { // LogUtil::Initialize(); @@ -42,7 +90,7 @@ SkeletonData* SpineWasmUtil::querySpineSkeletonDataByUUID(const String& uuid) { return skeletonDataMap[uuid]; } -SkeletonData* SpineWasmUtil::createSpineSkeletonDataWithJson(const String& jsonStr, const String& altasStr) { +SkeletonData* SpineWasmUtil::createSpineSkeletonDataWithJson(const String& jsonStr, const String& altasStr, const spine::Vector& textureNames, const spine::Vector& textureUUIDs) { #if ENABLE_JSON_PARSER auto* atlas = new Atlas(altasStr.buffer(), altasStr.length(), "", nullptr, false); if (!atlas) { @@ -53,13 +101,15 @@ SkeletonData* SpineWasmUtil::createSpineSkeletonDataWithJson(const String& jsonS json.setScale(1.0F); SkeletonData* skeletonData = json.readSkeletonData(jsonStr.buffer()); + updateAttachmentVerticesTextureId(skeletonData, textureNames, textureUUIDs); + return skeletonData; #else return nullptr; #endif } -SkeletonData* SpineWasmUtil::createSpineSkeletonDataWithBinary(uint32_t byteSize, const String& altasStr) { +SkeletonData* SpineWasmUtil::createSpineSkeletonDataWithBinary(uint32_t byteSize, const String& altasStr, const spine::Vector& textureNames, const spine::Vector& textureUUIDs) { #if ENABLE_BINARY_PARSER auto* atlas = new Atlas(altasStr.buffer(), altasStr.length(), "", nullptr, false); if (!atlas) { @@ -69,6 +119,9 @@ SkeletonData* SpineWasmUtil::createSpineSkeletonDataWithBinary(uint32_t byteSize SkeletonBinary binary(attachmentLoader); binary.setScale(1.0F); SkeletonData* skeletonData = binary.readSkeletonData(s_mem, byteSize); + + updateAttachmentVerticesTextureId(skeletonData, textureNames, textureUUIDs); + return skeletonData; #else return nullptr; @@ -95,17 +148,9 @@ void SpineWasmUtil::destroySpineSkeleton(Skeleton* skeleton) { } } -uint32_t SpineWasmUtil::queryStoreMemory(uint32_t size) { - if (s_mem) { - if (s_memSize < size) { - delete[] s_mem; - s_mem = new uint8_t[size]; - s_memSize = size; - } - } else { - s_mem = new uint8_t[size]; - s_memSize = size; - } +uint32_t SpineWasmUtil::createStoreMemory(uint32_t size) { + s_mem = new uint8_t[size]; + return (uint32_t)s_mem; } @@ -114,7 +159,6 @@ void SpineWasmUtil::freeStoreMemory() { delete[] s_mem; s_mem = nullptr; } - s_memSize = 0; } uint32_t SpineWasmUtil::getCurrentListenerID() { diff --git a/native/cocos/editor-support/spine-wasm/spine-wasm.h b/native/cocos/editor-support/spine-wasm/spine-wasm.h index 655b7f743c1..cdb6561bf0a 100644 --- a/native/cocos/editor-support/spine-wasm/spine-wasm.h +++ b/native/cocos/editor-support/spine-wasm/spine-wasm.h @@ -7,12 +7,12 @@ class SpineWasmUtil { public: static void spineWasmInit(); static void spineWasmDestroy(); - static uint32_t queryStoreMemory(uint32_t size); + static uint32_t createStoreMemory(uint32_t size); static void freeStoreMemory(); static spine::SkeletonData* querySpineSkeletonDataByUUID(const spine::String& uuid); - static spine::SkeletonData* createSpineSkeletonDataWithJson(const spine::String& jsonStr, const spine::String& altasStr); - static spine::SkeletonData* createSpineSkeletonDataWithBinary(uint32_t byteSize, const spine::String& altasStr); + static spine::SkeletonData* createSpineSkeletonDataWithJson(const spine::String& jsonStr, const spine::String& altasStr, const spine::Vector& textureNames, const spine::Vector& textureUUIDs); + static spine::SkeletonData* createSpineSkeletonDataWithBinary(uint32_t byteSize, const spine::String& altasStr, const spine::Vector& textureNames, const spine::Vector& textureUUIDs); static void registerSpineSkeletonDataWithUUID(spine::SkeletonData* data, const spine::String& uuid); static void destroySpineSkeletonDataWithUUID(const spine::String& uuid); static void destroySpineSkeleton(spine::Skeleton* skeleton); @@ -28,5 +28,4 @@ class SpineWasmUtil { static spine::Event* s_currentEvent; static uint8_t* s_mem; - static uint32_t s_memSize; }; diff --git a/native/cocos/platform/android/AndroidPlatform.cpp b/native/cocos/platform/android/AndroidPlatform.cpp index d1bd348a45d..8a8f192e750 100644 --- a/native/cocos/platform/android/AndroidPlatform.cpp +++ b/native/cocos/platform/android/AndroidPlatform.cpp @@ -158,7 +158,7 @@ class GameInputProxy { } ABORT_IF(_jniEnv != nullptr) - Paddleboat_init(_jniEnv, platform->_app->activity->javaGameActivity); + Paddleboat_init(_jniEnv, cc::JniHelper::getContext()); Paddleboat_setControllerStatusCallback(gameControllerStatusCallback, this); // This is needed to allow controller events through to us. // By default, only touch-screen events are passed through, to match the @@ -849,13 +849,12 @@ void AndroidPlatform::exit() { int32_t AndroidPlatform::loop() { IXRInterface *xr = CC_GET_XR_INTERFACE(); while (true) { - int events; struct android_poll_source *source; // suspend thread while _loopTimeOut set to -1 - while ((ALooper_pollAll(_loopTimeOut, nullptr, &events, - reinterpret_cast(&source))) >= 0) { - // process event + while (ALooper_pollOnce(_loopTimeOut, nullptr, nullptr, + reinterpret_cast(&source)) >= 0) { + // Process event if (source != nullptr) { source->process(_app, source); } diff --git a/native/cocos/platform/android/adpf_manager.cpp b/native/cocos/platform/android/adpf_manager.cpp index ff9e186944d..32c5a97cad7 100644 --- a/native/cocos/platform/android/adpf_manager.cpp +++ b/native/cocos/platform/android/adpf_manager.cpp @@ -104,7 +104,7 @@ bool ADPFManager::initializePowerManager() { #endif JNIEnv *env = cc::JniHelper::getEnv(); - auto *javaGameActivity = cc::JniHelper::getActivity(); + auto *applicationContext = cc::JniHelper::getContext(); // Retrieve class information jclass context = env->FindClass("android/content/Context"); @@ -117,7 +117,7 @@ bool ADPFManager::initializePowerManager() { // Get the method 'getSystemService' and call it jmethodID mid_getss = env->GetMethodID( context, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"); - jobject obj_power_service = env->CallObjectMethod(javaGameActivity, mid_getss, str_svc); + jobject obj_power_service = env->CallObjectMethod(applicationContext, mid_getss, str_svc); // Add global reference to the power service object. obj_power_service_ = env->NewGlobalRef(obj_power_service); @@ -189,7 +189,7 @@ bool ADPFManager::initializePerformanceHintManager() { return true; #else JNIEnv *env = cc::JniHelper::getEnv(); - auto *javaGameActivity = cc::JniHelper::getActivity(); + auto *applicationContext = cc::JniHelper::getContext(); // Retrieve class information jclass context = env->FindClass("android/content/Context"); @@ -203,7 +203,7 @@ bool ADPFManager::initializePerformanceHintManager() { jmethodID mid_getss = env->GetMethodID( context, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"); jobject obj_perfhint_service = env->CallObjectMethod( - javaGameActivity, mid_getss, str_svc); + applicationContext, mid_getss, str_svc); // Add global reference to the power service object. obj_perfhint_service_ = env->NewGlobalRef(obj_perfhint_service); diff --git a/native/cocos/platform/android/java/src/com/cocos/lib/CocosActivity.java b/native/cocos/platform/android/java/src/com/cocos/lib/CocosActivity.java index 55e93a24ba9..7942bd1184a 100644 --- a/native/cocos/platform/android/java/src/com/cocos/lib/CocosActivity.java +++ b/native/cocos/platform/android/java/src/com/cocos/lib/CocosActivity.java @@ -24,6 +24,7 @@ package com.cocos.lib; +import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -58,19 +59,19 @@ public class CocosActivity extends GameActivity { - private native void onCreateNative(); + private native void onCreateNative(Context applicationContext); @Override protected void onCreate(Bundle savedInstanceState) { onLoadNativeLibraries(); - onCreateNative(); + onCreateNative(this.getApplicationContext()); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().requestFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); // GlobalObject.init should be initialized at first. - GlobalObject.init(this, this); + GlobalObject.init(this.getApplicationContext(), this); CocosHelper.registerBatteryLevelReceiver(this); CocosHelper.init(); diff --git a/native/cocos/platform/android/java/src/com/cocos/lib/CocosDownloader.java b/native/cocos/platform/android/java/src/com/cocos/lib/CocosDownloader.java index c5f98b8b64a..da05c5c3f49 100644 --- a/native/cocos/platform/android/java/src/com/cocos/lib/CocosDownloader.java +++ b/native/cocos/platform/android/java/src/com/cocos/lib/CocosDownloader.java @@ -180,7 +180,11 @@ public void run() { host = domain.startsWith("www.") ? domain.substring(4) : domain; if (fileLen > 0) { - SharedPreferences sharedPreferences = GlobalObject.getContext().getSharedPreferences("breakpointDownloadSupport", Context.MODE_PRIVATE); + Context ctx = GlobalObject.getContext(); + if (ctx == null) { + return; + } + SharedPreferences sharedPreferences = ctx.getSharedPreferences("breakpointDownloadSupport", Context.MODE_PRIVATE); if (sharedPreferences.contains(host) && sharedPreferences.getBoolean(host, false)) { downloadStart = fileLen; } else { @@ -246,6 +250,9 @@ public void onResponse(Call call, Response response) throws IOException { // save breakpointDownloadSupport Data to SharedPreferences storage Context context = GlobalObject.getContext(); + if (context == null) { + return; + } SharedPreferences sharedPreferences = context.getSharedPreferences("breakpointDownloadSupport", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); long total = response.body().contentLength() + downloadStart; diff --git a/native/cocos/platform/android/java/src/com/cocos/lib/CocosWebViewHelper.java b/native/cocos/platform/android/java/src/com/cocos/lib/CocosWebViewHelper.java index adf17aa99c0..90bcc08b23a 100755 --- a/native/cocos/platform/android/java/src/com/cocos/lib/CocosWebViewHelper.java +++ b/native/cocos/platform/android/java/src/com/cocos/lib/CocosWebViewHelper.java @@ -80,7 +80,7 @@ public static int createWebView() { GlobalObject.runOnUiThread(new Runnable() { @Override public void run() { - CocosWebView webView = new CocosWebView(GlobalObject.getContext(), index); + CocosWebView webView = new CocosWebView(GlobalObject.getActivity(), index); FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); diff --git a/native/cocos/platform/android/jni/JniCocosEntry.cpp b/native/cocos/platform/android/jni/JniCocosEntry.cpp index 9334f01c263..5c2566d7cd4 100644 --- a/native/cocos/platform/android/jni/JniCocosEntry.cpp +++ b/native/cocos/platform/android/jni/JniCocosEntry.cpp @@ -39,7 +39,8 @@ void android_main(struct android_app *app) { } //NOLINTNEXTLINE -JNIEXPORT void JNICALL Java_com_cocos_lib_CocosActivity_onCreateNative(JNIEnv *env, jobject activity) { - cc::JniHelper::init(env, activity); +JNIEXPORT void JNICALL Java_com_cocos_lib_CocosActivity_onCreateNative(JNIEnv *env, jobject activity, jobject context) { + cc::JniHelper::init(env, context); + cc::JniHelper::setActivity(activity); } } diff --git a/native/cocos/platform/java/jni/JniHelper.cpp b/native/cocos/platform/java/jni/JniHelper.cpp index 8e7eff242a2..a4a39778059 100644 --- a/native/cocos/platform/java/jni/JniHelper.cpp +++ b/native/cocos/platform/java/jni/JniHelper.cpp @@ -120,6 +120,7 @@ jmethodID JniHelper::loadclassMethodMethodId = nullptr; jobject JniHelper::classloader = nullptr; std::function JniHelper::classloaderCallback = nullptr; jobject JniHelper::sContext = nullptr; +jobject JniHelper::sActivity = nullptr; JavaVM *JniHelper::sJavaVM = nullptr; JavaVM *JniHelper::getJavaVM() { @@ -139,9 +140,13 @@ void JniHelper::init(JNIEnv *env, jobject context) { void JniHelper::onDestroy() { if (JniHelper::sJavaVM) { - if (JniHelper::sContext) { - cc::JniHelper::getEnv()->DeleteGlobalRef(JniHelper::sContext); - JniHelper::sContext = nullptr; + if (sContext) { + cc::JniHelper::getEnv()->DeleteGlobalRef(sContext); + sContext = nullptr; + } + if (sActivity) { + cc::JniHelper::getEnv()->DeleteGlobalRef(sActivity); + sActivity = nullptr; } LOGD("JniHelper::onDestroy"); } @@ -199,7 +204,15 @@ jobject JniHelper::getContext() { jobject JniHelper::getActivity() { // TODO(cjh): In normal mode, sContext is Activity itself, but in surface-less mode, we need to // returns nullptr. - return sContext; + return sActivity; +} + +void JniHelper::setActivity(jobject activity) { + if (sActivity) { + cc::JniHelper::getEnv()->DeleteGlobalRef(sActivity); + sActivity = nullptr; + } + sActivity = cc::JniHelper::getEnv()->NewGlobalRef(activity); } #if CC_PLATFORM == CC_PLATFORM_OHOS diff --git a/native/cocos/platform/java/jni/JniHelper.h b/native/cocos/platform/java/jni/JniHelper.h index e69c5f04bfe..06ed926cbf2 100644 --- a/native/cocos/platform/java/jni/JniHelper.h +++ b/native/cocos/platform/java/jni/JniHelper.h @@ -74,6 +74,7 @@ class CC_DLL JniHelper { static JavaVM *getJavaVM(); static JNIEnv *getEnv(); static jobject getActivity(); + static void setActivity(jobject activity); static jobject getContext(); static void init(JNIEnv *env, jobject context); @@ -394,6 +395,7 @@ class CC_DLL JniHelper { private: static jobject sContext; + static jobject sActivity; static JavaVM *sJavaVM; static JNIEnv *cacheEnv(); diff --git a/native/external-config.json b/native/external-config.json index 00d984fac5a..8e35d682eea 100644 --- a/native/external-config.json +++ b/native/external-config.json @@ -3,6 +3,6 @@ "type": "github", "owner": "cocos-creator", "name": "engine-native-external", - "checkout": "v3.8.5-8" + "checkout": "v3.8.6-1" } } \ No newline at end of file diff --git a/native/utils/clear-platform.js b/native/utils/clear-platform.js index 42aa9ea1576..019afa301c1 100644 --- a/native/utils/clear-platform.js +++ b/native/utils/clear-platform.js @@ -253,7 +253,7 @@ async function minimizeBoost() { let boostURL; console.log(`Testing local url: ${BOOST_URL_LOCAL}`); try { - const FETCH_TIMEOUTOUT = 3000; + const FETCH_TIMEOUTOUT = 30 * 1000; const testLocal = await Promise.race( [fetch(BOOST_URL_LOCAL), new Promise((_, r)=> { setTimeout(()=> r(new Error('Request timed out')), FETCH_TIMEOUTOUT); })]);