Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize variable bind #45

Merged
merged 1 commit into from
Sep 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions cocos/core/animation/newgen-anim/__tmp__/graph-from-description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { PoseBlend1D } from '../pose-blend-1d';
import { PoseBlend2D } from '../pose-blend-2d';
import { GraphNode, PoseSubgraph, PoseTransition, VariableType } from '../pose-graph';
import { Pose } from '../pose';
import { BindingHost } from '../parametric';
import { Bindable } from '../parametric';
import { Value } from '../variable';
import { PoseNode } from '../pose-node';
import { BinaryCondition, TriggerCondition, UnaryCondition } from '../condition';
Expand Down Expand Up @@ -84,14 +84,14 @@ function createTransition (graph: PoseSubgraph, from: GraphNode, to: GraphNode,
case 'unary': {
const condition = new UnaryCondition();
condition.operator = UnaryCondition.Operator[conditionDesc.type];
condition.operand = createParametric(conditionDesc.operand, condition, 'operand');
createParametric(conditionDesc.operand, condition.operand);
return condition;
}
case 'binary': {
const condition = new BinaryCondition();
condition.operator = BinaryCondition.Operator[conditionDesc.type];
condition.lhs = createParametric(conditionDesc.lhs, condition, 'lhs');
condition.rhs = createParametric(conditionDesc.rhs, condition, 'rhs');
createParametric(conditionDesc.lhs, condition.lhs);
createParametric(conditionDesc.rhs, condition.rhs);
return condition;
}
case 'trigger': {
Expand Down Expand Up @@ -133,7 +133,7 @@ function createMotion (motionDesc: MotionDescription): Pose {
createMotion(childMotionDesc),
thresholds[iMotion],
] as [Pose, number]);
motion.param = createParametric(motionDesc.blender.value, motion, 'param');
createParametric(motionDesc.blender.value, motion.param);
return motion;
} else {
const algorithm = PoseBlend2D.Algorithm[motionDesc.blender.algorithm];
Expand All @@ -144,18 +144,18 @@ function createMotion (motionDesc: MotionDescription): Pose {
createMotion(childMotionDesc),
new Vec2(thresholds[iMotion].x, thresholds[iMotion].y),
] as [Pose, Vec2]);
motion.paramX = createParametric(motionDesc.blender.values[0], motion, 'paramX');
motion.paramY = createParametric(motionDesc.blender.values[1], motion, 'paramY');
createParametric(motionDesc.blender.values[0], motion.paramX);
createParametric(motionDesc.blender.values[1], motion.paramY);
return motion;
}
}

function createParametric<T extends string | number | boolean> (paramDesc: ParametricDescription<T>, host: BindingHost, bindingPointId: string) {
function createParametric<T extends string | number | boolean> (paramDesc: ParametricDescription<T>, bindable: Bindable<T>) {
if (typeof paramDesc === 'object') {
host.bindProperty(bindingPointId, paramDesc.name);
return paramDesc.value;
bindable.variable = paramDesc.name;
bindable.value = paramDesc.value;
} else {
return paramDesc;
bindable.value = paramDesc;
}
}

Expand Down
117 changes: 69 additions & 48 deletions cocos/core/animation/newgen-anim/condition.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { VariableNotDefinedError, VariableType } from '.';
import { ccclass, serializable } from '../../data/decorators';
import { CLASS_NAME_PREFIX_ANIM } from '../define';
import { createEval } from './create-eval';
import { VariableTypeMismatchedError } from './errors';
import { BindingHost, parametric } from './parametric';
import { BindableBoolean, BindableNumber, BindContext, bindOr } from './parametric';
import type { Value } from './variable';

export interface Condition extends BindingHost {
[createEval] (context: { getParam(host: BindingHost, name: string): unknown; }): ConditionEval;
export type ConditionEvalContext = BindContext;

export interface Condition {
[createEval] (context: BindContext): ConditionEval;
}

export interface ConditionEval {
Expand All @@ -26,31 +29,37 @@ enum BinaryOperator {
}

@ccclass(`${CLASS_NAME_PREFIX_ANIM}BinaryCondition`)
export class BinaryCondition extends BindingHost implements Condition {
export class BinaryCondition implements Condition {
public static readonly Operator = BinaryOperator;

@serializable
public operator!: BinaryOperator;

@serializable
@parametric<Value, [BinaryConditionEval]>({
notify: (value: Value, conditionEval: BinaryConditionEval) => conditionEval.setLhs(value),
})
public lhs!: Value;
public lhs: BindableNumber = new BindableNumber();

@serializable
@parametric<Value, [BinaryConditionEval]>({
notify: (value: Value, conditionEval: BinaryConditionEval) => conditionEval.setRhs(value),
})
public rhs: Value | undefined;

public [createEval] (context: { getParam(host: BindingHost, name: string): unknown; }) {
const { operator } = this;
const lhs = context.getParam(this, 'lhs') ?? this.lhs;
const rhs = context.getParam(this, 'rhs') ?? this.rhs;
validateConditionParamNumber(lhs, 'lhs');
validateConditionParamNumber(rhs, 'rhs');
return new BinaryConditionEval(operator, lhs, rhs as Value | undefined);
public rhs: BindableNumber = new BindableNumber();

public [createEval] (context: BindContext) {
const { operator, lhs, rhs } = this;
const evaluation = new BinaryConditionEval(operator, 0.0, 0.0);
const lhsValue = bindOr(
context,
lhs,
VariableType.NUMBER,
evaluation.setLhs,
evaluation,
);
const rhsValue = bindOr(
context,
rhs,
VariableType.NUMBER,
evaluation.setRhs,
evaluation,
);
evaluation.reset(lhsValue, rhsValue);
return evaluation;
}
}

Expand All @@ -69,6 +78,11 @@ class BinaryConditionEval implements ConditionEval {
this._eval();
}

public reset (lhs: Value, rhs?: Value) {
this._operands = [lhs, rhs];
this._eval();
}

public setLhs (value: Value) {
this._operands[0] = value;
this._eval();
Expand Down Expand Up @@ -119,23 +133,27 @@ enum UnaryOperator {
}

@ccclass(`${CLASS_NAME_PREFIX_ANIM}UnaryCondition`)
export class UnaryCondition extends BindingHost implements Condition {
export class UnaryCondition implements Condition {
public static readonly Operator = UnaryOperator;

@serializable
public operator!: UnaryOperator;

@serializable
@parametric<Value, [UnaryConditionEval]>({
notify: (value: Value, conditionEval: UnaryConditionEval) => conditionEval.setOperand(value),
})
public operand!: Value;

public [createEval] (context: { getParam(host: BindingHost, name: string): unknown; }) {
const { operator } = this;
const operand = context.getParam(this, 'operand') ?? this.operand;
validateConditionParamBoolean(operand, 'operand');
return new UnaryConditionEval(operator, operand);
public operand = new BindableBoolean();

public [createEval] (context: ConditionEvalContext) {
const { operator, operand } = this;
const evaluation = new UnaryConditionEval(operator, 0.0);
const value = bindOr(
context,
operand,
VariableType.BOOLEAN,
evaluation.setOperand,
evaluation,
);
evaluation.reset(value);
return evaluation;
}
}

Expand All @@ -154,6 +172,10 @@ class UnaryConditionEval implements ConditionEval {
this._eval();
}

public reset (value: Value) {
this.setOperand(value);
}

public setOperand (value: Value) {
this._operand = value;
this._eval();
Expand Down Expand Up @@ -181,19 +203,22 @@ class UnaryConditionEval implements ConditionEval {
}

@ccclass(`${CLASS_NAME_PREFIX_ANIM}TriggerCondition`)
export class TriggerCondition extends BindingHost implements Condition {
@parametric<Value, [TriggerConditionEval]>({
notify: (value: Value, conditionEval: TriggerConditionEval) => {
validateConditionParamBoolean(value, 'trigger');
conditionEval.trigger = value;
},
})
export class TriggerCondition implements Condition {
@serializable
public trigger!: string;

[createEval] (context: { getParam(host: BindingHost, name: string): unknown; }): ConditionEval {
const value = context.getParam(this, 'trigger') ?? false;
validateConditionParamBoolean(value, 'trigger');
return new TriggerConditionEval(value);
[createEval] (context: BindContext): ConditionEval {
const evaluation = new TriggerConditionEval(false);
const initialValue = context.bind(
this.trigger,
VariableType.TRIGGER,
evaluation.setTrigger,
evaluation,
);
if (typeof initialValue !== 'undefined') {
evaluation.setTrigger(initialValue);
}
return evaluation;
}
}

Expand All @@ -202,12 +227,8 @@ class TriggerConditionEval implements ConditionEval {
this._triggered = triggered;
}

get trigger () {
return this._triggered;
}

set trigger (value) {
this._triggered = value;
public setTrigger (trigger: boolean) {
this._triggered = trigger;
}

public eval (): boolean {
Expand Down
Loading