Files
cocos-engine/pal/utils.ts
PP 11287df34a fix gl stencil on pc wechat game (#8871)
* support versionCompare util

* fix gl stencil
2021-06-24 13:59:59 +08:00

160 lines
5.9 KiB
TypeScript

/**
* This method clones methods in minigame enviroment, sucb as `wx`, `swan` etc. to a module called minigame.
* @param targetObject Usually it's specified as the minigame module.
* @param originObj Original minigame environment such as `wx`, `swan` etc.
*/
export function cloneObject (targetObject: any, originObj: any) {
Object.keys(originObj).forEach((key) => {
if (typeof originObj[key] === 'function') {
targetObject[key] = originObj[key].bind(originObj);
return;
}
targetObject[key] = originObj[key];
});
}
type MiningameAudioCallbackName = 'onPlay' | 'onPause' | 'onStop' | 'onSeek';
type InnerAudioContextPolyfillConfig = {
[CallbackName in MiningameAudioCallbackName]: boolean;
};
/**
* This method is to create a polyfill on minigame platform when the innerAudioContext callback doesn't work.
* @param minigameEnv Specify the minigame enviroment such as `wx`, `swan` etc.
* @param polyfillConfig Specify the field, if it's true, the polyfill callback will be applied.
* @param isAsynchronous Specify whether the callback is called asynchronous.
* @returns A polyfilled createInnerAudioContext method.
*/
export function createInnerAudioContextPolyfill (minigameEnv: any, polyfillConfig: InnerAudioContextPolyfillConfig, isAsynchronous = false) {
return () => {
const audioContext: InnerAudioContext = minigameEnv.createInnerAudioContext();
// add polyfill if onPlay method doesn't work this platform
if (polyfillConfig.onPlay) {
const originalPlay = audioContext.play;
let _onPlayCB: (()=> void) | null = null;
Object.defineProperty(audioContext, 'onPlay', {
configurable: true,
value (cb: ()=> void) {
_onPlayCB = cb;
},
});
Object.defineProperty(audioContext, 'play', {
configurable: true,
value () {
originalPlay.call(audioContext);
if (_onPlayCB) {
if (isAsynchronous) {
setTimeout(_onPlayCB, 0);
} else {
_onPlayCB();
}
}
},
});
}
// add polyfill if onPause method doesn't work this platform
if (polyfillConfig.onPause) {
const originalPause = audioContext.pause;
let _onPauseCB: (()=> void) | null = null;
Object.defineProperty(audioContext, 'onPause', {
configurable: true,
value (cb: ()=> void) {
_onPauseCB = cb;
},
});
Object.defineProperty(audioContext, 'pause', {
configurable: true,
value () {
originalPause.call(audioContext);
if (_onPauseCB) {
if (isAsynchronous) {
setTimeout(_onPauseCB, 0);
} else {
_onPauseCB();
}
}
},
});
}
// add polyfill if onStop method doesn't work on this platform
if (polyfillConfig.onStop) {
const originalStop = audioContext.stop;
let _onStopCB: (()=> void) | null = null;
Object.defineProperty(audioContext, 'onStop', {
configurable: true,
value (cb: ()=> void) {
_onStopCB = cb;
},
});
Object.defineProperty(audioContext, 'stop', {
configurable: true,
value () {
originalStop.call(audioContext);
if (_onStopCB) {
if (isAsynchronous) {
setTimeout(_onStopCB, 0);
} else {
_onStopCB();
}
}
},
});
}
// add polyfill if onSeeked method doesn't work on this platform
if (polyfillConfig.onSeek) {
const originalSeek = audioContext.seek;
let _onSeekCB: (()=> void) | null = null;
Object.defineProperty(audioContext, 'onSeeked', {
configurable: true,
value (cb: ()=> void) {
_onSeekCB = cb;
},
});
Object.defineProperty(audioContext, 'seek', {
configurable: true,
value (time: number) {
originalSeek.call(audioContext, time);
if (_onSeekCB) {
if (isAsynchronous) {
setTimeout(_onSeekCB, 0);
} else {
_onSeekCB();
}
}
},
});
}
return audioContext;
};
}
/**
* Compare two version, version should in pattern like 3.0.0.
* If versionA > versionB, return number larger than 0.
* If versionA = versionB, return number euqal to 0.
* If versionA < versionB, return number smaller than 0.
* @param versionA
* @param versionB
*/
export function versionCompare (versionA: string, versionB: string): number {
const versionRegExp = /\d+\.\d+\.\d+/;
if (!(versionRegExp.test(versionA) && versionRegExp.test(versionB))) {
console.warn('wrong format of version when compare version');
return 0;
}
const versionNumbersA = versionA.split('.').map((num: string) => Number.parseInt(num));
const versionNumbersB = versionB.split('.').map((num: string) => Number.parseInt(num));
for (let i = 0; i < 3; ++i) {
const numberA = versionNumbersA[i];
const numberB = versionNumbersB[i];
if (numberA !== numberB) {
return numberA - numberB;
}
}
return 0;
}