From 3a470a6dff6d00fefc41cbe9b7961e7c585daa4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leslie=20Leigh=20=28=E6=9D=8E=E7=9A=84=E5=BA=8F=29?= Date: Thu, 13 Jul 2023 14:18:53 +0800 Subject: [PATCH 1/5] Add utilities to check integrity of pal implementations (#15694) * Add utilities to check integrity of pal implementation * Fix screen adapter * Fix game pad input * Apply suggestions from code review Co-authored-by: PP * Add license --------- Co-authored-by: PP --- @types/pal/input.d.ts | 1 + @types/pal/screen-adapter.d.ts | 8 +-- @types/pal/system-info.d.ts | 6 ++- pal/env/minigame/env.ts | 3 ++ pal/env/native/env.ts | 5 +- pal/env/runtime/env.ts | 3 ++ pal/env/web/env.ts | 4 ++ pal/input/minigame/index.ts | 4 ++ pal/input/native/index.ts | 4 ++ pal/input/web/index.ts | 4 ++ pal/integrity-check.ts | 54 +++++++++++++++++++ pal/minigame/alipay.ts | 3 ++ pal/minigame/baidu.ts | 3 ++ pal/minigame/bytedance.ts | 3 ++ pal/minigame/non-minigame.ts | 4 ++ pal/minigame/runtime.ts | 3 ++ pal/minigame/taobao.ts | 3 ++ pal/minigame/taobao_minigame.ts | 3 ++ pal/minigame/wechat.ts | 3 ++ pal/minigame/wechat_mini_program.ts | 3 ++ pal/minigame/xiaomi.ts | 3 ++ pal/pacer/pacer-minigame.ts | 3 ++ pal/pacer/pacer-native.ts | 3 ++ pal/pacer/pacer-web.ts | 3 ++ pal/screen-adapter/minigame/screen-adapter.ts | 3 ++ pal/screen-adapter/native/screen-adapter.ts | 3 ++ pal/screen-adapter/web/screen-adapter.ts | 3 ++ pal/system-info/minigame/system-info.ts | 3 ++ pal/system-info/native/system-info.ts | 3 ++ pal/system-info/web/system-info.ts | 3 ++ pal/wasm/wasm-minigame.ts | 3 ++ pal/wasm/wasm-native.ts | 3 ++ pal/wasm/wasm-web.ts | 3 ++ 33 files changed, 154 insertions(+), 9 deletions(-) create mode 100644 pal/integrity-check.ts diff --git a/@types/pal/input.d.ts b/@types/pal/input.d.ts index 5dfb192becb..892fa1c294f 100644 --- a/@types/pal/input.d.ts +++ b/@types/pal/input.d.ts @@ -52,6 +52,7 @@ declare module 'pal/input' { * Class designed for gamepad input */ export class GamepadInputDevice { + private constructor(deviceId: number); /** * @engineInternal */ diff --git a/@types/pal/screen-adapter.d.ts b/@types/pal/screen-adapter.d.ts index 505e2e661fb..363e6f42326 100644 --- a/@types/pal/screen-adapter.d.ts +++ b/@types/pal/screen-adapter.d.ts @@ -79,12 +79,6 @@ declare module 'pal/screen-adapter' { */ public get resolution (): import('cocos/core/math').Size; - /** - * Update the resolution by resolutionScale. - * This method rebuilds the size of frame buffer and the size of canvas. - * This method should be called when window resized (fullscreen changing included) or the resolution scale changed. - */ - private _updateResolution (); /** * Get and set the resolution scale of screen, which will affect the quality of the rendering. * Note: if this value is set too high, the rendering performance of GPU will be reduced, this value is 1 by default. @@ -123,4 +117,6 @@ declare module 'pal/screen-adapter' { } export const screenAdapter: ScreenAdapter; + + export {}; } diff --git a/@types/pal/system-info.d.ts b/@types/pal/system-info.d.ts index 4cb322b7afe..cec8f7f032c 100644 --- a/@types/pal/system-info.d.ts +++ b/@types/pal/system-info.d.ts @@ -57,10 +57,12 @@ declare module 'pal/system-info' { */ public exit(): void; - on (event: PalSystemEvent, cb: (...args: any)=>void, target?: any): void; - off (event: PalSystemEvent, cb?: (...args: any)=>void, target?: any): void; + on (event: PalSystemEvent, cb: (...args: any) => void, target?: any): void; + off (event: PalSystemEvent, cb?: (...args: any) => void, target?: any): void; // TODO: support onError } export const systemInfo: SystemInfo; + + export {}; } diff --git a/pal/env/minigame/env.ts b/pal/env/minigame/env.ts index cd57091c42a..21fa0118eb3 100644 --- a/pal/env/minigame/env.ts +++ b/pal/env/minigame/env.ts @@ -24,6 +24,7 @@ /* eslint-disable import/no-dynamic-require */ import { BAIDU, TAOBAO, TAOBAO_MINIGAME, WECHAT, WECHAT_MINI_PROGRAM, XIAOMI } from 'internal:constants'; +import { checkPalIntegrity, withImpl } from '../../integrity-check'; declare const require: (path: string) => any; declare const __baiduRequire: (path: string) => any; @@ -54,3 +55,5 @@ export function loadJsFile (path: string): any { } return require(`../${path}`); } + +checkPalIntegrity(withImpl()); diff --git a/pal/env/native/env.ts b/pal/env/native/env.ts index 082671beb31..65db77f5cdd 100644 --- a/pal/env/native/env.ts +++ b/pal/env/native/env.ts @@ -22,7 +22,8 @@ THE SOFTWARE. */ -import { PREVIEW } from "internal:constants"; +import { PREVIEW } from 'internal:constants'; +import { checkPalIntegrity, withImpl } from '../../integrity-check'; declare const require: (path: string) => Promise; @@ -69,3 +70,5 @@ export function loadJsFile (path: string): Promise { return require(`${path}`); } } + +checkPalIntegrity(withImpl()); diff --git a/pal/env/runtime/env.ts b/pal/env/runtime/env.ts index cedeca6aa61..d418ba86b1f 100644 --- a/pal/env/runtime/env.ts +++ b/pal/env/runtime/env.ts @@ -23,6 +23,7 @@ */ import { COCOSPLAY, HUAWEI, OPPO, VIVO } from 'internal:constants'; +import { checkPalIntegrity, withImpl } from '../../integrity-check'; declare const require: (path: string) => Promise; declare const ral: any; @@ -52,3 +53,5 @@ export function loadJsFile (path: string): Promise { // eslint-disable-next-line import/no-dynamic-require return require(`${path}`); } + +checkPalIntegrity(withImpl()); diff --git a/pal/env/web/env.ts b/pal/env/web/env.ts index ff35915bbcb..e0aee6672a7 100644 --- a/pal/env/web/env.ts +++ b/pal/env/web/env.ts @@ -22,6 +22,8 @@ THE SOFTWARE. */ +import { checkPalIntegrity, withImpl } from '../../integrity-check'; + export function findCanvas (): { frame: HTMLDivElement, container: HTMLDivElement, canvas: HTMLCanvasElement } { const frame = document.querySelector('#GameDiv') as HTMLDivElement; const container = document.querySelector('#Cocos3dGameContainer') as HTMLDivElement; @@ -62,3 +64,5 @@ export function loadJsFile (path: string): Promise { document.head.appendChild(script); }); } + +checkPalIntegrity(withImpl()); diff --git a/pal/input/minigame/index.ts b/pal/input/minigame/index.ts index 4af5ab414e7..a30638e3682 100644 --- a/pal/input/minigame/index.ts +++ b/pal/input/minigame/index.ts @@ -22,6 +22,8 @@ THE SOFTWARE. */ +import { checkPalIntegrity, withImpl } from '../../integrity-check'; + export * from './accelerometer-input'; export * from './gamepad-input'; export * from './handle-input'; @@ -30,3 +32,5 @@ export * from './handheld-input'; export * from './keyboard-input'; export * from './mouse-input'; export * from './touch-input'; + +checkPalIntegrity(withImpl()); diff --git a/pal/input/native/index.ts b/pal/input/native/index.ts index 4af5ab414e7..a30638e3682 100644 --- a/pal/input/native/index.ts +++ b/pal/input/native/index.ts @@ -22,6 +22,8 @@ THE SOFTWARE. */ +import { checkPalIntegrity, withImpl } from '../../integrity-check'; + export * from './accelerometer-input'; export * from './gamepad-input'; export * from './handle-input'; @@ -30,3 +32,5 @@ export * from './handheld-input'; export * from './keyboard-input'; export * from './mouse-input'; export * from './touch-input'; + +checkPalIntegrity(withImpl()); diff --git a/pal/input/web/index.ts b/pal/input/web/index.ts index 4af5ab414e7..a30638e3682 100644 --- a/pal/input/web/index.ts +++ b/pal/input/web/index.ts @@ -22,6 +22,8 @@ THE SOFTWARE. */ +import { checkPalIntegrity, withImpl } from '../../integrity-check'; + export * from './accelerometer-input'; export * from './gamepad-input'; export * from './handle-input'; @@ -30,3 +32,5 @@ export * from './handheld-input'; export * from './keyboard-input'; export * from './mouse-input'; export * from './touch-input'; + +checkPalIntegrity(withImpl()); diff --git a/pal/integrity-check.ts b/pal/integrity-check.ts new file mode 100644 index 00000000000..44838582ab5 --- /dev/null +++ b/pal/integrity-check.ts @@ -0,0 +1,54 @@ +/* + Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +declare const guard: unique symbol; + +type Guard = typeof guard; + +/** + * Checks if a PAL implementation module is compatible with its target interface module. + * + * @example + * If you write the following in somewhere: + * + * ```ts + * checkPalIntegrity( + * withImpl()); + * ``` + * + * you will receive a compilation error + * if your implementation module is not fulfil the interface module. + * + * @note This function should be easily tree-shaken. + */ +export function checkPalIntegrity (impl: T & Guard) { +} + +/** + * Utility function, see example of `checkPalIntegrity()`. + * + */ +export function withImpl () { + return 0 as unknown as T & Guard; +} diff --git a/pal/minigame/alipay.ts b/pal/minigame/alipay.ts index 6f5c8e7b630..be1f535e267 100644 --- a/pal/minigame/alipay.ts +++ b/pal/minigame/alipay.ts @@ -23,6 +23,7 @@ */ import { IMiniGame } from 'pal/minigame'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; import { Orientation } from '../screen-adapter/enum-type'; import { cloneObject, createInnerAudioContextPolyfill } from '../utils'; @@ -158,3 +159,5 @@ minigame.getSafeArea = function (): SafeArea { // #endregion SafeArea export { minigame }; + +checkPalIntegrity(withImpl()); diff --git a/pal/minigame/baidu.ts b/pal/minigame/baidu.ts index 81955833f15..2f0b86ea669 100644 --- a/pal/minigame/baidu.ts +++ b/pal/minigame/baidu.ts @@ -23,6 +23,7 @@ */ import { IMiniGame } from 'pal/minigame'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; import { Orientation } from '../screen-adapter/enum-type'; import { cloneObject, createInnerAudioContextPolyfill } from '../utils'; @@ -111,3 +112,5 @@ minigame.getSafeArea = function (): SafeArea { // #endregion SafeArea export { minigame }; + +checkPalIntegrity(withImpl()); diff --git a/pal/minigame/bytedance.ts b/pal/minigame/bytedance.ts index b8148703f7c..e81d37e56c1 100644 --- a/pal/minigame/bytedance.ts +++ b/pal/minigame/bytedance.ts @@ -23,6 +23,7 @@ */ import { IMiniGame, SystemInfo } from 'pal/minigame'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; import { Orientation } from '../screen-adapter/enum-type'; import { cloneObject, createInnerAudioContextPolyfill } from '../utils'; @@ -125,3 +126,5 @@ minigame.getSafeArea = function (): SafeArea { // #endregion SafeArea export { minigame }; + +checkPalIntegrity(withImpl()); diff --git a/pal/minigame/non-minigame.ts b/pal/minigame/non-minigame.ts index 01053d21fc1..4e70986d6e9 100644 --- a/pal/minigame/non-minigame.ts +++ b/pal/minigame/non-minigame.ts @@ -22,5 +22,9 @@ THE SOFTWARE. */ +import { checkPalIntegrity, withImpl } from '../integrity-check'; + const minigame: any = {}; export { minigame }; + +checkPalIntegrity(withImpl()); diff --git a/pal/minigame/runtime.ts b/pal/minigame/runtime.ts index 3c2336b0c57..8dfad251c88 100644 --- a/pal/minigame/runtime.ts +++ b/pal/minigame/runtime.ts @@ -24,6 +24,7 @@ import { COCOSPLAY, HUAWEI, LINKSURE, OPPO, QTT, VIVO } from 'internal:constants'; import { SystemInfo, IMiniGame } from 'pal/minigame'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; import { Orientation } from '../screen-adapter/enum-type'; import { cloneObject, createInnerAudioContextPolyfill } from '../utils'; @@ -152,3 +153,5 @@ minigame.getSafeArea = function (): SafeArea { // #endregion SafeArea export { minigame }; + +checkPalIntegrity(withImpl()); diff --git a/pal/minigame/taobao.ts b/pal/minigame/taobao.ts index 4c8948a3079..8e5f9e18974 100644 --- a/pal/minigame/taobao.ts +++ b/pal/minigame/taobao.ts @@ -26,6 +26,7 @@ import { IMiniGame, SystemInfo } from 'pal/minigame'; import { Orientation } from '../screen-adapter/enum-type'; import { cloneObject, createInnerAudioContextPolyfill, versionCompare } from '../utils'; import { Language } from '../system-info/enum-type'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; //taobao IDE language ("Chinese") //taobao phone language (Andrond: "cn", iPad: 'zh_CN') @@ -217,3 +218,5 @@ function adapterGL (gl): void { } export { minigame }; + +checkPalIntegrity(withImpl()); diff --git a/pal/minigame/taobao_minigame.ts b/pal/minigame/taobao_minigame.ts index 7f52e5a88d4..5db86b6cfa9 100644 --- a/pal/minigame/taobao_minigame.ts +++ b/pal/minigame/taobao_minigame.ts @@ -26,6 +26,7 @@ import { IMiniGame, SystemInfo } from 'pal/minigame'; import { Orientation } from '../screen-adapter/enum-type'; import { cloneObject, createInnerAudioContextPolyfill, versionCompare } from '../utils'; import { Language } from '../system-info/enum-type'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; //taobao IDE language ("Chinese") //taobao phone language (Andrond: "cn", iPad: 'zh_CN') @@ -229,3 +230,5 @@ function adapterGL (gl): void { minigame.loadSubpackage = my.loadSubPackage.bind(my); export { minigame }; + +checkPalIntegrity(withImpl()); diff --git a/pal/minigame/wechat.ts b/pal/minigame/wechat.ts index 5049cf6163a..9a912da3bf8 100644 --- a/pal/minigame/wechat.ts +++ b/pal/minigame/wechat.ts @@ -23,6 +23,7 @@ */ import { IMiniGame, SystemInfo } from 'pal/minigame'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; import { Orientation } from '../screen-adapter/enum-type'; import { cloneObject, createInnerAudioContextPolyfill, versionCompare } from '../utils'; @@ -174,3 +175,5 @@ if (systemInfo.platform === 'windows' && versionCompare(systemInfo.SDKVersion, ' } export { minigame }; + +checkPalIntegrity(withImpl()); diff --git a/pal/minigame/wechat_mini_program.ts b/pal/minigame/wechat_mini_program.ts index 8abf6e2d0c4..61034a008d3 100644 --- a/pal/minigame/wechat_mini_program.ts +++ b/pal/minigame/wechat_mini_program.ts @@ -23,6 +23,7 @@ */ import { IMiniGame, SystemInfo } from 'pal/minigame'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; import { Orientation } from '../screen-adapter/enum-type'; import { cloneObject, createInnerAudioContextPolyfill, versionCompare } from '../utils'; @@ -197,3 +198,5 @@ gl.texSubImage2D = function (...args): void { }; export { minigame }; + +checkPalIntegrity(withImpl()); diff --git a/pal/minigame/xiaomi.ts b/pal/minigame/xiaomi.ts index 9a07a7a7b46..e182de7f828 100644 --- a/pal/minigame/xiaomi.ts +++ b/pal/minigame/xiaomi.ts @@ -23,6 +23,7 @@ */ import { IMiniGame } from 'pal/minigame'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; import { Orientation } from '../screen-adapter/enum-type'; import { cloneObject, createInnerAudioContextPolyfill } from '../utils'; @@ -150,3 +151,5 @@ minigame.getSafeArea = function (): SafeArea { // #endregion SafeArea export { minigame }; + +checkPalIntegrity(withImpl()); diff --git a/pal/pacer/pacer-minigame.ts b/pal/pacer/pacer-minigame.ts index 841e014ec3e..17b42c385fb 100644 --- a/pal/pacer/pacer-minigame.ts +++ b/pal/pacer/pacer-minigame.ts @@ -24,6 +24,7 @@ import { minigame } from 'pal/minigame'; import { assertIsTrue } from '../../cocos/core/data/utils/asserts'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; export class Pacer { private _rafHandle = 0; @@ -79,3 +80,5 @@ export class Pacer { this._isPlaying = false; } } + +checkPalIntegrity(withImpl()); diff --git a/pal/pacer/pacer-native.ts b/pal/pacer/pacer-native.ts index 15ef3c2b100..a4ae05b6148 100644 --- a/pal/pacer/pacer-native.ts +++ b/pal/pacer/pacer-native.ts @@ -23,6 +23,7 @@ */ import { assertIsTrue } from '../../cocos/core/data/utils/asserts'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; declare const jsb: any; export class Pacer { @@ -79,3 +80,5 @@ export class Pacer { this._isPlaying = false; } } + +checkPalIntegrity(withImpl()); diff --git a/pal/pacer/pacer-web.ts b/pal/pacer/pacer-web.ts index bf9aed7f704..f24212984a2 100644 --- a/pal/pacer/pacer-web.ts +++ b/pal/pacer/pacer-web.ts @@ -24,6 +24,7 @@ import { EDITOR } from 'internal:constants'; import { assertIsTrue } from '../../cocos/core/data/utils/asserts'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; const FRAME_RESET_TIME = 2000; @@ -144,3 +145,5 @@ export class Pacer { } } } + +checkPalIntegrity(withImpl()); diff --git a/pal/screen-adapter/minigame/screen-adapter.ts b/pal/screen-adapter/minigame/screen-adapter.ts index f95deecca7e..cc720af7d19 100644 --- a/pal/screen-adapter/minigame/screen-adapter.ts +++ b/pal/screen-adapter/minigame/screen-adapter.ts @@ -31,6 +31,7 @@ import { EventTarget } from '../../../cocos/core/event/event-target'; import { Size } from '../../../cocos/core/math'; import { OS } from '../../system-info/enum-type'; import { Orientation } from '../enum-type'; +import { checkPalIntegrity, withImpl } from '../../integrity-check'; declare const my: any; @@ -174,3 +175,5 @@ class ScreenAdapter extends EventTarget { } export const screenAdapter = new ScreenAdapter(); + +checkPalIntegrity(withImpl()); diff --git a/pal/screen-adapter/native/screen-adapter.ts b/pal/screen-adapter/native/screen-adapter.ts index 0e0056104e5..29cdec1adfa 100644 --- a/pal/screen-adapter/native/screen-adapter.ts +++ b/pal/screen-adapter/native/screen-adapter.ts @@ -25,6 +25,7 @@ import { EDITOR } from 'internal:constants'; import { EventTarget } from '../../../cocos/core/event/event-target'; import { Size } from '../../../cocos/core/math'; +import { checkPalIntegrity, withImpl } from '../../integrity-check'; import { Orientation } from '../enum-type'; export interface SafeAreaEdge { @@ -183,3 +184,5 @@ class ScreenAdapter extends EventTarget { } export const screenAdapter = new ScreenAdapter(); + +checkPalIntegrity(withImpl()); diff --git a/pal/screen-adapter/web/screen-adapter.ts b/pal/screen-adapter/web/screen-adapter.ts index 86590be5ddf..15ed7d9af15 100644 --- a/pal/screen-adapter/web/screen-adapter.ts +++ b/pal/screen-adapter/web/screen-adapter.ts @@ -30,6 +30,7 @@ import { EventTarget } from '../../../cocos/core/event/event-target'; import { Size } from '../../../cocos/core/math'; import { Orientation } from '../enum-type'; import legacyCC from '../../../predefine'; +import { checkPalIntegrity, withImpl } from '../../integrity-check'; interface ICachedStyle { width: string; @@ -562,3 +563,5 @@ class ScreenAdapter extends EventTarget { } export const screenAdapter = new ScreenAdapter(); + +checkPalIntegrity(withImpl()); diff --git a/pal/system-info/minigame/system-info.ts b/pal/system-info/minigame/system-info.ts index bb8fa7f2964..b00600cfa59 100644 --- a/pal/system-info/minigame/system-info.ts +++ b/pal/system-info/minigame/system-info.ts @@ -26,6 +26,7 @@ import { ALIPAY, BAIDU, BYTEDANCE, COCOSPLAY, HUAWEI, LINKSURE, OPPO, QTT, VIVO, import { minigame } from 'pal/minigame'; import { IFeatureMap } from 'pal/system-info'; import { EventTarget } from '../../../cocos/core/event'; +import { checkPalIntegrity, withImpl } from '../../integrity-check'; import { BrowserType, NetworkType, OS, Platform, Language, Feature } from '../enum-type'; // NOTE: register minigame platform here @@ -256,3 +257,5 @@ class SystemInfo extends EventTarget { } export const systemInfo = new SystemInfo(); + +checkPalIntegrity(withImpl()); diff --git a/pal/system-info/native/system-info.ts b/pal/system-info/native/system-info.ts index 4b2b4dfab2f..ab32f1c8824 100644 --- a/pal/system-info/native/system-info.ts +++ b/pal/system-info/native/system-info.ts @@ -24,6 +24,7 @@ import { OPEN_HARMONY } from 'internal:constants'; import { EventTarget } from '../../../cocos/core/event'; +import { checkPalIntegrity, withImpl } from '../../integrity-check'; import { BrowserType, NetworkType, OS, Platform, Language, Feature } from '../enum-type'; type IFeatureMap = { @@ -194,3 +195,5 @@ class SystemInfo extends EventTarget { } export const systemInfo = new SystemInfo(); + +checkPalIntegrity(withImpl()); diff --git a/pal/system-info/web/system-info.ts b/pal/system-info/web/system-info.ts index 044c99eafdf..14d6c3311dd 100644 --- a/pal/system-info/web/system-info.ts +++ b/pal/system-info/web/system-info.ts @@ -25,6 +25,7 @@ import { DEBUG, EDITOR, PREVIEW, TEST } from 'internal:constants'; import { IFeatureMap } from 'pal/system-info'; import { EventTarget } from '../../../cocos/core/event'; +import { checkPalIntegrity, withImpl } from '../../integrity-check'; import { BrowserType, NetworkType, OS, Platform, Language, Feature } from '../enum-type'; class SystemInfo extends EventTarget { @@ -383,3 +384,5 @@ class SystemInfo extends EventTarget { } export const systemInfo = new SystemInfo(); + +checkPalIntegrity(withImpl()); diff --git a/pal/wasm/wasm-minigame.ts b/pal/wasm/wasm-minigame.ts index 2d19a2beb6f..a7527f15235 100644 --- a/pal/wasm/wasm-minigame.ts +++ b/pal/wasm/wasm-minigame.ts @@ -25,6 +25,7 @@ import { HUAWEI, TAOBAO_MINIGAME, WASM_SUBPACKAGE, XIAOMI } from 'internal:constants'; import { minigame } from 'pal/minigame'; import { basename } from '../../cocos/core/utils/path'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; export function instantiateWasm (wasmUrl: string, importObject: WebAssembly.Imports): Promise { return getPlatformBinaryUrl(wasmUrl).then((url) => WebAssembly.instantiate(url, importObject)); @@ -108,3 +109,5 @@ function getPlatformBinaryUrl (binaryUrl: string): Promise { } }); } + +checkPalIntegrity(withImpl()); diff --git a/pal/wasm/wasm-native.ts b/pal/wasm/wasm-native.ts index 04b19d90a47..57a9d3ef8ad 100644 --- a/pal/wasm/wasm-native.ts +++ b/pal/wasm/wasm-native.ts @@ -23,6 +23,7 @@ */ import { EDITOR } from 'internal:constants'; import { native } from '../../cocos/native-binding/index'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; export function instantiateWasm (wasmUrl: string, importObject: WebAssembly.Imports): Promise { return fetchBuffer(wasmUrl).then((arrayBuffer) => WebAssembly.instantiate(arrayBuffer, importObject)); @@ -53,3 +54,5 @@ export function fetchBuffer (binaryUrl: string): Promise { export function ensureWasmModuleReady (): Promise { return Promise.resolve(); } + +checkPalIntegrity(withImpl()); diff --git a/pal/wasm/wasm-web.ts b/pal/wasm/wasm-web.ts index b61c0cf5893..6585310a34f 100644 --- a/pal/wasm/wasm-web.ts +++ b/pal/wasm/wasm-web.ts @@ -23,6 +23,7 @@ */ import { EDITOR, PREVIEW } from 'internal:constants'; +import { checkPalIntegrity, withImpl } from '../integrity-check'; declare const require: any; @@ -64,3 +65,5 @@ export function fetchBuffer (binaryUrl: string): Promise { export function ensureWasmModuleReady (): Promise { return Promise.resolve(); } + +checkPalIntegrity(withImpl()); From d31a3d6188d87379e14fcd3082f022358aeb987b Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 14 Jul 2023 09:58:27 +0800 Subject: [PATCH 2/5] fix #15704: [swig] The generated glue code is wrong if rename an inner class (#15710) --- native/external-config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native/external-config.json b/native/external-config.json index 0947b936cfc..f181e91c4c4 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.1-4" + "checkout": "v3.8.1-5" } } From e6dc2215c81f9e183c89f4f468c216eb2251ac75 Mon Sep 17 00:00:00 2001 From: Myway Date: Fri, 14 Jul 2023 10:28:37 +0800 Subject: [PATCH 3/5] change heightmap range (#15716) --- cocos/terrain/terrain-asset.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/cocos/terrain/terrain-asset.ts b/cocos/terrain/terrain-asset.ts index 0a1fa12f141..156360f280d 100644 --- a/cocos/terrain/terrain-asset.ts +++ b/cocos/terrain/terrain-asset.ts @@ -32,7 +32,8 @@ export const TERRAIN_BLOCK_TILE_COMPLEXITY = 32; export const TERRAIN_BLOCK_VERTEX_COMPLEXITY = 33; export const TERRAIN_BLOCK_VERTEX_SIZE = 8; // position + normal + uv export const TERRAIN_HEIGHT_BASE = 32768; -export const TERRAIN_HEIGHT_FACTORY = 1.0 / 512.0; +export const TERRAIN_HEIGHT_FACTORY = 1.0 / 128.0; +export const TERRAIN_HEIGHT_FACTORY_V7 = 1.0 / 512.0; export const TERRAIN_HEIGHT_FMIN = (-TERRAIN_HEIGHT_BASE) * TERRAIN_HEIGHT_FACTORY; export const TERRAIN_HEIGHT_FMAX = (65535 - TERRAIN_HEIGHT_BASE) * TERRAIN_HEIGHT_FACTORY; export const TERRAIN_NORTH_INDEX = 0; @@ -47,6 +48,7 @@ export const TERRAIN_DATA_VERSION4 = 0x01010004; export const TERRAIN_DATA_VERSION5 = 0x01010005; export const TERRAIN_DATA_VERSION6 = 0x01010006; export const TERRAIN_DATA_VERSION7 = 0x01010007; +export const TERRAIN_DATA_VERSION8 = 0x01010008; export const TERRAIN_DATA_VERSION_DEFAULT = 0x01010111; class TerrainBuffer { @@ -475,7 +477,8 @@ export class TerrainAsset extends Asset { && this._version !== TERRAIN_DATA_VERSION4 && this._version !== TERRAIN_DATA_VERSION5 && this._version !== TERRAIN_DATA_VERSION6 - && this._version !== TERRAIN_DATA_VERSION7) { + && this._version !== TERRAIN_DATA_VERSION7 + && this._version !== TERRAIN_DATA_VERSION8) { return false; } @@ -498,6 +501,14 @@ export class TerrainAsset extends Asset { this.heights[i] = stream.readInt16(); } + if (this._version < TERRAIN_DATA_VERSION8) { + for (let i = 0; i < this.heights.length; ++i) { + const h = (this._heights[i] - TERRAIN_HEIGHT_BASE) * TERRAIN_HEIGHT_FACTORY_V7; + const ch = TERRAIN_HEIGHT_BASE + h / TERRAIN_HEIGHT_FACTORY; + this.heights[i] = ch; + } + } + // normals if (this._version >= TERRAIN_DATA_VERSION6) { const normalBufferSize = stream.readInt(); @@ -560,7 +571,7 @@ export class TerrainAsset extends Asset { const stream = new TerrainBuffer(); // version - stream.writeInt32(TERRAIN_DATA_VERSION7); + stream.writeInt32(TERRAIN_DATA_VERSION8); // geometry info stream.writeDouble(this.tileSize); From f87d196f8dd8954c579951a7713380011c4b17a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leslie=20Leigh=20=28=E6=9D=8E=E7=9A=84=E5=BA=8F=29?= Date: Fri, 14 Jul 2023 10:33:16 +0800 Subject: [PATCH 4/5] Add Vec3.generateOrthogonal (#15705) --- cocos/core/math/vec3.ts | 49 ++++++++++++++------------ tests/core/math/vec3.test.ts | 66 ++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 22 deletions(-) diff --git a/cocos/core/math/vec3.ts b/cocos/core/math/vec3.ts index a82d05dfa0e..969ae9290a2 100644 --- a/cocos/core/math/vec3.ts +++ b/cocos/core/math/vec3.ts @@ -408,7 +408,7 @@ export class Vec3 extends ValueType { // If the directions are almost opposite, // every vector that orthonormal to the directions can be the rotation axis. const fromNormalized = Vec3.multiplyScalar(cacheV1, from, 1.0 / lenFrom); - const axis = chooseAnyPerpendicular(cacheV2, fromNormalized); + const axis = Vec3.generateOrthogonal(cacheV2, fromNormalized); const angle = Math.PI * t; rotateAxisAngle(cacheV3, fromNormalized, axis, angle); Vec3.multiplyScalar(out, cacheV3, lenLerped); @@ -801,6 +801,32 @@ export class Vec3 extends ValueType { return out; } + /** + * @zh 生成指定向量的一个正交单位向量。如果指定的向量 **精确地** 是零向量,则返回 **精确的** 零向量。 + * @en Generates an unit vector orthogonal to specified vector. + * If the specified vector is **strictly** zero vector, the result is **strict** zero vector. + * @param out @zh 生成的向量。@en The generated vector. + * @param n @zh 输入向量。该向量 **不必** 是标准化的。 @en The input vector. **Need not** to be normalized. + * @returns `out` + */ + public static generateOrthogonal (out: Out, n: Readonly): Out { + const { x, y, z } = n; + // 1. Drop the component with minimal magnitude. + // 2. Negate one of the remain components. + // 3. Swap the remain components. + const absX = Math.abs(x); + const absY = Math.abs(y); + const absZ = Math.abs(z); + if (absX < absY && absX < absZ) { + Vec3.set(out, 0.0, z, -y); + } else if (absY < absZ) { + Vec3.set(out, z, 0.0, -x); + } else { + Vec3.set(out, y, -x, 0.0); + } + return Vec3.normalize(out, out); + } + /** * @en x component. * @zh x 分量。 @@ -1185,27 +1211,6 @@ export function v3 (x?: number | Vec3, y?: number, z?: number): Vec3 { return new Vec3(x as any, y, z); } -/** - * Chooses an arbitrary unit vector that is perpendicular to input. - */ -function chooseAnyPerpendicular (out: Vec3, v: Readonly): Vec3 { - const { x, y, z } = v; - // 1. Drop the component with minimal magnitude. - // 2. Negate one of the remain components. - // 3. Swap the remain components. - const absX = Math.abs(x); - const absY = Math.abs(y); - const absZ = Math.abs(z); - if (absX < absY && absX < absZ) { - Vec3.set(out, 0.0, z, -y); - } else if (absY < absZ) { - Vec3.set(out, z, 0.0, -x); - } else { - Vec3.set(out, y, -x, 0.0); - } - return Vec3.normalize(out, out); -} - /** * Rotates `input` around `axis` for `angle` radians. */ diff --git a/tests/core/math/vec3.test.ts b/tests/core/math/vec3.test.ts index f28b16de61b..b7020520af6 100644 --- a/tests/core/math/vec3.test.ts +++ b/tests/core/math/vec3.test.ts @@ -3,6 +3,7 @@ import { Vec3 } from '../../../cocos/core/math/vec3'; import { Mat3 } from '../../../cocos/core/math/mat3'; import { Mat4 } from '../../../cocos/core/math/mat4'; import { Quat } from '../../../cocos/core/math/quat'; +import '../../utils/matchers/value-type-asymmetric-matchers'; describe('Test Vec3', () => { test('normalize', () => { @@ -169,4 +170,69 @@ describe('Test Vec3', () => { log('moveTowards: ', value0); expect(Vec3.equals(value0, expect0)).toBe(true); }); + + test(`generateOrthogonal`, () => { + // Zero input results zero result. + expect(gen(Vec3.ZERO)).toBeCloseToVec3(Vec3.ZERO); + + // Even the input is very close to zero, the result is not zero. + expect(gen(Vec3.add(new Vec3(), Vec3.ZERO, new Vec3(1e-10, 1e-20, 1e-30)))).toEqual({ + x: 9.999999999999999e-11, + y: -1, + z: 0, + }); + + // Especially observe the behavior on standard unit vectors. + { + for (const len of [1, -1, 0.3, -6.18]) { + if (len > 0) { + expect(gen(new Vec3(len, 0, 0))).toBeCloseToVec3(new Vec3(0, -1, 0)); + expect(gen(new Vec3(0, len, 0))).toBeCloseToVec3(new Vec3(1, 0, 0)); + expect(gen(new Vec3(0, 0, len))).toBeCloseToVec3(new Vec3(1, 0, 0)); + } else { + expect(gen(new Vec3(len, 0, 0))).toBeCloseToVec3(new Vec3(0, 1, 0)); + expect(gen(new Vec3(0, len, 0))).toBeCloseToVec3(new Vec3(-1, 0, 0)); + expect(gen(new Vec3(0, 0, len))).toBeCloseToVec3(new Vec3(-1, 0, 0)); + } + } + } + + expect(gen(new Vec3(1, -2, 3))).toEqual({ + x: 0, + y: 0.8320502943378437, + z: 0.5547001962252291, + }); + expect(gen(new Vec3(1, -1, -1))).toEqual({ + x: -0.7071067811865475, + y: -0.7071067811865475, + z: 0, + }); + + // The input vector need not to be normalized, + // but its effect should be equivalent to its normalized version. + ((v: Readonly) => void expect(gen(v)).toBeCloseToVec3(gen(Vec3.normalize(new Vec3(), v))))( + new Vec3(1, -2, 3)); + + function gen (input: Readonly) { + const result = new Vec3(Number.NaN, Number.NaN, Number.NaN); + + // The input should not be modified. + const inputFrozen = Object.freeze(Vec3.clone(input)); + + // The return value should be the `out` argument. + expect(Vec3.generateOrthogonal(result, inputFrozen)).toBe(result); + + if (Vec3.strictEquals(input, Vec3.ZERO)) { + // If the input is strictly 0, the result should be strictly 0. + expect(Vec3.strictEquals(result, Vec3.ZERO)).toBe(true); + } else { + // Otherwise, the result should be normalized. + expect(Vec3.lengthSqr(result)).toBeCloseTo(1, 5); + // The result should be orthogonal to input. + expect(Vec3.angle(input, result)).toBeCloseTo(Math.PI / 2, 5); + } + + return result; + }; + }); }); \ No newline at end of file From 7943b1b53af7c0a135a2dd658bb70e0118781c41 Mon Sep 17 00:00:00 2001 From: knox Date: Fri, 14 Jul 2023 13:35:42 +0800 Subject: [PATCH 5/5] refine code --- tests/core/math/vec3.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/core/math/vec3.test.ts b/tests/core/math/vec3.test.ts index 8eba1ebfd6b..f98a81a2e7b 100644 --- a/tests/core/math/vec3.test.ts +++ b/tests/core/math/vec3.test.ts @@ -195,7 +195,7 @@ describe('Test Vec3', () => { z: expect.toBeAround(1.7), })); } - }); + }); test(`generateOrthogonal`, () => { // Zero input results zero result. @@ -261,4 +261,4 @@ describe('Test Vec3', () => { return result; }; }); -}); \ No newline at end of file +});