diff --git a/.github/workflows/run_test_cases.yml b/.github/workflows/run_test_cases.yml index cadf5f73ad1..fbe998ac413 100644 --- a/.github/workflows/run_test_cases.yml +++ b/.github/workflows/run_test_cases.yml @@ -66,6 +66,8 @@ jobs: - name: Checkout rebase run: | + git config user.email + git config user.name git fetch origin git reset --hard git checkout origin/${{ steps.parse_pr.outputs.pr_base_ref }} diff --git a/cocos/core/algorithm/easing.ts b/cocos/core/algorithm/easing.ts index 84394a6ecbc..d425473fcf5 100644 --- a/cocos/core/algorithm/easing.ts +++ b/cocos/core/algorithm/easing.ts @@ -197,7 +197,7 @@ export function sineInOut (k: number): number { * @zh 启动慢,加速快。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 */ export function expoIn (k: number): number { - return k === 0 ? 0 : Math.pow(1024, k - 1); + return k === 0 ? 0 : 1024 ** (k - 1); } /** @@ -206,7 +206,7 @@ export function expoIn (k: number): number { * @zh 起动迅速,减速慢。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。 */ export function expoOut (k: number): number { - return k === 1 ? 1 : 1 - Math.pow(2, -10 * k); + return k === 1 ? 1 : 1 - (2 ** (-10 * k)); } /** @@ -223,9 +223,9 @@ export function expoInOut (k: number): number { } k *= 2; if (k < 1) { - return 0.5 * Math.pow(1024, k - 1); + return 0.5 * 1024 ** (k - 1); } - return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2); + return 0.5 * (-(2 ** (-10 * (k - 1))) + 2); } /** @@ -278,7 +278,7 @@ export function elasticIn (k: number): number { } else { s = p * Math.asin(1 / a) / (2 * Math.PI); } - return -(a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p)); + return -(a * 2 ** (10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p)); } /** @@ -301,7 +301,7 @@ export function elasticOut (k: number): number { } else { s = p * Math.asin(1 / a) / (2 * Math.PI); } - return (a * Math.pow(2, -10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1); + return (a * 2 ** (-10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1); } /** @@ -327,9 +327,9 @@ export function elasticInOut (k: number): number { k *= 2; if (k < 1) { return -0.5 - * (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p)); + * (a * 2 ** (10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p)); } - return a * Math.pow(2, -10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1; + return a * 2 ** (-10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1; } /** diff --git a/cocos/misc/renderer.ts b/cocos/misc/renderer.ts index f7ccdbd2ca4..0b7c60e4672 100644 --- a/cocos/misc/renderer.ts +++ b/cocos/misc/renderer.ts @@ -244,14 +244,17 @@ export class Renderer extends Component { } protected _onMaterialModified (index: number, material: Material | null): void { + /* empty */ } /** * @engineInternal */ public _onRebuildPSO (index: number, material: Material | null): void { + /* empty */ } protected _clearMaterials (): void { + /* empty */ } } diff --git a/cocos/primitive/torus.ts b/cocos/primitive/torus.ts index 45f9e939bc0..e4731a1cdc7 100644 --- a/cocos/primitive/torus.ts +++ b/cocos/primitive/torus.ts @@ -46,7 +46,19 @@ interface ITorusOptions extends IGeometryOptions { * @param tube @zh 管形大小。@en The radius of tube * @param opts @zh 参数选项。@en The optional creation parameters of the torus */ -export default function torus (radius = 0.4, tube = 0.1, opts: RecursivePartial = {}): { positions: number[]; normals: number[]; uvs: number[]; indices: number[]; minPos: Vec3; maxPos: Vec3; boundingRadius: number; } { +export default function torus ( + radius = 0.4, + tube = 0.1, + opts: RecursivePartial = {}, +): { + positions: number[]; + normals: number[]; + uvs: number[]; + indices: number[]; + minPos: Vec3; + maxPos: Vec3; + boundingRadius: number; +} { const radialSegments = opts.radialSegments || 32; const tubularSegments = opts.tubularSegments || 32; const arc = opts.arc || 2.0 * Math.PI; diff --git a/cocos/tween/actions/action-instant.ts b/cocos/tween/actions/action-instant.ts index 075283d9f7d..9966d2e6f01 100644 --- a/cocos/tween/actions/action-instant.ts +++ b/cocos/tween/actions/action-instant.ts @@ -24,10 +24,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* eslint-disable @typescript-eslint/ban-types */ - -import { FiniteTimeAction, Action } from './action'; +import { FiniteTimeAction } from './action'; import { Renderer } from '../../misc/renderer'; +import type { Node } from '../../scene-graph'; /** * @en Instant actions are immediate actions. They don't have a duration like the ActionInterval actions. @@ -35,16 +34,16 @@ import { Renderer } from '../../misc/renderer'; * @class ActionInstant * @extends FiniteTimeAction */ -export class ActionInstant extends FiniteTimeAction { +export abstract class ActionInstant extends FiniteTimeAction { isDone (): boolean { return true; } - step (dt: any): void { + step (_dt: number): void { this.update(1); } - update (dt: number): void { + update (_dt: number): void { // nothing } @@ -55,13 +54,11 @@ export class ActionInstant extends FiniteTimeAction { * - The reversed action will be x of 100 move to 0. * @returns {Action} */ - reverse (): Action { + reverse (): ActionInstant { return this.clone(); } - clone (): ActionInstant { - return new ActionInstant(); - } + abstract clone (): ActionInstant; } /* @@ -69,20 +66,21 @@ export class ActionInstant extends FiniteTimeAction { * @class Show * @extends ActionInstant */ -export class Show extends ActionInstant { - update (dt: any): void { - const _renderComps = this.target!.getComponentsInChildren(Renderer); +export class Show extends ActionInstant { + update (_dt: number): void { + const target = this.target as T; + const _renderComps = target.getComponentsInChildren(Renderer); for (let i = 0; i < _renderComps.length; ++i) { const render = _renderComps[i]; render.enabled = true; } } - reverse (): Hide { + reverse (): Hide { return new Hide(); } - clone (): Show { + clone (): Show { return new Show(); } } @@ -91,13 +89,13 @@ export class Show extends ActionInstant { * @en Show the Node. * @zh 立即显示。 * @method show - * @return {ActionInstant} + * @return {Show} * @example * // example * var showAction = show(); */ -export function show (): ActionInstant { - return new Show(); +export function show (): Show { + return new Show(); } /* @@ -105,21 +103,22 @@ export function show (): ActionInstant { * @class Hide * @extends ActionInstant */ -export class Hide extends ActionInstant { - update (dt: any): void { - const _renderComps = this.target!.getComponentsInChildren(Renderer); +export class Hide extends ActionInstant { + update (_dt: number): void { + const target = this.target as T; + const _renderComps = target.getComponentsInChildren(Renderer); for (let i = 0; i < _renderComps.length; ++i) { const render = _renderComps[i]; render.enabled = false; } } - reverse (): Show { - return new Show(); + reverse (): Show { + return new Show(); } - clone (): Hide { - return new Hide(); + clone (): Hide { + return new Hide(); } } @@ -127,13 +126,13 @@ export class Hide extends ActionInstant { * @en Hide the node. * @zh 立即隐藏。 * @method hide - * @return {ActionInstant} + * @return {Hide} * @example * // example * var hideAction = hide(); */ -export function hide (): ActionInstant { - return new Hide(); +export function hide (): Hide { + return new Hide(); } /* @@ -141,21 +140,22 @@ export function hide (): ActionInstant { * @class ToggleVisibility * @extends ActionInstant */ -export class ToggleVisibility extends ActionInstant { - update (dt: any): void { - const _renderComps = this.target!.getComponentsInChildren(Renderer); +export class ToggleVisibility extends ActionInstant { + update (_dt: number): void { + const target = this.target as T; + const _renderComps = target.getComponentsInChildren(Renderer); for (let i = 0; i < _renderComps.length; ++i) { const render = _renderComps[i]; render.enabled = !render.enabled; } } - reverse (): ToggleVisibility { - return new ToggleVisibility(); + reverse (): ToggleVisibility { + return new ToggleVisibility(); } - clone (): ToggleVisibility { - return new ToggleVisibility(); + clone (): ToggleVisibility { + return new ToggleVisibility(); } } @@ -163,13 +163,13 @@ export class ToggleVisibility extends ActionInstant { * @en Toggles the visibility of a node. * @zh 显隐状态切换。 * @method toggleVisibility - * @return {ActionInstant} + * @return {ToggleVisibility} * @example * // example * var toggleVisibilityAction = toggleVisibility(); */ -export function toggleVisibility (): ActionInstant { - return new ToggleVisibility(); +export function toggleVisibility (): ToggleVisibility { + return new ToggleVisibility(); } /* @@ -182,32 +182,33 @@ export function toggleVisibility (): ActionInstant { * // example * var removeSelfAction = new RemoveSelf(false); */ -export class RemoveSelf extends ActionInstant { +export class RemoveSelf extends ActionInstant { protected _isNeedCleanUp = true; constructor (isNeedCleanUp?: boolean) { super(); - isNeedCleanUp !== undefined && this.init(isNeedCleanUp); + if (isNeedCleanUp !== undefined) this.init(isNeedCleanUp); } - update (dt: any): void { - this.target!.removeFromParent(); + update (_dt: number): void { + const target = this.target as T; + target.removeFromParent(); if (this._isNeedCleanUp) { - this.target!.destroy(); + target.destroy(); } } - init (isNeedCleanUp: any): boolean { + init (isNeedCleanUp: boolean): boolean { this._isNeedCleanUp = isNeedCleanUp; return true; } - reverse (): RemoveSelf { - return new RemoveSelf(this._isNeedCleanUp); + reverse (): RemoveSelf { + return new RemoveSelf(this._isNeedCleanUp); } - clone (): RemoveSelf { - return new RemoveSelf(this._isNeedCleanUp); + clone (): RemoveSelf { + return new RemoveSelf(this._isNeedCleanUp); } } @@ -216,16 +217,18 @@ export class RemoveSelf extends ActionInstant { * @zh 从父节点移除自身。 * @method removeSelf * @param {Boolean} [isNeedCleanUp = true] - * @return {ActionInstant} + * @return {RemoveSelf} * * @example * // example * var removeSelfAction = removeSelf(); */ -export function removeSelf (isNeedCleanUp: boolean): ActionInstant { - return new RemoveSelf(isNeedCleanUp); +export function removeSelf (isNeedCleanUp: boolean): RemoveSelf { + return new RemoveSelf(isNeedCleanUp); } +export type TCallFuncCallback = (target?: TTarget, data?: TData) => void; + /* * Calls a 'callback'. * @class CallFunc @@ -241,36 +244,36 @@ export function removeSelf (isNeedCleanUp: boolean): ActionInstant { * // CallFunc with data * var finish = new CallFunc(this.removeFromParentAndCleanup, this, true); */ -export class CallFunc extends ActionInstant { - private _selectorTarget = null; - private _function: Function | null = null; - private _data = null; +export class CallFunc extends ActionInstant { + private _callbackThis: TCallbackThis | undefined = undefined; + private _callback: TCallFuncCallback | undefined = undefined; + private _data: TData | undefined = undefined; /* - * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Constructor function, override it to extend the construction behavior, remember to call "super()".
* Creates a CallFunc action with the callback. - * @param {function} selector - * @param {object} [selectorTarget=null] - * @param {*} [data=null] data for function, it accepts all data types. + * @param {TCallFuncCallback} callback The callback function + * @param {TCallbackThis} callbackThis The this object for callback + * @param {TData} data The custom data passed to the callback function, it accepts all data types. */ - constructor (selector?: Function, selectorTarget?: any, data?: any) { + constructor (selector?: TCallFuncCallback, callbackThis?: TCallbackThis, data?: TData) { super(); - this.initWithFunction(selector, selectorTarget, data); + this.initWithFunction(selector, callbackThis, data); } /* * Initializes the action with a function or function and its target - * @param {function} selector - * @param {object|Null} selectorTarget - * @param {*|Null} [data] data for function, it accepts all data types. + * @param {TCallFuncCallback} callback The callback function + * @param {TCallbackThis} callbackThis The this object for callback + * @param {TData} data The custom data passed to the callback function, it accepts all data types. * @return {Boolean} */ - initWithFunction (selector: any, selectorTarget?: any, data?: any): boolean { - if (selector) { - this._function = selector; + initWithFunction (callback?: TCallFuncCallback, callbackThis?: TCallbackThis, data?: TData): boolean { + if (callback) { + this._callback = callback; } - if (selectorTarget) { - this._selectorTarget = selectorTarget; + if (callbackThis) { + this._callbackThis = callbackThis; } if (data !== undefined) { this._data = data; @@ -282,12 +285,12 @@ export class CallFunc extends ActionInstant { * execute the function. */ execute (): void { - if (this._function) { - this._function.call(this._selectorTarget, this.target, this._data); + if (this._callback) { + this._callback.call(this._callbackThis, this.target as TTarget, this._data); } } - update (dt: any): void { + update (_dt: number): void { this.execute(); } @@ -295,24 +298,23 @@ export class CallFunc extends ActionInstant { * Get selectorTarget. * @return {object} */ - getTargetCallback (): null { - return this._selectorTarget; + getTargetCallback (): TCallbackThis | undefined { + return this._callbackThis; } /* * Set selectorTarget. * @param {object} sel */ - setTargetCallback (sel: any): void { - if (sel !== this._selectorTarget) { - if (this._selectorTarget) { this._selectorTarget = null; } - this._selectorTarget = sel; + setTargetCallback (sel: TCallbackThis): void { + if (sel !== this._callbackThis) { + this._callbackThis = sel; } } - clone (): CallFunc { - const action = new CallFunc(); - action.initWithFunction(this._function, this._selectorTarget, this._data); + clone (): CallFunc { + const action = new CallFunc(); + if (this._callback) action.initWithFunction(this._callback, this._callbackThis, this._data); return action; } } @@ -333,6 +335,10 @@ export class CallFunc extends ActionInstant { * // CallFunc with data * var finish = callFunc(this.removeFromParentAndCleanup, this._grossini, true); */ -export function callFunc (selector: Function, selectorTarget?: any, data?: any): ActionInstant { +export function callFunc ( + selector: TCallFuncCallback, + selectorTarget?: TSelectorTarget, + data?: TData, +): ActionInstant { return new CallFunc(selector, selectorTarget, data); } diff --git a/cocos/tween/actions/action-interval.ts b/cocos/tween/actions/action-interval.ts index 4ee34426d57..36ea1c40709 100644 --- a/cocos/tween/actions/action-interval.ts +++ b/cocos/tween/actions/action-interval.ts @@ -47,12 +47,10 @@ import { ActionInstant } from './action-instant'; * @extends FiniteTimeAction * @param {Number} d duration in seconds */ -export class ActionInterval extends FiniteTimeAction { +export abstract class ActionInterval extends FiniteTimeAction { protected MAX_VALUE = 2; protected _elapsed = 0; protected _firstTick = false; - // eslint-disable-next-line @typescript-eslint/ban-types - protected _easeList: Function[] = []; protected _speed = 1; protected _repeatForever = false; _repeatMethod = false; // Compatible with repeat class, Discard after can be deleted @@ -96,52 +94,11 @@ export class ActionInterval extends FiniteTimeAction { action._repeatForever = this._repeatForever; action._speed = this._speed; action._timesForRepeat = this._timesForRepeat; - action._easeList = this._easeList; action._speedMethod = this._speedMethod; action._repeatMethod = this._repeatMethod; } - _reverseEaseList (action: ActionInterval): void { - if (this._easeList) { - action._easeList = []; - for (let i = 0; i < this._easeList.length; i++) { - action._easeList.push(this._easeList[i]); - } - } - } - - clone (): ActionInterval { - const action = new ActionInterval(this._duration); - this._cloneDecoration(action); - return action; - } - - /** - * @en Implementation of ease motion. - * @zh 缓动运动。 - * @method easing - * @param {Object} easeObj - * @returns {ActionInterval} - * @example - * import { easeIn } from 'cc'; - * action.easing(easeIn(3.0)); - */ - easing (easeObj: any): ActionInterval { - if (this._easeList) this._easeList.length = 0; - else this._easeList = []; - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - for (let i = 0; i < arguments.length; i++) this._easeList.push(arguments[i]); - return this; - } - - _computeEaseTime (dt: any): any { - // var locList = this._easeList; - // if ((!locList) || (locList.length === 0)) - // return dt; - // for (var i = 0, n = locList.length; i < n; i++) - // dt = locList[i].easing(dt); - return dt; - } + abstract clone (): ActionInterval; step (dt: number): void { if (this._firstTick) { @@ -169,8 +126,8 @@ export class ActionInterval extends FiniteTimeAction { } } - startWithTarget (target: any): void { - Action.prototype.startWithTarget.call(this, target); + startWithTarget (target: T | null): void { + super.startWithTarget(target); this._elapsed = 0; this._firstTick = true; } @@ -185,7 +142,7 @@ export class ActionInterval extends FiniteTimeAction { * @warning It should be overridden in subclass. * @param {Number} amp */ - setAmplitudeRate (amp: any): void { + setAmplitudeRate (amp: number): void { // Abstract class needs implementation logID(1011); } @@ -287,13 +244,13 @@ export class ActionInterval extends FiniteTimeAction { * Runs actions sequentially, one after another. */ export class Sequence extends ActionInterval { - static _actionOneTwo = function (actionOne: ActionInterval, actionTwo: ActionInterval): Sequence { + static _actionOneTwo (actionOne: FiniteTimeAction, actionTwo: FiniteTimeAction): Sequence { const sequence = new Sequence(); sequence.initWithTwoActions(actionOne, actionTwo); return sequence; - }; + } - private _actions: ActionInterval[] = []; + private _actions: FiniteTimeAction[] = []; private _split = 0; private _last = 0; private _reversed = false; @@ -309,10 +266,11 @@ export class Sequence extends ActionInterval { * const seq = new Sequence(actArray); */ constructor (...actions: FiniteTimeAction[]); + constructor (actions: FiniteTimeAction[]); constructor (tempArray: any) { super(); - const paramArray = (tempArray instanceof Array) ? tempArray : arguments; + const paramArray = ((tempArray instanceof Array) ? tempArray : arguments) as FiniteTimeAction[]; if (paramArray.length === 1) { errorID(1019); return; @@ -321,11 +279,12 @@ export class Sequence extends ActionInterval { if ((last >= 0) && (paramArray[last] == null)) logID(1015); if (last >= 0) { - let prev = paramArray[0]; let action1: any; + let prev = paramArray[0]; + let action1: FiniteTimeAction; for (let i = 1; i < last; i++) { if (paramArray[i]) { action1 = prev; - prev = Sequence._actionOneTwo(action1 as ActionInterval, paramArray[i] as ActionInterval); + prev = Sequence._actionOneTwo(action1, paramArray[i]) as FiniteTimeAction; } } this.initWithTwoActions(prev, paramArray[last]); @@ -338,51 +297,50 @@ export class Sequence extends ActionInterval { * @param {FiniteTimeAction} actionTwo * @return {Boolean} */ - initWithTwoActions (actionOne: any, actionTwo: any): boolean { + initWithTwoActions (actionOne?: FiniteTimeAction, actionTwo?: FiniteTimeAction): boolean { if (!actionOne || !actionTwo) { errorID(1025); return false; } let durationOne = actionOne._duration; let durationTwo = actionTwo._duration; - durationOne *= actionOne._repeatMethod ? actionOne._timesForRepeat : 1; - durationTwo *= actionTwo._repeatMethod ? actionTwo._timesForRepeat : 1; + durationOne *= (actionOne as any)._repeatMethod ? actionOne._timesForRepeat : 1; + durationTwo *= (actionTwo as any)._repeatMethod ? actionTwo._timesForRepeat : 1; const d = durationOne + durationTwo; - this.initWithDuration(d as number); + this.initWithDuration(d); this._actions[0] = actionOne; this._actions[1] = actionTwo; return true; } - clone (): any { + clone (): Sequence { const action = new Sequence(); - this._cloneDecoration(action as ActionInterval); + this._cloneDecoration(action); action.initWithTwoActions(this._actions[0].clone(), this._actions[1].clone()); - return action as any; + return action; } - startWithTarget (target: any): void { - ActionInterval.prototype.startWithTarget.call(this, target); + startWithTarget (target: T | null): void { + super.startWithTarget(target); this._split = this._actions[0]._duration / this._duration; - this._split *= this._actions[0]._repeatMethod ? this._actions[0]._timesForRepeat : 1; + this._split *= (this._actions[0] as any)._repeatMethod ? this._actions[0]._timesForRepeat : 1; this._last = -1; } stop (): void { // Issue #1305 if (this._last !== -1) this._actions[this._last].stop(); - Action.prototype.stop.call(this); + super.stop(); } update (dt: number): void { - let new_t: number; let found = 0; + let new_t: number = 0; + let found = 0; const locSplit = this._split; const locActions = this._actions; const locLast = this._last; - let actionFound: ActionInterval; - dt = this._computeEaseTime(dt); if (dt < locSplit) { // action[0] new_t = (locSplit !== 0) ? dt / locSplit : 1; @@ -413,8 +371,7 @@ export class Sequence extends ActionInterval { } } - // eslint-disable-next-line prefer-const - actionFound = locActions[found]; + const actionFound = locActions[found]; // Last action found and it is done. if (locLast === found && actionFound.isDone()) return; @@ -426,12 +383,11 @@ export class Sequence extends ActionInterval { this._last = found; } - reverse (): any { - const action = Sequence._actionOneTwo(this._actions[1].reverse(), this._actions[0].reverse()); + reverse (): Sequence { + const action: Sequence = Sequence._actionOneTwo(this._actions[1].reverse(), this._actions[0].reverse()); this._cloneDecoration(action); - this._reverseEaseList(action); action._reversed = true; - return action as any; + return action; } } @@ -454,25 +410,28 @@ export class Sequence extends ActionInterval { * const seq = sequence(actArray); */ // todo: It should be use new -export function sequence (/* Multiple Arguments */tempArray: any): ActionInterval { - const paramArray = (tempArray instanceof Array) ? tempArray : arguments; +export function sequence (...actions: FiniteTimeAction[]): ActionInterval | null; +export function sequence (actions: FiniteTimeAction[]): ActionInterval | null; +export function sequence (tempArray: any): ActionInterval | null { + const paramArray = ((tempArray instanceof Array) ? tempArray : arguments) as FiniteTimeAction[]; + if (paramArray.length === 1) { - return paramArray[0] as ActionInterval; + return paramArray[0] as ActionInterval; //FIXME: Remove 'as' } const last = paramArray.length - 1; if ((last >= 0) && (paramArray[last] == null)) logID(1015); - let result: any = null; + let result: FiniteTimeAction | null = null; if (last >= 0) { result = paramArray[0]; for (let i = 1; i <= last; i++) { if (paramArray[i]) { - result = Sequence._actionOneTwo(result as ActionInterval, paramArray[i] as ActionInterval); + result = Sequence._actionOneTwo(result, paramArray[i]); } } } - return result as ActionInterval; + return result as ActionInterval; //FIXME: remove 'as' } /* @@ -493,9 +452,9 @@ export class Repeat extends ActionInterval { private _actionInstant = false; private _innerAction: FiniteTimeAction | null = null; - constructor (action?: any, times?: any) { + constructor (action?: FiniteTimeAction, times?: number) { super(); - times !== undefined && this.initWithAction(action as FiniteTimeAction, times as number); + this.initWithAction(action, times); } /* @@ -503,7 +462,10 @@ export class Repeat extends ActionInterval { * @param {Number} times * @return {Boolean} */ - initWithAction (action: FiniteTimeAction, times: number): boolean { + initWithAction (action?: FiniteTimeAction, times?: number): boolean { + if (!action || times === undefined) { + return false; + } const duration = action._duration * times; if (this.initWithDuration(duration)) { @@ -522,28 +484,32 @@ export class Repeat extends ActionInterval { clone (): Repeat { const action = new Repeat(); this._cloneDecoration(action); - action.initWithAction(this._innerAction!.clone(), this._times); + if (this._innerAction) { + action.initWithAction(this._innerAction.clone(), this._times); + } return action; } - startWithTarget (target: any): void { + startWithTarget (target: T | null): void { this._total = 0; - this._nextDt = this._innerAction!._duration / this._duration; - ActionInterval.prototype.startWithTarget.call(this, target); - this._innerAction!.startWithTarget(target); + this._nextDt = (this._innerAction ? this._innerAction._duration : 0) / this._duration; + super.startWithTarget(target); + if (this._innerAction) this._innerAction.startWithTarget(target); } stop (): void { - this._innerAction!.stop(); - Action.prototype.stop.call(this); + if (this._innerAction) this._innerAction.stop(); + super.stop(); } update (dt: number): void { - dt = this._computeEaseTime(dt); - const locInnerAction = this._innerAction!; + const locInnerAction = this._innerAction; const locDuration = this._duration; const locTimes = this._times; let locNextDt = this._nextDt; + if (!locInnerAction) { + return; + } if (dt >= locNextDt) { while (dt > locNextDt && this._total < locTimes) { @@ -580,18 +546,18 @@ export class Repeat extends ActionInterval { return this._total === this._times; } - reverse (): any { - const action = new Repeat(this._innerAction!.reverse(), this._times); + reverse (): Repeat { + const actionArg = this._innerAction ? this._innerAction.reverse() : undefined; + const action = new Repeat(actionArg, this._times); this._cloneDecoration(action); - this._reverseEaseList(action); - return action as any; + return action; } /* * Set inner Action. * @param {FiniteTimeAction} action */ - setInnerAction (action: any): void { + setInnerAction (action: FiniteTimeAction): void { if (this._innerAction !== action) { this._innerAction = action; } @@ -617,7 +583,7 @@ export class Repeat extends ActionInterval { * import { repeat, sequence } from 'cc'; * const rep = repeat(sequence(jump2, jump1), 5); */ -export function repeat (action: any, times: any): Action { +export function repeat (action: FiniteTimeAction, times: number): Action { return new Repeat(action, times); } @@ -637,7 +603,7 @@ export class RepeatForever extends ActionInterval { constructor (action?: ActionInterval) { super(); - action && this.initWithAction(action); + if (action) this.initWithAction(action); } /* @@ -657,18 +623,25 @@ export class RepeatForever extends ActionInterval { clone (): RepeatForever { const action = new RepeatForever(); this._cloneDecoration(action); - action.initWithAction(this._innerAction!.clone()); + if (this._innerAction) { + action.initWithAction(this._innerAction.clone()); + } return action; } - startWithTarget (target: any): void { - ActionInterval.prototype.startWithTarget.call(this, target); - this._innerAction!.startWithTarget(target); + startWithTarget (target: T | null): void { + super.startWithTarget(target); + if (this._innerAction) { + this._innerAction.startWithTarget(target); + } } - step (dt: any): void { - const locInnerAction = this._innerAction!; - locInnerAction.step(dt as number); + step (dt: number): void { + const locInnerAction = this._innerAction; + if (!locInnerAction) { + return; + } + locInnerAction.step(dt); if (locInnerAction.isDone()) { // var diff = locInnerAction.getElapsed() - locInnerAction._duration; locInnerAction.startWithTarget(this.target); @@ -683,18 +656,20 @@ export class RepeatForever extends ActionInterval { return false; } - reverse (): any { - const action = new RepeatForever(this._innerAction!.reverse()); - this._cloneDecoration(action); - this._reverseEaseList(action); - return action as any; + reverse (): RepeatForever { + if (this._innerAction) { + const action = new RepeatForever(this._innerAction.reverse()); + this._cloneDecoration(action); + return action; + } + return this; } /* * Set inner action. * @param {ActionInterval} action */ - setInnerAction (action: any): void { + setInnerAction (action: ActionInterval | null): void { if (this._innerAction !== action) { this._innerAction = action; } @@ -704,7 +679,7 @@ export class RepeatForever extends ActionInterval { * Get inner action. * @return {ActionInterval} */ - getInnerAction (): ActionInstant | null { + getInnerAction (): ActionInterval | null { return this._innerAction; } } @@ -729,19 +704,22 @@ export function repeatForever (action?: ActionInterval): ActionInterval { * @extends ActionInterval */ export class Spawn extends ActionInterval { - static _actionOneTwo = function (action1: any, action2: any): Spawn { - const pSpawn = new Spawn(); - pSpawn.initWithTwoActions(action1, action2); - return pSpawn; - }; + static _actionOneTwo (action1?: FiniteTimeAction, action2?: FiniteTimeAction): Spawn { + const spawn = new Spawn(); + spawn.initWithTwoActions(action1, action2); + return spawn; + } - private _one: ActionInterval | null = null; - private _two: ActionInterval | null = null; + private _one: FiniteTimeAction | null = null; + private _two: FiniteTimeAction | null = null; - constructor (tempArray?: any) { + constructor (...actions: FiniteTimeAction[]); + constructor (actions: FiniteTimeAction[]); + constructor (tempArray: any) { super(); - const paramArray = (tempArray instanceof Array) ? tempArray : arguments; + const paramArray = ((tempArray instanceof Array) ? tempArray : arguments) as FiniteTimeAction[]; + if (paramArray.length === 1) { errorID(1020); return; @@ -750,7 +728,8 @@ export class Spawn extends ActionInterval { if ((last >= 0) && (paramArray[last] == null)) logID(1015); if (last >= 0) { - let prev = paramArray[0]; let action1: any; + let prev: FiniteTimeAction = paramArray[0]; + let action1: FiniteTimeAction; for (let i = 1; i < last; i++) { if (paramArray[i]) { action1 = prev; @@ -761,12 +740,12 @@ export class Spawn extends ActionInterval { } } - /* initializes the Spawn action with the 2 actions to spawn - * @param {FiniteTimeAction} action1 - * @param {FiniteTimeAction} action2 - * @return {Boolean} + /* Initializes the Spawn action with the 2 actions to spawn + * @param {FiniteTimeAction} action1 The first action + * @param {FiniteTimeAction} action2 The second action + * @return {Boolean} Return true if the initialization succeeds, otherwise return false. */ - initWithTwoActions (action1: any, action2: any): boolean { + initWithTwoActions (action1?: FiniteTimeAction, action2?: FiniteTimeAction): boolean { if (!action1 || !action2) { errorID(1027); return false; @@ -777,14 +756,14 @@ export class Spawn extends ActionInterval { const d1 = action1._duration; const d2 = action2._duration; - if (this.initWithDuration(Math.max(d1 as number, d2 as number))) { + if (this.initWithDuration(Math.max(d1, d2))) { this._one = action1; this._two = action2; if (d1 > d2) { - this._two = Sequence._actionOneTwo(action2 as ActionInterval, delayTime(d1 - d2)); + this._two = Sequence._actionOneTwo(action2, delayTime(d1 - d2)); } else if (d1 < d2) { - this._one = Sequence._actionOneTwo(action1 as ActionInterval, delayTime(d2 - d1)); + this._one = Sequence._actionOneTwo(action1, delayTime(d2 - d1)); } ret = true; @@ -795,33 +774,36 @@ export class Spawn extends ActionInterval { clone (): Spawn { const action = new Spawn(); this._cloneDecoration(action); - action.initWithTwoActions(this._one!.clone(), this._two!.clone()); + if (this._one && this._two) { + action.initWithTwoActions(this._one.clone(), this._two.clone()); + } return action; } - startWithTarget (target: any): void { - ActionInterval.prototype.startWithTarget.call(this, target); - this._one!.startWithTarget(target); - this._two!.startWithTarget(target); + startWithTarget (target: T | null): void { + super.startWithTarget(target); + if (this._one) this._one.startWithTarget(target); + if (this._two) this._two.startWithTarget(target); } stop (): void { - this._one!.stop(); - this._two!.stop(); - Action.prototype.stop.call(this); + if (this._one) this._one.stop(); + if (this._two) this._two.stop(); + super.stop(); } - update (dt: any): void { - dt = this._computeEaseTime(dt); - if (this._one) this._one.update(dt as number); - if (this._two) this._two.update(dt as number); + update (dt: number): void { + if (this._one) this._one.update(dt); + if (this._two) this._two.update(dt); } - reverse (): any { - const action = Spawn._actionOneTwo(this._one!.reverse(), this._two!.reverse()); - this._cloneDecoration(action); - this._reverseEaseList(action); - return action as any; + reverse (): Spawn { + if (this._one && this._two) { + const action = Spawn._actionOneTwo(this._one.reverse(), this._two.reverse()); + this._cloneDecoration(action); + return action; + } + return this; } } @@ -837,20 +819,23 @@ export class Spawn extends ActionInterval { * const action = spawn(jumpBy(2, new Vec2(300, 0), 50, 4), rotateBy(2, 720)); * todo: It should be the direct use new */ -export function spawn (/* Multiple Arguments */tempArray: any): FiniteTimeAction { - const paramArray = (tempArray instanceof Array) ? tempArray : arguments; +export function spawn (...actions: FiniteTimeAction[]): FiniteTimeAction | null; +export function spawn (actions: FiniteTimeAction[]): FiniteTimeAction | null; +export function spawn (tempArray: any): FiniteTimeAction | null { + const paramArray = ((tempArray instanceof Array) ? tempArray : arguments) as FiniteTimeAction[]; if (paramArray.length === 1) { errorID(1020); - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return null as any; + return null; } if ((paramArray.length > 0) && (paramArray[paramArray.length - 1] == null)) logID(1015); let prev = paramArray[0]; + let current: FiniteTimeAction | null; for (let i = 1; i < paramArray.length; i++) { - if (paramArray[i] != null) prev = Spawn._actionOneTwo(prev, paramArray[i]); + current = paramArray[i]; + if (current != null) prev = Spawn._actionOneTwo(prev, current); } - return prev as FiniteTimeAction; + return prev; } /* Delays the action a certain amount of seconds @@ -858,14 +843,12 @@ export function spawn (/* Multiple Arguments */tempArray: any): FiniteTimeAction * @extends ActionInterval */ class DelayTime extends ActionInterval { - // eslint-disable-next-line @typescript-eslint/no-empty-function - update (dt: any): void { } + update (_dt: number): void { /* empty */ } - reverse (): any { + reverse (): DelayTime { const action = new DelayTime(this._duration); this._cloneDecoration(action); - this._reverseEaseList(action); - return action as any; + return action; } clone (): DelayTime { @@ -907,9 +890,9 @@ export function delayTime (d: number): ActionInterval { export class ReverseTime extends ActionInterval { private _other: ActionInterval | null = null; - constructor (action?: any) { + constructor (action?: ActionInterval) { super(); - action && this.initWithAction(action as ActionInterval); + if (action) this.initWithAction(action); } /* @@ -926,7 +909,7 @@ export class ReverseTime extends ActionInterval { return false; } - if (ActionInterval.prototype.initWithDuration.call(this, action._duration)) { + if (super.initWithDuration(action._duration)) { // Don't leak if action is reused this._other = action; return true; @@ -937,27 +920,31 @@ export class ReverseTime extends ActionInterval { clone (): ReverseTime { const action = new ReverseTime(); this._cloneDecoration(action); - action.initWithAction(this._other!.clone()); + if (this._other) { + action.initWithAction(this._other.clone()); + } return action; } - startWithTarget (target: any): void { - ActionInterval.prototype.startWithTarget.call(this, target); - this._other!.startWithTarget(target); + startWithTarget (target: T | null): void { + super.startWithTarget(target); + if (this._other) this._other.startWithTarget(target); } update (dt: number): void { - dt = this._computeEaseTime(dt); if (this._other) this._other.update(1 - dt); } - reverse (): any { - return this._other!.clone() as any; + reverse (): ActionInterval { + if (this._other) { + return this._other.clone(); + } + return this; } stop (): void { - this._other!.stop(); - Action.prototype.stop.call(this); + if (this._other) this._other.stop(); + super.stop(); } } @@ -971,6 +958,6 @@ export class ReverseTime extends ActionInterval { * import { reverseTime } from 'cc'; * const reverse = reverseTime(this); */ -export function reverseTime (action: any): ActionInterval { +export function reverseTime (action: ActionInterval): ActionInterval { return new ReverseTime(action); } diff --git a/cocos/tween/actions/action-manager.ts b/cocos/tween/actions/action-manager.ts index 738a6416bbc..ce73021d8c6 100644 --- a/cocos/tween/actions/action-manager.ts +++ b/cocos/tween/actions/action-manager.ts @@ -27,7 +27,6 @@ import { errorID, logID } from '../../core/platform/debug'; import { Action } from './action'; -import { Node } from '../../scene-graph'; import { legacyCC } from '../../core/global-exports'; import { isCCObject } from '../../core/data/object'; import type { ActionInterval } from './action-interval'; @@ -41,9 +40,9 @@ let ID_COUNTER = 0; */ class HashElement { actions: Action[] = []; - target: Record | null = null; // ccobject + target: unknown = null; actionIndex = 0; - currentAction: Action | null = null; // CCAction + currentAction: Action | null = null; paused = false; lock = false; } @@ -51,36 +50,24 @@ class HashElement { /** * @en * `ActionManager` is a class that can manage actions.
- * Normally you won't need to use this class directly. 99% of the cases you will use the CCNode interface, + * Normally you won't need to use this class directly. 99% of the cases you will use the `Tween` interface, * which uses this class's singleton object. - * But there are some cases where you might need to use this class.
- * Examples:
- * - When you want to run an action where the target is different from a CCNode.
* - When you want to pause / resume the actions
* @zh * `ActionManager` 是可以管理动作的单例类。
- * 通常你并不需要直接使用这个类,99%的情况您将使用 CCNode 的接口。
+ * 通常你并不需要直接使用这个类,99%的情况您将使用 `Tween` 的接口。
* 但也有一些情况下,您可能需要使用这个类。
* 例如: - * - 当你想要运行一个动作,但目标不是 CCNode 类型时。
* - 当你想要暂停/恢复动作时。
* @class ActionManager - * @example {@link cocos2d/core/CCActionManager/ActionManager.js} */ export class ActionManager { - private _hashTargets = new Map(); + private _hashTargets = new Map(); private _arrayTargets: HashElement[] = []; private _currentTarget!: HashElement; private _elementPool: HashElement[] = []; - private _searchElementByTarget (arr: HashElement[], target: Record): HashElement | null { - for (let k = 0; k < arr.length; k++) { - if (target === arr[k].target) return arr[k]; - } - return null; - } - - private _getElement (target: Record, paused: boolean): HashElement { + private _getElement (target: T, paused: boolean): HashElement { let element = this._elementPool.pop(); if (!element) { element = new HashElement(); @@ -90,7 +77,7 @@ export class ActionManager { return element; } - private _putElement (element: HashElement): void { + private _putElement (element: HashElement): void { element.actions.length = 0; element.actionIndex = 0; element.currentAction = null; @@ -118,12 +105,14 @@ export class ActionManager { * @param {object} target * @param {Boolean} paused */ - addAction (action: Action, target: Node, paused: boolean): void { + addAction (action: Action | null, target: T, paused: boolean): void { if (!action || !target) { errorID(1000); return; } + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error if (target.uuid == null) { (target as any).uuid = `_TWEEN_UUID_${ID_COUNTER++}`; } @@ -132,7 +121,7 @@ export class ActionManager { let element = this._hashTargets.get(target); // if doesn't exists, create a hashelement and push in mpTargets if (!element) { - element = this._getElement(target as any, paused); + element = this._getElement(target, paused); this._hashTargets.set(target, element); this._arrayTargets.push(element); } else if (!element.actions) { @@ -156,7 +145,7 @@ export class ActionManager { if (element) this._putElement(element); } this._arrayTargets.length = 0; - this._hashTargets = new Map(); + this._hashTargets = new Map(); } /** * @en @@ -166,9 +155,9 @@ export class ActionManager { * 移除指定对象上的所有动作。
* 属于该目标的所有的动作将被删除。 * @method removeAllActionsFromTarget - * @param {Node} target + * @param {T} target */ - removeAllActionsFromTarget (target: Node): void { + removeAllActionsFromTarget (target: T): void { // explicit null handling if (target == null) return; const element = this._hashTargets.get(target); @@ -183,7 +172,7 @@ export class ActionManager { * @method removeAction * @param {Action} action */ - removeAction (action: Action): void { + removeAction (action: Action | null): void { // explicit null handling if (action == null) return; const target = action.getOriginalTarget()!; @@ -204,7 +193,7 @@ export class ActionManager { /** * @internal */ - _removeActionByTag (tag: number, element: any, target?: Node): void { + _removeActionByTag (tag: number, element: HashElement, target?: T): void { for (let i = 0, l = element.actions.length; i < l; ++i) { const action = element.actions[i]; if (action && action.getTag() === tag) { @@ -220,7 +209,7 @@ export class ActionManager { /** * @internal */ - _removeAllActionsByTag (tag: number, element: any, target?: Node): void { + _removeAllActionsByTag (tag: number, element: HashElement, target?: T): void { for (let i = element.actions.length - 1; i >= 0; --i) { const action = element.actions[i]; if (action && action.getTag() === tag) { @@ -237,9 +226,9 @@ export class ActionManager { * @zh 删除指定对象下特定标签的一个动作,将删除首个匹配到的动作。 * @method removeActionByTag * @param {Number} tag - * @param {Node} target + * @param {T} target */ - removeActionByTag (tag: number, target?: Node): void { + removeActionByTag (tag: number, target?: T): void { if (tag === Action.TAG_INVALID) logID(1002); const hashTargets = this._hashTargets; @@ -260,9 +249,9 @@ export class ActionManager { * @zh 删除指定对象下特定标签的所有动作。 * @method removeAllActionsByTag * @param {Number} tag - * @param {Node} target + * @param {T} target */ - removeAllActionsByTag (tag: number, target?: Node): void { + removeAllActionsByTag (tag: number, target?: T): void { if (tag === Action.TAG_INVALID) logID(1002); const hashTargets = this._hashTargets; @@ -283,10 +272,10 @@ export class ActionManager { * @zh 通过目标对象和标签获取一个动作。 * @method getActionByTag * @param {Number} tag - * @param {Node} target + * @param {T} target * @return {Action|null} return the Action with the given tag on success */ - getActionByTag (tag: number, target: Node): Action | null { + getActionByTag (tag: number, target: T): Action | null { if (tag === Action.TAG_INVALID) logID(1004); const element = this._hashTargets.get(target); @@ -295,7 +284,7 @@ export class ActionManager { for (let i = 0; i < element.actions.length; ++i) { const action = element.actions[i]; if (action && action.getTag() === tag) { - return action as Action; + return action; } } } @@ -319,13 +308,13 @@ export class ActionManager { * - 如果你正在运行 2 个序列动作(Sequence)和 5 个普通动作,这个函数将返回 7。
* * @method getNumberOfRunningActionsInTarget - * @param {Node} target + * @param {T} target * @return {Number} */ - getNumberOfRunningActionsInTarget (target: Node): number { + getNumberOfRunningActionsInTarget (target: T): number { const element = this._hashTargets.get(target); if (element) { - return (element.actions) ? element.actions.length as number : 0; + return (element.actions) ? element.actions.length : 0; } return 0; @@ -334,9 +323,9 @@ export class ActionManager { * @en Pauses the target: all running actions and newly added actions will be paused. * @zh 暂停指定对象:所有正在运行的动作和新添加的动作都将会暂停。 * @method pauseTarget - * @param {Node} target + * @param {T} target */ - pauseTarget (target: Node): void { + pauseTarget (target: T): void { const element = this._hashTargets.get(target); if (element) element.paused = true; } @@ -344,9 +333,9 @@ export class ActionManager { * @en Resumes the target. All queued actions will be resumed. * @zh 让指定目标恢复运行。在执行序列中所有被暂停的动作将重新恢复运行。 * @method resumeTarget - * @param {Node} target + * @param {T} target */ - resumeTarget (target: Node): void { + resumeTarget (target: T): void { const element = this._hashTargets.get(target); if (element) element.paused = false; } @@ -357,14 +346,16 @@ export class ActionManager { * @method pauseAllRunningActions * @return {Array} a list of targets whose actions were paused. */ - pauseAllRunningActions (): Array { - const idsWithActions: Record[] = []; + pauseAllRunningActions (): unknown[] { + const idsWithActions: unknown[] = []; const locTargets = this._arrayTargets; for (let i = 0; i < locTargets.length; i++) { const element = locTargets[i]; if (element && !element.paused) { element.paused = true; - idsWithActions.push(element.target!); + if (element.target) { + idsWithActions.push(element.target); + } } } return idsWithActions; @@ -376,7 +367,7 @@ export class ActionManager { * @method resumeTargets * @param {Array} targetsToResume */ - resumeTargets (targetsToResume: Array): void { + resumeTargets (targetsToResume: Array): void { if (!targetsToResume) return; for (let i = 0; i < targetsToResume.length; i++) { @@ -390,7 +381,7 @@ export class ActionManager { * @method pauseTargets * @param {Array} targetsToPause */ - pauseTargets (targetsToPause: Array): void { + pauseTargets (targetsToPause: Array): void { if (!targetsToPause) return; for (let i = 0; i < targetsToPause.length; i++) { @@ -412,7 +403,7 @@ export class ActionManager { } // protected - private _removeActionAtIndex (index, element): void { + private _removeActionAtIndex (index: number, element: HashElement): void { const action = element.actions[index]; element.actions.splice(index, 1); @@ -425,7 +416,7 @@ export class ActionManager { } } - private _deleteHashElement (element): boolean { + private _deleteHashElement (element: HashElement): boolean { let ret = false; if (element && !element.lock) { if (this._hashTargets.get(element.target)) { @@ -459,7 +450,7 @@ export class ActionManager { const target = locCurrTarget.target; if (isCCObject(target) && !target.isValid) { - this.removeAllActionsFromTarget(target as unknown as Node); + this.removeAllActionsFromTarget(target); elt--; continue; } @@ -472,7 +463,9 @@ export class ActionManager { if (!locCurrTarget.currentAction) continue; // use for speed - locCurrTarget.currentAction.step(dt * (this._isActionInternal(locCurrTarget.currentAction) ? locCurrTarget.currentAction.getSpeed() : 1)); + locCurrTarget.currentAction.step( + dt * (this._isActionInterval(locCurrTarget.currentAction) ? locCurrTarget.currentAction.getSpeed() : 1), + ); if (locCurrTarget.currentAction && locCurrTarget.currentAction.isDone()) { locCurrTarget.currentAction.stop(); @@ -495,7 +488,7 @@ export class ActionManager { } } - private _isActionInternal (action: any): action is ActionInterval { + private _isActionInterval (action: any): action is ActionInterval { return typeof action._speedMethod !== 'undefined'; } } diff --git a/cocos/tween/actions/action.ts b/cocos/tween/actions/action.ts index 065ae1bd2f9..bc89171d00d 100644 --- a/cocos/tween/actions/action.ts +++ b/cocos/tween/actions/action.ts @@ -26,14 +26,13 @@ */ import { logID, errorID } from '../../core'; -import { Node } from '../../scene-graph'; /** * @en Base classAction for action classes. * @zh Action 类是所有动作类型的基类。 * @class Action */ -export class Action { +export abstract class Action { /** * @en Default Action tag. * @zh 默认动作标签。 @@ -43,8 +42,8 @@ export class Action { */ static TAG_INVALID = -1; - protected originalTarget: Node | null = null; - protected target: Node | null = null; + protected originalTarget: unknown = null; + protected target: unknown = null; protected tag = Action.TAG_INVALID; /** @@ -55,13 +54,7 @@ export class Action { * @method clone * @return {Action} */ - clone (): Action { - const action = new Action(); - action.originalTarget = null; - action.target = null; - action.tag = this.tag; - return action; - } + abstract clone (): Action; /** * @en @@ -75,7 +68,7 @@ export class Action { } // called before the action start. It will also set the target. - startWithTarget (target: any): void { + startWithTarget (target: T | null): void { this.originalTarget = target; this.target = target; } @@ -101,8 +94,8 @@ export class Action { * @method getTarget * @return {object} */ - getTarget (): Node | null { - return this.target; + getTarget (): T | null { + return this.target as T; } /** @@ -111,7 +104,7 @@ export class Action { * @method setTarget * @param {object} target */ - setTarget (target: Node): void { + setTarget (target: T): void { this.target = target; } @@ -121,14 +114,14 @@ export class Action { * @method getOriginalTarget * @return {object} */ - getOriginalTarget (): Node | null { - return this.originalTarget; + getOriginalTarget (): T | null { + return this.originalTarget as T; } // Set the original target, since target can be nil. // Is the target that were used to run the action. // Unless you are doing something complex, like `ActionManager`, you should NOT call this method. - setOriginalTarget (originalTarget: any): void { + setOriginalTarget (originalTarget: T): void { this.originalTarget = originalTarget; } @@ -163,20 +156,7 @@ export class Action { * @method reverse * @return {Action | null} */ - reverse (): Action | null { - logID(1008); - return null; - } - - // Currently JavaScript Bindigns (JSB), in some cases, needs to use retain and release. This is a bug in JSB, - // and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB. - // This is a hack, and should be removed once JSB fixes the retain/release bug. - retain (): void { } - - // Currently JavaScript Bindigns (JSB), in some cases, needs to use retain and release. This is a bug in JSB, - // and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB. - // This is a hack, and should be removed once JSB fixes the retain/release bug. - release (): void { } + abstract reverse (): Action | null; } /** @@ -191,7 +171,7 @@ export class Action { * @class FiniteTimeAction * @extends Action */ -export class FiniteTimeAction extends Action { +export abstract class FiniteTimeAction extends Action { _duration = 0; _timesForRepeat = 1; @@ -217,15 +197,15 @@ export class FiniteTimeAction extends Action { /** * @en - * to copy object with deep copy. - * returns a clone of action. - * @zh 返回一个克隆的动作。 + * To copy object with deep copy. + * returns a clone of FiniteTimeAction. + * @zh 返回一个克隆的有限时间动作。 * @method clone * @return {FiniteTimeAction} */ - clone (): FiniteTimeAction { - return new FiniteTimeAction(); - } + abstract clone (): FiniteTimeAction; + + abstract reverse (): FiniteTimeAction; } /* @@ -240,9 +220,9 @@ export class Speed extends Action { /** * @warning This action can't be `Sequence-able` because it is not an `IntervalAction` */ - constructor (action?: Action, speed = 1) { + constructor (action?: Action | null, speed = 1) { super(); - action && this.initWithAction(action, speed); + if (action) this.initWithAction(action, speed); } /* @@ -285,30 +265,35 @@ export class Speed extends Action { clone (): Speed { const action = new Speed(); - action.initWithAction(this._innerAction!.clone(), this._speed); + if (this._innerAction) { + action.initWithAction(this._innerAction.clone()!, this._speed); + } return action; } - startWithTarget (target: any): void { - Action.prototype.startWithTarget.call(this, target); - this._innerAction!.startWithTarget(target); + startWithTarget (target: T | null): void { + super.startWithTarget(target); + if (this._innerAction) this._innerAction.startWithTarget(target); } stop (): void { - this._innerAction!.stop(); - Action.prototype.stop.call(this); + if (this._innerAction) this._innerAction.stop(); + super.stop(); } step (dt: number): void { - this._innerAction!.step(dt * this._speed); + if (this._innerAction) this._innerAction.step(dt * this._speed); } isDone (): boolean { - return this._innerAction!.isDone(); + return this._innerAction ? this._innerAction.isDone() : false; } reverse (): Speed { - return new Speed(this._innerAction!.reverse()!, this._speed); + if (this._innerAction) { + return new Speed(this._innerAction.reverse(), this._speed); + } + return this; } /* @@ -316,7 +301,7 @@ export class Speed extends Action { * @method setInnerAction * @param {ActionInterval} action */ - setInnerAction (action: any): void { + setInnerAction (action: Action): void { if (this._innerAction !== action) { this._innerAction = action; } diff --git a/cocos/tween/export-api.ts b/cocos/tween/export-api.ts index 339043ac1f4..4c935360821 100644 --- a/cocos/tween/export-api.ts +++ b/cocos/tween/export-api.ts @@ -48,7 +48,7 @@ export type TweenEasing = * @zh * 缓动的可选属性的接口定义。 */ -export interface ITweenOption { +export interface ITweenOption { /** * @en @@ -58,6 +58,14 @@ export interface ITweenOption { */ easing?: TweenEasing | ((k: number) => number); + /** + * @en + * Whether to use relative value calculation method during easing process + * @zh + * 缓动过程中是否采用相对值计算的方法 + */ + relative?: boolean; + /** * @en * Interpolation function, you can pass in a custom function. @@ -72,7 +80,7 @@ export interface ITweenOption { * @zh * 回调,当缓动动作启动时触发。 */ - onStart?: (target?: object) => void; + onStart?: (target?: T) => void; /** * @en @@ -80,7 +88,7 @@ export interface ITweenOption { * @zh * 回调,当缓动动作更新时触发。 */ - onUpdate?: (target?: object, ratio?: number) => void; + onUpdate?: (target?: T, ratio?: number) => void; /** * @en @@ -88,5 +96,5 @@ export interface ITweenOption { * @zh * 回调,当缓动动作完成时触发。 */ - onComplete?: (target?: object) => void; + onComplete?: (target?: T) => void; } diff --git a/cocos/tween/set-action.ts b/cocos/tween/set-action.ts index 7ad3ddd513d..a4d158e3b56 100644 --- a/cocos/tween/set-action.ts +++ b/cocos/tween/set-action.ts @@ -30,11 +30,10 @@ export class SetAction extends ActionInstant { constructor (props?: any) { super(); this._props = {}; - // eslint-disable-next-line @typescript-eslint/no-unused-expressions - props !== undefined && this.init(props); + if (props) this.init(props); } - init (props): boolean { + init (props: any): boolean { for (const name in props) { this._props[name] = props[name]; } @@ -45,7 +44,7 @@ export class SetAction extends ActionInstant { const props = this._props; const target = this.target; for (const name in props) { - target![name] = props[name]; + (target as any)[name] = props[name]; } } diff --git a/cocos/tween/tween-action.ts b/cocos/tween/tween-action.ts index 4a5c80120d6..a75f73b39b2 100644 --- a/cocos/tween/tween-action.ts +++ b/cocos/tween/tween-action.ts @@ -24,9 +24,11 @@ import { warnID, warn, easing } from '../core'; import { ActionInterval } from './actions/action-interval'; -import { ITweenOption } from './export-api'; +import { ITweenOption, TweenEasing } from './export-api'; import { VERSION } from '../core/global-exports'; +type TypeEquality = { [K in keyof T]: K extends keyof U ? T[K] : never } extends T ? true : false; + /** adapter */ function TweenEasingAdapter (easingName: string): string { const initialChar = easingName.charAt(0); @@ -69,7 +71,7 @@ function TweenEasingAdapter (easingName: string): string { } /** checker */ -function TweenOptionChecker (opts: ITweenOption): void { +function TweenOptionChecker (opts: ITweenOption): void { const header = ' [Tween:] '; const message = ` option is not support in v + ${VERSION}`; const _opts = opts as unknown as any; @@ -90,12 +92,12 @@ function TweenOptionChecker (opts: ITweenOption): void { } } -export class TweenAction extends ActionInterval { - private _opts: any; +export class TweenAction extends ActionInterval { + private _opts: ITweenOption | undefined; private _props: any; private _originProps: any; - constructor (duration: number, props: any, opts?: ITweenOption) { + constructor (duration: number, props: any, opts?: ITweenOption) { super(); if (opts == null) { opts = Object.create(null); @@ -105,7 +107,7 @@ export class TweenAction extends ActionInterval { /** adapter */ if (opts.easing && typeof opts.easing === 'string') { - opts.easing = TweenEasingAdapter(opts.easing) as any; + opts.easing = TweenEasingAdapter(opts.easing) as TweenEasing; } // global easing or progress used for this action @@ -135,11 +137,12 @@ export class TweenAction extends ActionInterval { } if (value == null || typeof value === 'string') continue; // property may have custom easing or progress function - let customEasing: any; let progress: any; + let customEasing: any; + let progress: any; if (value.value !== undefined && (value.easing || value.progress)) { if (typeof value.easing === 'string') { customEasing = easing[value.easing]; - if (!customEasing) warnID(1031, value.easing); + if (!customEasing) warnID(1031, value.easing as string); } else { customEasing = value.easing; } @@ -158,16 +161,18 @@ export class TweenAction extends ActionInterval { this.initWithDuration(duration); } - clone (): TweenAction { + clone (): TweenAction { const action = new TweenAction(this._duration, this._originProps, this._opts); this._cloneDecoration(action); return action; } - startWithTarget (target: Record): void { - ActionInterval.prototype.startWithTarget.call(this, target); + startWithTarget (target: U | undefined): void { + const isEqual: TypeEquality = true; + super.startWithTarget(target); + if (!target || !isEqual) return; - const relative = !!this._opts.relative; + const relative = !!this._opts!.relative; const props = this._props; for (const property in props) { const _t: any = target[property]; @@ -178,7 +183,6 @@ export class TweenAction extends ActionInterval { if (typeof _t === 'number') { prop.start = _t; prop.current = _t; - // eslint-disable-next-line @typescript-eslint/restrict-plus-operands prop.end = relative ? _t + value : value; } else if (typeof _t === 'object') { if (prop.start == null) { @@ -186,28 +190,27 @@ export class TweenAction extends ActionInterval { } for (const k in value) { - // filtering if it not a number - // eslint-disable-next-line no-restricted-globals - if (isNaN(_t[k])) continue; + if (Number.isNaN(_t[k] as number)) continue; prop.start[k] = _t[k]; prop.current[k] = _t[k]; - // eslint-disable-next-line @typescript-eslint/restrict-plus-operands prop.end[k] = relative ? _t[k] + value[k] : value[k]; } } } - if (this._opts.onStart) { this._opts.onStart(this.target); } + if (this._opts!.onStart) { this._opts!.onStart(this.target as T); } } update (t: number): void { const target = this.target; if (!target) return; + if (!this._opts) return; + const props = this._props; const opts = this._opts; let easingTime = t; - if (opts.easing) easingTime = opts.easing(t); + if (typeof opts.easing === 'function') easingTime = opts.easing(t); const progress = opts.progress; for (const name in props) { @@ -234,8 +237,8 @@ export class TweenAction extends ActionInterval { target[name] = prop.current; } - if (opts.onUpdate) { opts.onUpdate(this.target, t); } - if (t === 1 && opts.onComplete) { opts.onComplete(this.target); } + if (opts.onUpdate) { opts.onUpdate(this.target as T, t); } + if (t === 1 && opts.onComplete) { opts.onComplete(this.target as T); } } progress (start: number, end: number, current: number, t: number): number { diff --git a/cocos/tween/tween-system.ts b/cocos/tween/tween-system.ts index cf374619583..e14a80bc49e 100644 --- a/cocos/tween/tween-system.ts +++ b/cocos/tween/tween-system.ts @@ -78,6 +78,6 @@ export class TweenSystem extends System { director.on(Director.EVENT_INIT, () => { const sys = new TweenSystem(); - (TweenSystem.instance as any) = sys; + (TweenSystem as any).instance = sys; director.registerSystem(TweenSystem.ID, sys, System.Priority.MEDIUM); }); diff --git a/cocos/tween/tween.ts b/cocos/tween/tween.ts index dfaca346899..da39f8a1855 100644 --- a/cocos/tween/tween.ts +++ b/cocos/tween/tween.ts @@ -25,12 +25,13 @@ import { TweenSystem } from './tween-system'; import { warn } from '../core'; import { ActionInterval, sequence, repeat, repeatForever, reverseTime, delayTime, spawn } from './actions/action-interval'; -import { removeSelf, show, hide, callFunc } from './actions/action-instant'; +import { removeSelf, show, hide, callFunc, TCallFuncCallback } from './actions/action-instant'; import { Action, FiniteTimeAction } from './actions/action'; import { ITweenOption } from './export-api'; import { TweenAction } from './tween-action'; import { SetAction } from './set-action'; import { legacyCC } from '../core/global-exports'; +import { Node } from '../scene-graph'; // https://medium.com/dailyjs/typescript-create-a-condition-based-subset-types-9d902cea5b8c type FlagExcludedType = { [Key in keyof Base]: Base[Key] extends Type ? never : Key }; @@ -39,6 +40,7 @@ type KeyPartial = { [P in K]?: T[P] }; type OmitType = KeyPartial>; // eslint-disable-next-line @typescript-eslint/ban-types type ConstructorType = OmitType; +type TweenWithNodeTargetOrUnknown = T extends Node ? Tween : unknown; /** * @en @@ -54,7 +56,7 @@ type ConstructorType = OmitType; * .by(1, {scale: new Vec3(-1, -1, -1), position: new Vec3(-5, -5, -5)}, {easing: 'sineOutIn'}) * .start() */ -export class Tween { +export class Tween { private _actions: Action[] = []; private _finalAction: Action | null = null; private _target: T | null = null; @@ -77,18 +79,24 @@ export class Tween { /** * @en - * Insert an action or tween to this sequence. + * Insert a tween to this sequence. * @zh * 插入一个 tween 到队列中。 * @method then * @param other @en The rear tween of this tween @zh 当前缓动的后置缓动 */ then (other: Tween): Tween { - if (other instanceof Action) { - this._actions.push(other.clone()); - } else { - this._actions.push(other._union()); - } + const u = other._union(); + if (u) this._actions.push(u); + return this; + } + + /** + * Insert an action to this sequence. + * @param other @en The rear action of this tween @zh 当前缓动的后置缓动 + */ + private insertAction (other: Action): Tween { + this._actions.push(other.clone()); return this; } @@ -100,9 +108,9 @@ export class Tween { * @method target * @param target @en The target of this tween @zh 当前缓动的目标对象 */ - target (target: T): Tween { - this._target = target; - return this; + target (target: U): Tween { + (this as unknown as Tween)._target = target; + return this as unknown as Tween; } /** @@ -120,8 +128,10 @@ export class Tween { TweenSystem.instance.ActionManager.removeAction(this._finalAction); } this._finalAction = this._union(); - this._finalAction.setTag(this._tag); - TweenSystem.instance.ActionManager.addAction(this._finalAction, this._target as any, false); + if (this._finalAction) { + this._finalAction.setTag(this._tag); + } + TweenSystem.instance.ActionManager.addAction(this._finalAction, this._target, false); return this; } @@ -146,9 +156,10 @@ export class Tween { * @method clone * @param target @en The target of clone tween @zh 克隆缓动的目标对象 */ - clone (target: T): Tween { + clone (target: U): Tween { const action = this._union(); - return tween(target).then(action.clone() as any); + const r = tween(target); + return action ? r.insertAction(action.clone()) : r; } /** @@ -160,7 +171,7 @@ export class Tween { union (): Tween { const action = this._union(); this._actions.length = 0; - this._actions.push(action); + if (action) this._actions.push(action); return this; } @@ -176,9 +187,9 @@ export class Tween { * @param opts.progress @en Interpolation function @zh 缓动的速度插值函数 * @param opts.easing @en Tween function or a lambda @zh 缓动的曲线函数或lambda表达式 */ - to (duration: number, props: ConstructorType, opts?: ITweenOption): Tween { - opts = opts || Object.create(null); - (opts as any).relative = false; + to (duration: number, props: ConstructorType, opts?: ITweenOption): Tween { + opts = opts || (Object.create(null) as ITweenOption); + opts.relative = false; const action = new TweenAction(duration, props, opts); this._actions.push(action); return this; @@ -197,9 +208,9 @@ export class Tween { * @param [opts.easing] * @return {Tween} */ - by (duration: number, props: ConstructorType, opts?: ITweenOption): Tween { - opts = opts || Object.create(null); - (opts as any).relative = true; + by (duration: number, props: ConstructorType, opts?: ITweenOption): Tween { + opts = opts || (Object.create(null) as ITweenOption); + opts.relative = true; const action = new TweenAction(duration, props, opts); this._actions.push(action); return this; @@ -242,11 +253,12 @@ export class Tween { * 添加一个回调 action。 * @method call * @param callback @en Callback function at the end of this tween @zh 当前缓动结束时的回调函数 + * @param callbackThis @en The this object in callback function @zh 回调函数中的 this 对象 + * @param data @en The Custom data that will be passed to callback @zh 要传递给回调函数的自定义数据 * @return {Tween} */ - // eslint-disable-next-line @typescript-eslint/ban-types - call (callback: Function): Tween { - const action = callFunc(callback); + call (callback: TCallFuncCallback, callbackThis?: TCallbackThis, data?: TData): Tween { + const action = callFunc(callback, callbackThis, data); this._actions.push(action); return this; } @@ -261,7 +273,7 @@ export class Tween { */ sequence (...args: Tween[]): Tween { const action = Tween._wrappedSequence(...args); - this._actions.push(action); + if (action) this._actions.push(action); return this; } @@ -275,7 +287,7 @@ export class Tween { */ parallel (...args: Tween[]): Tween { const action = Tween._wrappedParallel(...args); - this._actions.push(action); + if (action) this._actions.push(action); return this; } @@ -295,7 +307,7 @@ export class Tween { } const actions = this._actions; - let action: any; + let action: Action | undefined | null; if (embedTween instanceof Tween) { action = embedTween._union(); @@ -303,7 +315,7 @@ export class Tween { action = actions.pop(); } - actions.push(repeat(action, repeatTimes)); + if (action) actions.push(repeat(action as FiniteTimeAction, repeatTimes)); //FIXME: remove 'as' return this; } @@ -318,7 +330,7 @@ export class Tween { */ repeatForever (embedTween?: Tween): Tween { const actions = this._actions; - let action: any; + let action: Action | undefined | null; if (embedTween instanceof Tween) { action = embedTween._union(); @@ -326,7 +338,7 @@ export class Tween { action = actions.pop(); } - actions.push(repeatForever(action as ActionInterval)); + if (action) actions.push(repeatForever(action as ActionInterval)); //FIXME: remove 'as' return this; } @@ -341,7 +353,7 @@ export class Tween { */ reverseTime (embedTween?: Tween): Tween { const actions = this._actions; - let action: any; + let action: Action | undefined | null; if (embedTween instanceof Tween) { action = embedTween._union(); @@ -349,7 +361,7 @@ export class Tween { action = actions.pop(); } - actions.push(reverseTime(action as ActionInterval)); + if (action) actions.push(reverseTime(action as ActionInterval)); //FIXME: remove 'as' return this; } @@ -359,10 +371,13 @@ export class Tween { * @zh * 添加一个隐藏 action,只适用于 target 是节点类型的。 */ - hide (): Tween { - const action = hide(); - this._actions.push(action); - return this; + hide (): TweenWithNodeTargetOrUnknown { + const isNode = this._target instanceof Node; + if (isNode) { + const action = hide(); + this._actions.push(action); + } + return this as unknown as TweenWithNodeTargetOrUnknown; } /** @@ -371,10 +386,13 @@ export class Tween { * @zh * 添加一个显示 action,只适用于 target 是节点类型的。 */ - show (): Tween { - const action = show(); - this._actions.push(action); - return this; + show (): TweenWithNodeTargetOrUnknown { + const isNode = this._target instanceof Node; + if (isNode) { + const action = show(); + this._actions.push(action); + } + return this as unknown as TweenWithNodeTargetOrUnknown; } /** @@ -383,10 +401,13 @@ export class Tween { * @zh * 添加一个移除自己 action,只适用于 target 是节点类型的。 */ - removeSelf (): Tween { - const action = removeSelf(false); - this._actions.push(action); - return this; + removeSelf (): TweenWithNodeTargetOrUnknown { + const isNode = this._target instanceof Node; + if (isNode) { + const action = removeSelf(false); + this._actions.push(action); + } + return this as unknown as TweenWithNodeTargetOrUnknown; } /** @@ -395,10 +416,13 @@ export class Tween { * @zh * 添加一个移除并销毁自己 action,只适用于 target 是节点类型的。 */ - destroySelf (): Tween { - const action = removeSelf(true); - this._actions.push(action); - return this; + destroySelf (): TweenWithNodeTargetOrUnknown { + const isNode = this._target instanceof Node; + if (isNode) { + const action = removeSelf(true); + this._actions.push(action); + } + return this as unknown as TweenWithNodeTargetOrUnknown; } /** @@ -416,9 +440,8 @@ export class Tween { * @zh * 停止所有指定标签的缓动 */ - // eslint-disable-next-line @typescript-eslint/ban-types static stopAllByTag (tag: number, target?: object): void { - TweenSystem.instance.ActionManager.removeAllActionsByTag(tag, target as any); + TweenSystem.instance.ActionManager.removeAllActionsByTag(tag, target); } /** * @en @@ -426,18 +449,17 @@ export class Tween { * @zh * 停止所有指定对象的缓动 */ - // eslint-disable-next-line @typescript-eslint/ban-types static stopAllByTarget (target?: object): void { - TweenSystem.instance.ActionManager.removeAllActionsFromTarget(target as any); + TweenSystem.instance.ActionManager.removeAllActionsFromTarget(target); } - private _union (): Action { + private _union (): Action | null { const actions = this._actions; - let action: Action; + let action: Action | null; if (actions.length === 1) { action = actions[0]; } else { - action = sequence(actions); + action = sequence(actions as FiniteTimeAction[]); //FIXME: remove 'as' } return action; @@ -449,30 +471,30 @@ export class Tween { private static readonly _tmp_args: Tween[] | Action[] = []; - private static _wrappedSequence (...args: Action[] | Tween[]): ActionInterval { + private static _wrappedSequence (...args: Tween[]): FiniteTimeAction | null { const tmp_args = Tween._tmp_args; tmp_args.length = 0; for (let l = args.length, i = 0; i < l; i++) { const arg = tmp_args[i] = args[i]; if (arg instanceof Tween) { - tmp_args[i] = arg._union(); + tmp_args[i] = arg._union() as Action; //FIXME: Remove 'as' } } - return sequence.apply(sequence, tmp_args as any); + return sequence(tmp_args as FiniteTimeAction[]); } - private static _wrappedParallel (...args: Action[] | Tween[]): FiniteTimeAction { + private static _wrappedParallel (...args: Tween[]): FiniteTimeAction | null { const tmp_args = Tween._tmp_args; tmp_args.length = 0; for (let l = args.length, i = 0; i < l; i++) { const arg = tmp_args[i] = args[i]; if (arg instanceof Tween) { - tmp_args[i] = arg._union(); + tmp_args[i] = arg._union() as Action; //FIXME: Remove 'as' } } - return spawn.apply(spawn, tmp_args as any); + return spawn(tmp_args as FiniteTimeAction[]); } } legacyCC.Tween = Tween; @@ -491,7 +513,7 @@ legacyCC.Tween = Tween; * .by(1, {scale: new Vec3(-1, -1, -1)}, {easing: 'sineOutIn'}) * .start() */ -export function tween (target?: T): Tween { +export function tween (target?: T): Tween { return new Tween(target); } legacyCC.tween = tween; @@ -503,7 +525,7 @@ legacyCC.tween = tween; * tweenUtil 是一个工具函数,帮助实例化 Tween 实例。 * @deprecated please use `tween` instead. */ -export function tweenUtil (target?: T): Tween { +export function tweenUtil (target?: T): Tween { warn('tweenUtil\' is deprecated, please use \'tween\' instead '); return new Tween(target); } diff --git a/pal/integrity-check.ts b/pal/integrity-check.ts index 44838582ab5..8e4597c1956 100644 --- a/pal/integrity-check.ts +++ b/pal/integrity-check.ts @@ -42,13 +42,14 @@ type Guard = typeof guard; * * @note This function should be easily tree-shaken. */ -export function checkPalIntegrity (impl: T & Guard) { +export function checkPalIntegrity (impl: T & Guard): void { + /* empty */ } /** * Utility function, see example of `checkPalIntegrity()`. * */ -export function withImpl () { +export function withImpl (): T & Guard { return 0 as unknown as T & Guard; }