UNPKG

dragonbones-runtime

Version:

the tools to build dragonbones file for diffrent framework

1,015 lines (939 loc) 45.1 kB
namespace dragonBones { type ConfigItem = { static?: boolean | ConfigItem; getter?: boolean; setter?: boolean | Function; array?: boolean; source?: string; replace?: any; }; export declare const EgretTextureData: any; export declare const EgretTextureAtlasData: any; export declare const EgretDisplayProxy: any; export declare const EgretArmatureProxy: any; export declare const EgretSlot: any; interface BindingClass { $$: { ptr: number; ptrType: { name: string; }, count: { value: number; } } } interface STDVector<T> extends BindingClass { size(): number; get(index: number): T; set(index: number, value: T): void; push_back(value: T): void; delete(): void; } interface STDMap<T> extends BindingClass { get(key: string): T; } export interface PEgretTextureData extends TextureData, BindingClass { textureID: number; renderTexture: egret.Texture | null; } export interface PEgretTextureAtlasData extends TextureAtlasData, BindingClass { textureID: number; renderTexture: egret.Texture | null; _renderTexture: egret.Texture | null; } export interface PEgretDisplayProxy extends BaseObject, BindingClass { _display: egret.DisplayObject | null; setDisplayInfo(id: number, type: DisplayType, armature: Armature | null): void; getDisplayType(): DisplayType; getDisplayID(): number; getArmature(): number; } export interface PEgretArmatureProxy extends IArmatureProxy, BindingClass { _display: EgretArmatureDisplay; getLastEventObject(): EventObject; } export interface PEgretSlot extends Slot, BindingClass { _displays: Array<egret.DisplayObject | Armature | null>; getEgretDisplayList(): STDVector<PEgretDisplayProxy | null>; setEgretDisplayList(value: STDVector<PEgretDisplayProxy | null>, isInternal: boolean): any; getEgretRawDisplay(): PEgretDisplayProxy; getEgretMeshDisplay(): PEgretDisplayProxy; getEgretDisplay(): PEgretDisplayProxy | null; setEgretDisplay(value: PEgretDisplayProxy | null): void; } export function stdVectorToArray<T>(stdVector: STDVector<T>, array: Array<T>): void { for (let i = 0, l = stdVector.size(); i < l; ++i) { array[i] = stdVector.get(i); } } export function stdMapToMap<T>(stdMap: STDMap<T>, map: Map<T>): void { const stdVector = Module["getMapKeys" + stdMap.$$.ptrType.name.replace("*", "")](stdMap); const array = new Array<string>(); stdVectorToArray(stdVector, array) for (let k of array) { for (let i = 0, l = k.length; i < l; ++i) { if (k.charCodeAt(i) > 255) { k = encodeURI(k); break; } } map[k] = stdMap.get(k); } } let isInitialed = false; export function modifyCPPAPI(): void { if (isInitialed) { return; } isInitialed = true; (dragonBones as any).webAssemblyModule = Module; const WASMPoint = Module.WASMPoint; // TODO const config: { [key: string]: { [key: string]: ConfigItem | boolean } } = { DragonBones: { clock: { getter: true }, eventManager: { getter: true } }, BaseObject: { borrowObject: { static: true, replace: function <T extends BaseObject>(this: any, objectConstructor: { new(): T; }): T { const object = new objectConstructor(); return object; } }, setMaxCount: { static: true, replace: function (this: any, objectConstructor: (typeof BaseObject) | null, maxCount: number): void { objectConstructor; // TODO this._c_setMaxCount(0, maxCount); } }, clearPool: { static: true, replace: function (this: any, objectConstructor: (typeof BaseObject) | null = null): void { objectConstructor; // TODO this._c_clearPool(0); } } }, WASMPoint: { // TODO }, UserData: { ints: { getter: true, array: true }, floats: { getter: true, array: true }, strings: { getter: true, array: true } }, ActionData: { bone: { getter: true, setter: true }, slot: { getter: true, setter: true }, data: { getter: true, setter: true }, }, DragonBonesData: { extend: true, frameIndices: { getter: true }, armatureNames: { getter: true, array: true }, binary: { getter: true }, userData: { getter: true, setter: true }, returnToPool: { replace: function (this: any): void { webAssemblyModule._free(this.binary); webAssemblyModule.setDataBinary(this, 0, 0, 0, 0, 0, 0, 0); this._c_returnToPool(); } } }, ArmatureData: { extend: true, aabb: { getter: true }, animationNames: { getter: true, array: true }, sortedBones: { getter: true, array: true }, sortedSlots: { getter: true, array: true }, defaultActions: { getter: true, array: true }, actions: { getter: true }, // defaultSkin: { getter: true, setter: true }, defaultAnimation: { getter: true, setter: true }, userData: { getter: true, setter: true }, parent: { getter: true, setter: true } }, BoneData: { transform: { getter: true }, constraints: { getter: true, array: true }, userData: { getter: true, setter: true }, parent: { getter: true, setter: true } }, ConstraintData: { target: { getter: true, setter: true }, bone: { getter: true, setter: true }, root: { getter: true, setter: true } }, IKConstraintData: {}, SlotData: { DEFAULT_COLOR: { getter: true, static: true }, color: { getter: true, setter: true }, userData: { getter: true, setter: true }, parent: { getter: true, setter: true } }, SkinData: { extend: true, displays: { getter: true, replace: function (this: any): Map<any> { const stdMap = this._c_get_displays() as STDMap<any>; const map = {}; stdMapToMap(stdMap, map); return map; } } }, DisplayData: { transform: { getter: true }, parent: { getter: true, setter: true } }, ImageDisplayData: { pivot: { getter: true }, texture: { getter: true, setter: true } }, ArmatureDisplayData: { actions: { getter: true, array: true }, armature: { getter: true, setter: true } }, MeshDisplayData: { weight: { getter: true, setter: true } }, BoundingBoxDisplayData: { boundingBox: { getter: true, setter: true } }, WeightData: { bones: { getter: true, array: true } }, BoundingBoxData: {}, RectangleBoundingBoxData: {}, EllipseBoundingBoxData: {}, PolygonBoundingBoxData: { vertices: { getter: true } // }, AnimationData: { actionTimeline: { getter: true, setter: true }, zOrderTimeline: { getter: true, setter: true }, parent: { getter: true, setter: true } }, TimelineData: { }, AnimationConfig: { }, TextureAtlasData: { textures: { getter: true, replace: function (this: any): Map<TextureData> { const stdMap = this._c_get_textures() as STDMap<TextureData>; const map = {}; stdMapToMap(stdMap, map); return map; } }, }, TextureData: { region: { getter: true }, frame: { getter: true, setter: true }, parent: { getter: true, setter: true } }, IArmatureProxy: { armature: { getter: true }, animation: { getter: true }, }, Armature: { extend: true, init: { replace: function (this: Armature, armatureData: ArmatureData, proxy: IArmatureProxy, display: any, dragonBones: DragonBones): void { Module.armatureInit(this, armatureData, proxy, display, dragonBones); } }, armatureData: { getter: true }, userData: { getter: true }, getBones: { array: true }, getSlots: { array: true }, animation: { getter: true }, proxy: { getter: true }, eventDispatcher: { getter: true, replace: function (this: Armature): EgretArmatureDisplay { return (this.proxy as PEgretArmatureProxy)._display; } }, display: { getter: true, replace: function (this: Armature): EgretArmatureDisplay { return (this.proxy as PEgretArmatureProxy)._display; } }, clock: { getter: true, setter: true }, parent: { getter: true }, invalidUpdate: { replace: function (this: any, boneName: string | null = null, updateSlotDisplay: boolean = false): void { this._c_invalidUpdate(boneName || "", updateSlotDisplay); } }, intersectsSegment: { replace: function ( this: any, xA: number, yA: number, xB: number, yB: number, intersectionPointA: { x: number, y: number } | null = null, intersectionPointB: { x: number, y: number } | null = null, normalRadians: { x: number, y: number } | null = null ): Slot | null { let a = null; let b = null; let c = null; if (intersectionPointA) { a = WASMPoint.getHelpPointA(); } if (intersectionPointB) { b = WASMPoint.getHelpPointB(); } if (normalRadians) { c = WASMPoint.getHelpPointB(); } const r = this._c_intersectsSegment(xA, yA, xB, yB, a, b, c); if (intersectionPointA) { intersectionPointA.x = a.x; intersectionPointA.y = a.y; } if (intersectionPointB) { intersectionPointB.x = b.x; intersectionPointB.y = b.y; } if (normalRadians) { normalRadians.x = c.x; normalRadians.y = c.y; } return r; } }, getBoneByDisplay: { replace: function (this: Armature, display: egret.DisplayObject): Bone | null { const slot = this.getSlotByDisplay(display); return slot !== null ? slot.parent : null; } }, getSlotByDisplay: { replace: function (this: Armature, display: egret.DisplayObject): Slot | null { for (const slot of this.getSlots()) { if (slot.display === display) { return slot; } } return null; } }, hasEventListener: { replace: function (this: Armature, type: string) { // TODO @deprecated (this.display as EgretArmatureDisplay).hasEventListener(type); } }, addEventListener: { replace: function (this: Armature, type: string, listener: Function, target: any) { // TODO @deprecated (this.display as EgretArmatureDisplay).addEventListener(type, listener, target); } }, removeEventListener: { replace: function (this: Armature, type: string, listener: Function, target: any) { // TODO @deprecated (this.display as EgretArmatureDisplay).removeEventListener(type, listener, target); } }, replacedTexture: { // TODO @deprecated getter: true, setter: function (this: Armature) { console.log("WebAssembly can not support set replacedTexture yet."); }, replace: function (this: Armature) { console.log("WebAssembly can not support get replacedTexture yet."); } }, replaceTexture: { // TODO @deprecated replace: function (this: Armature) { console.log("WebAssembly can not support replaceTexture yet."); } }, enableAnimationCache: { // TODO @deprecated replace: function (this: Armature, frameRate: number): void { this.cacheFrameRate = frameRate; } }, getDisplay: { // TODO @deprecated replace: function (this: Armature) { return this.display; } } }, TransformObject: { globalTransformMatrix: { getter: true }, global: { getter: true }, offset: { getter: true }, origin: { getter: true }, armature: { getter: true }, parent: { getter: true } }, Bone: { boneData: { getter: true }, getBones: { array: true }, getSlots: { array: true }, slot: { getter: true, replace: function (this: Bone): Slot | null { console.warn("已废弃,请参考 @see"); for (const slot of this.armature.getSlots()) { if (slot.parent === this) { return slot; } } return null; } } }, Constraint: { target: { getter: true, setter: true }, bone: { getter: true, setter: true }, root: { getter: true, setter: true } }, IKConstraint: { }, Slot: { slotData: { getter: true }, rawDisplayDatas: { getter: true, setter: true }, boundingBoxData: { getter: true }, childArmature: { getter: true, setter: true }, getDisplay: { replace: function (this: Slot): any { return this.display; } }, setDisplay: { replace: function (this: Slot, value: any) { this.display = value; } } }, IAnimatable: {}, WorldClock: { clock: { static: { getter: true, replace: function (this: any): WorldClock { return this.getStaticClock(); } }, getter: true, setter: true }, contains: { replace: function (this: any, value: IAnimatable): boolean { if (value instanceof Armature) { return this._c_contains((value as any).getAnimatable()); } return this._c_contains(value); } }, add: { replace: function (this: any, value: IAnimatable): void { if (value instanceof Armature) { this._c_add((value as any).getAnimatable()); } else { this._c_add(value); } } }, remove: { replace: function (this: any, value: IAnimatable): void { if (value instanceof Armature) { this._c_remove((value as any).getAnimatable()); } else { this._c_remove(value); } } }, advanceTime: { replace: function (this: any, passedTime: number): void { if (passedTime < 0.0) { passedTime = new Date().getTime() * 0.001 - this.time; } this._c_advanceTime(passedTime); } } }, Animation: { stop: { replace: function (this: any, animationName: string | null): void { this._c_stop(animationName || ""); } }, play: { replace: function (this: any, animationName: string | null, playTimes: number = -1): AnimationState | null { return this._c_play(animationName || "", playTimes); } }, fadeIn: { replace: function ( this: any, animationName: string, fadeInTime: number = -1.0, playTimes: number = -1, layer: number = 0, group: string | null = null, fadeOutMode: AnimationFadeOutMode = AnimationFadeOutMode.SameLayerAndGroup ): AnimationState | null { return this._c_fadeIn(animationName || "", fadeInTime, playTimes, layer, group || "", fadeOutMode); } }, gotoAndPlayByTime: { replace: function ( this: any, animationName: string, time: number = 0.0, playTimes: number = -1 ): AnimationState | null { return this._c_gotoAndPlayByTime(animationName, time, playTimes); } }, gotoAndPlayByFrame: { replace: function ( this: any, animationName: string, frame: number = 0, playTimes: number = -1 ): AnimationState | null { return this._c_gotoAndPlayByFrame(animationName, frame, playTimes); } }, gotoAndPlayByProgress: { replace: function ( this: any, animationName: string, progress: number = 0.0, playTimes: number = -1 ): AnimationState | null { return this._c_gotoAndPlayByProgress(animationName, progress, playTimes); } }, gotoAndStopByTime: { replace: function ( this: any, animationName: string, time: number = 0.0 ): AnimationState | null { return this._c_gotoAndStopByTime(animationName, time); } }, gotoAndStopByFrame: { replace: function ( this: any, animationName: string, frame: number = 0.0 ): AnimationState | null { return this._c_gotoAndStopByFrame(animationName, frame); } }, gotoAndStopByProgress: { replace: function ( this: any, animationName: string, progress: number = 0.0 ): AnimationState | null { return this._c_gotoAndStopByProgress(animationName, progress); } }, getStates: { array: true }, animationNames: { getter: true, array: true }, animationConfig: { getter: true }, lastAnimationState: { getter: true }, gotoAndPlay: { replace: function ( this: Animation, animationName: string, fadeInTime: number = -1, duration: number = -1, playTimes: number = -1 ): AnimationState | null { console.warn("已废弃,请参考 play()"); console.warn("已废弃,请参考 fadeIn()"); const animationState = this.fadeIn(animationName, fadeInTime, playTimes); if (animationState != null && duration >= 0.0) { if (duration = 0.0) { animationState.timeScale = 0.0; } else { animationState.timeScale = animationState.totalTime / duration; } } return animationState; } }, gotoAndStop: { replace: function (this: Animation, animationName: string, time: number = 0): AnimationState | null { console.warn("已废弃,请参考 @see"); return this.gotoAndStopByTime(animationName, time); } } }, AnimationState: { animationData: { getter: true }, fadeOut: { replace: function (this: any, fadeOutTime: number, pausePlayhead: boolean = true): void { this._c_fadeOut(fadeOutTime, pausePlayhead); } }, addBoneMask: { replace: function (this: any, name: string, recursive: boolean = true): void { this._c_addBoneMask(name, recursive); } }, removeBoneMask: { replace: function (this: any, name: string, recursive: boolean = true): void { this._c_removeBoneMask(name, recursive); } } }, EventObject: { START: { static: true, replace: EventObject.START }, LOOP_COMPLETE: { static: true, replace: EventObject.LOOP_COMPLETE }, COMPLETE: { static: true, replace: EventObject.COMPLETE }, FADE_IN: { static: true, replace: EventObject.FADE_IN }, FADE_IN_COMPLETE: { static: true, replace: EventObject.FADE_IN_COMPLETE }, FADE_OUT: { static: true, replace: EventObject.FADE_OUT }, FADE_OUT_COMPLETE: { static: true, replace: EventObject.FADE_OUT_COMPLETE }, FRAME_EVENT: { static: true, replace: EventObject.FRAME_EVENT }, SOUND_EVENT: { static: true, replace: EventObject.SOUND_EVENT }, armature: { getter: true }, bone: { getter: true }, slot: { getter: true }, animationState: { getter: true }, data: { getter: true } }, EgretTextureAtlasData: { extend: true, renderTexture: { getter: true, setter: function (this: PEgretTextureAtlasData, value: egret.Texture | null): void { if (this._renderTexture === value) { return; } this._renderTexture = value; let textureID = -1; if (this._renderTexture && !this._renderTexture.$textureId) { egret.WebAssemblyNode.setValuesToBitmapData(this._renderTexture); textureID = this._renderTexture.$textureId; } this.textureID = textureID; if (this._renderTexture) { const bitmapData = this._renderTexture.bitmapData; const textureAtlasWidth = this.width > 0.0 ? this.width : bitmapData.width; const textureAtlasHeight = this.height > 0.0 ? this.height : bitmapData.height; for (let k in this.textures) { const textureData = this.textures[k] as PEgretTextureData; const region = textureData.region; const subTextureWidth = region.width; const subTextureHeight = region.height; if (!textureData.renderTexture) { // May be undefined. textureData.renderTexture = new egret.Texture(); textureData.renderTexture.disposeBitmapData = false; } textureData.renderTexture._bitmapData = bitmapData; if (textureData.rotated) { textureData.renderTexture.$initData( region.x, region.y, subTextureHeight, subTextureWidth, 0, 0, subTextureHeight, subTextureWidth, textureAtlasWidth, textureAtlasHeight ); } else { textureData.renderTexture.$initData( region.x, region.y, subTextureWidth, subTextureHeight, 0, 0, subTextureWidth, subTextureHeight, textureAtlasWidth, textureAtlasHeight ); } (egret as any).WebAssemblyNode.setValuesToBitmapData(textureData.renderTexture); textureData.textureID = textureData.renderTexture.$textureId; } } else { for (let k in this.textures) { const textureData = this.textures[k] as PEgretTextureData; textureData.renderTexture = null; } } }, replace: function (this: PEgretTextureAtlasData): egret.Texture | null { return this._renderTexture; } }, createTexture: { replace: function (this: PEgretTextureAtlasData): TextureData { return BaseObject.borrowObject(EgretTextureData) as any; } }, returnToPool: { replace: function (this: PEgretTextureAtlasData): void { (this as any)._c_returnToPool(); this._renderTexture = null; } } }, EgretTextureData: { extend: true, _onClear: { replace: function (this: PEgretTextureData): void { if (this.renderTexture) { this.renderTexture.dispose(); this.renderTexture = null; } } } }, EgretDisplayProxy: { extend: true, }, EgretArmatureProxy: { extend: true, _dispatchEvent: { replace: function (this: PEgretArmatureProxy, type: string): void { this._display._dispatchEvent(type, this.getLastEventObject()); } }, hasEvent: { replace: function (this: PEgretArmatureProxy, type: string): boolean { return this._display.hasEvent(type); } }, addEvent: { replace: function (this: PEgretArmatureProxy, type: EventStringType, listener: (event: EgretEvent) => void, target: any): void { this._display.addEvent(type, listener, target); } }, removeEvent: { replace: function (this: PEgretArmatureProxy, type: EventStringType, listener: (event: EgretEvent) => void, target: any): void { this._display.removeEvent(type, listener, target); } } }, EgretSlot: { extend: true, _setDisplayList: { replace: function (this: PEgretSlot, value: Array<egret.DisplayObject | Armature | null>): void { const stdVector = new Module.EgretDisplayVector() as STDVector<PEgretDisplayProxy | null>; for (let i = 0, l = value.length; i < l; ++i) { const display = value[i]; if (display instanceof Armature) { stdVector.push_back((display.proxy as any)._c_get_display()); } else if (display !== null) { if (display === this.rawDisplay) { stdVector.push_back(this.getEgretRawDisplay()); } else { stdVector.push_back(this.getEgretMeshDisplay()); } } else { stdVector.push_back(null); } } this.setEgretDisplayList(stdVector, true); stdVector.delete(); } }, init: { replace: function (this: PEgretSlot, slotData: SlotData, displayDatas: STDVector<DisplayData | null> | null, rawDisplay: egret.Bitmap, meshDisplay: egret.Mesh): void { const egretRawDisplayProxy = BaseObject.borrowObject(EgretDisplayProxy) as any as PEgretDisplayProxy; const egretMeshDisplayProxy = BaseObject.borrowObject(EgretDisplayProxy) as any as PEgretDisplayProxy; egretRawDisplayProxy.setDisplayInfo(rawDisplay.$waNode.id, DisplayType.Image, null); egretMeshDisplayProxy.setDisplayInfo(meshDisplay.$waNode.id, DisplayType.Mesh, null); egretRawDisplayProxy._display = rawDisplay; egretMeshDisplayProxy._display = meshDisplay; Module.slotInit(this, slotData, displayDatas, egretRawDisplayProxy, egretMeshDisplayProxy); } }, displayList: { getter: true, setter: function (this: PEgretSlot, value: Array<egret.DisplayObject | Armature | null>): void { const stdVector = new Module.EgretDisplayVector() as STDVector<PEgretDisplayProxy | null>; for (let i = 0, l = value.length; i < l; ++i) { const display = value[i]; if (display instanceof Armature) { stdVector.push_back((display.proxy as any)._c_get_display()); } else if (display !== null) { if (display === this.rawDisplay) { stdVector.push_back(this.getEgretRawDisplay()); } else if (display === this.meshDisplay) { stdVector.push_back(this.getEgretMeshDisplay()); } else { // TODO search all display. const egretDisplayProxy = BaseObject.borrowObject(EgretDisplayProxy) as any as PEgretDisplayProxy; const displayID = display.$waNode.id; egretDisplayProxy.setDisplayInfo(displayID, value instanceof egret.Mesh ? DisplayType.Mesh : DisplayType.Image, null); stdVector.push_back(egretDisplayProxy); } } else { stdVector.push_back(null); } } this.setEgretDisplayList(stdVector, false); stdVector.delete(); }, replace: function (this: PEgretSlot): Array<egret.DisplayObject | Armature | null> { if (this._displays) { this._displays.length = 0; } else { this._displays = []; } const displays = this.getEgretDisplayList(); for (let i = 0, l = displays.size(); i < l; ++i) { const display = displays.get(i); this._displays.push(display ? display._display : null); } return this._displays.concat(); } }, rawDisplay: { getter: true, replace: function (this: PEgretSlot): egret.Bitmap { return this.getEgretRawDisplay()._display as any; } }, meshDisplay: { getter: true, replace: function (this: PEgretSlot): egret.Mesh { return this.getEgretMeshDisplay()._display as any; } }, display: { getter: true, setter: function (this: PEgretSlot, value: egret.DisplayObject | null): void { if (value instanceof Armature) { this.setEgretDisplay((value.proxy as any)._c_get_display()); } else if (value !== null) { if (value === this.rawDisplay) { this.setEgretDisplay(this.getEgretRawDisplay()); } else if (value === this.meshDisplay) { this.setEgretDisplay(this.getEgretMeshDisplay()); } else { // TODO search all display. const egretDisplayProxy = BaseObject.borrowObject(EgretDisplayProxy) as any as PEgretDisplayProxy; const displayID = value.$waNode.id; egretDisplayProxy.setDisplayInfo(displayID, value instanceof egret.Mesh ? DisplayType.Mesh : DisplayType.Image, null); this.setEgretDisplay(egretDisplayProxy); } } else { this.setEgretDisplay(null); } }, replace: function (this: PEgretSlot): egret.DisplayObject | null { const egretDisplay = this.getEgretDisplay(); return egretDisplay ? egretDisplay._display : null; } } } }; function modifyTarget(target: any, memberKey: string, memberConfig: ConfigItem): void { if (memberConfig.getter && memberConfig.setter) { if (memberConfig.array) { // TODO } else { Object.defineProperty(target, memberKey, { get: memberConfig.replace || target["_c_get_" + (memberConfig.source || memberKey)], set: memberConfig.setter instanceof Function ? memberConfig.setter : target["_c_set_" + (memberConfig.source || memberKey)], enumerable: true, configurable: true }); } } else if (memberConfig.getter) { if (memberConfig.replace) { Object.defineProperty(target, memberKey, { get: memberConfig.replace, enumerable: true, configurable: true }); } else if (memberConfig.array) { Object.defineProperty(target, memberKey, { get: function (this: any): Array<any> | null { const stdVector = this[memberConfig.source || ("_c_get_" + memberKey)](); if (stdVector) { const array = this["_js_" + memberKey] = this["_js_" + memberKey] || new Array<any>(); stdVectorToArray(stdVector, array); return array; } return null; }, enumerable: true, configurable: true }); } else { if (memberConfig.source === memberKey) { memberConfig.source = ""; target["_c_get_" + memberKey] = target[memberKey]; } Object.defineProperty(target, memberKey, { get: target[memberConfig.source || ("_c_get_" + memberKey)], enumerable: true, configurable: true }); } } else if (memberConfig.setter) { if (memberConfig.array) { // TODO } else { Object.defineProperty(target, memberKey, { set: memberConfig.setter instanceof Function ? memberConfig.setter : target["_c_set_" + (memberConfig.source || memberKey)], enumerable: true, configurable: true }); } } else if (memberConfig.array) { target["_c_" + memberKey] = target[memberConfig.source || memberKey]; target[memberKey] = function (this: any): Array<any> | null { const stdVector = this["_c_" + memberKey].apply(this, arguments) as STDVector<any>; if (stdVector) { const array = this["_js_" + memberKey] = this["_js_" + memberKey] || new Array<any>(); array.length = 0; stdVectorToArray(stdVector, array); return array; } return null; } } else if (memberConfig.replace) { const rawFunction = target[memberConfig.source || memberKey]; if (rawFunction) { target["_c_" + memberKey] = rawFunction; } target[memberKey] = memberConfig.replace; } } for (let classKey in config) { const classConfig = config[classKey]; const extend = classConfig["extend"] as boolean | undefined; const clazz = extend ? Module[classKey].extend(classKey + "Wrapper", {}) : Module[classKey]; const classPrototype = clazz.prototype; if (classKey in dragonBones) { // console.log(`Replace ${classKey}.`); } for (let memberKey in classConfig) { if (memberKey === "extend") { continue; } const memberConfig = classConfig[memberKey] as ConfigItem; if (memberConfig.static && typeof memberConfig.static !== "boolean") { modifyTarget(clazz, memberKey, memberConfig.static); } else { const target = memberConfig.static ? clazz : classPrototype; modifyTarget(target, memberKey, memberConfig); } } (dragonBones as any)[classKey] = clazz; } } egret.WebAssembly.addModuleCallback(modifyCPPAPI, null); }