diff --git a/CHANGELOG.md b/CHANGELOG.md index a860150..064f3c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ - Use displayable actions to reorder layers - Better image preloading - Scene config inheritance -- Use scene name to jump between two cross-referenced scenes +- Use the scene name to jump between two cross-referenced scenes ### _Incompatible Changes_ @@ -24,7 +24,8 @@ - Disable image auto initialize using image.config - Quick image preloading only preloads images when needed - Use `scene.inherit` to inherit scene config -- Use scene name to jump between two cross-referenced scenes +- Use the scene name to jump between two cross-referenced scenes +- Better signatures for `Condition` ### Updated diff --git a/src/game/nlcore/action/actionable.ts b/src/game/nlcore/action/actionable.ts index ed92b5d..02456dc 100644 --- a/src/game/nlcore/action/actionable.ts +++ b/src/game/nlcore/action/actionable.ts @@ -15,7 +15,12 @@ export class Actionable< return null; } - /**@internal */ + /** + * @internal + * override this method can override the default behavior of chaining + * + * When converting a chain to actions, this method is called to convert the chain to actions + */ public fromChained(chained: Proxied>): LogicAction.Actions[] { return chained.getActions(); } diff --git a/src/game/nlcore/elements/condition.ts b/src/game/nlcore/elements/condition.ts index 5373d95..405e00c 100644 --- a/src/game/nlcore/elements/condition.ts +++ b/src/game/nlcore/elements/condition.ts @@ -1,4 +1,3 @@ -import {deepMerge} from "@lib/util/data"; import {ContentNode, RenderableNode} from "@core/action/tree/actionTree"; import {LogicAction} from "@core/action/logicAction"; import {Actionable} from "@core/action/actionable"; @@ -6,18 +5,17 @@ import {GameState} from "@player/gameState"; import {Chained, ChainedActions, Proxied} from "@core/action/chain"; import {ScriptCtx} from "@core/elements/script"; import {StaticScriptWarning} from "@core/common/Utils"; -import Actions = LogicAction.Actions; import {ConditionAction} from "@core/action/actions/conditionAction"; +import Actions = LogicAction.Actions; -/* eslint-disable @typescript-eslint/no-empty-object-type */ -export type ConditionConfig = {}; - -interface LambdaCtx extends ScriptCtx { -} - +type LambdaCtx = ScriptCtx; type LambdaHandler = (ctx: LambdaCtx) => T; export class Lambda { + public static isLambda(value: any): value is Lambda { + return value instanceof Lambda && "handler" in value; + } + handler: LambdaHandler; constructor(handler: LambdaHandler) { @@ -57,10 +55,7 @@ export type ConditionData = { } }; -export class Condition extends Actionable { - /**@internal */ - static defaultConfig: ConditionConfig = {}; - +export class Condition extends Actionable { /**@internal */ static getInitialState(): ConditionData { return { @@ -75,14 +70,15 @@ export class Condition extends Actionable { }; } + /** + * @chainable + */ public static If( condition: Lambda | LambdaHandler, action: ChainedActions ): Proxied> { - return new Condition().If(condition, action); + return new Condition().createIfCondition(condition, action); } - /**@internal */ - readonly config: ConditionConfig; /**@internal */ conditions: ConditionData = { If: { @@ -95,54 +91,25 @@ export class Condition extends Actionable { } }; - constructor(config: ConditionConfig = {}) { + /**@internal */ + private constructor() { super(); - this.config = deepMerge(Condition.defaultConfig, config); - } - - /** - * @chainable - */ - public If( - condition: Lambda | LambdaHandler, action: ChainedActions - ): Proxied> { - // when IF condition already set - if (this.conditions.If.condition) { - throw new StaticScriptWarning("IF condition already set\nYou are trying to set multiple IF conditions for the same condition"); - } - - // when ELSE-IF condition already set - if (this.conditions.ElseIf.length) { - throw new StaticScriptWarning("ELSE-IF condition already set\nYou are trying to set an IF condition after an ELSE-IF condition"); - } - - // when ELSE condition already set - if (this.conditions.Else.action) { - throw new StaticScriptWarning("ELSE condition already set\nYou are trying to set an IF condition after an ELSE condition"); - } - this.conditions.If.condition = condition instanceof Lambda ? condition : new Lambda(condition); - this.conditions.If.action = this.construct(Array.isArray(action) ? action : [action]); - return this.chain(); } /** * @chainable */ public ElseIf( - condition: Lambda | LambdaHandler, action: ChainedActions - ): Proxied> { - // when there is no IF condition - if (!this.conditions.If.condition) { - throw new StaticScriptWarning("IF condition not set\nYou are trying to set an ELSE-IF condition without an IF condition"); - } - + condition: Closed extends false ? (Lambda | LambdaHandler) : never, + action: Closed extends false ? ChainedActions : never + ): Closed extends false ? Proxied> : never { // when ELSE condition already set if (this.conditions.Else.action) { throw new StaticScriptWarning("ELSE condition already set\nYou are trying to set an ELSE-IF condition after an ELSE condition"); } this.conditions.ElseIf.push({ - condition: condition instanceof Lambda ? condition : new Lambda(condition), + condition: Lambda.isLambda(condition) ? condition : new Lambda(condition), action: this.construct(Array.isArray(action) ? action : [action]) }); return this.chain(); @@ -152,13 +119,8 @@ export class Condition extends Actionable { * @chainable */ public Else( - action: ChainedActions - ): Proxied> { - // when there is no IF condition - if (!this.conditions.If.condition) { - throw new StaticScriptWarning("IF condition not set\nYou are trying to set an ELSE condition without an IF condition"); - } - + action: Closed extends false ? ChainedActions : never + ): Closed extends false ? Proxied, Chained> : never { // when ELSE condition already set if (this.conditions.Else.action) { throw new StaticScriptWarning("ELSE condition already set\nYou are trying to set multiple ELSE conditions for the same condition"); @@ -225,4 +187,13 @@ export class Condition extends Actionable { (this.conditions.Else.action?.[0] || []) ]); } + + /**@internal */ + private createIfCondition( + condition: Lambda | LambdaHandler, action: ChainedActions + ): Proxied> { + this.conditions.If.condition = condition instanceof Lambda ? condition : new Lambda(condition); + this.conditions.If.action = this.construct(Array.isArray(action) ? action : [action]); + return this.chain(); + } }