Skip to content

Commit bdbf497

Browse files
authored
Merge pull request #103 from NarraLeaf/dev_nomen
narraleaf-react-0.8.4
2 parents 22d61a1 + 6204ce1 commit bdbf497

6 files changed

Lines changed: 74 additions & 15 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog
22

3+
## [0.8.4]
4+
5+
### _Feature_
6+
7+
- `Persistent.equals`, `Persistent.notEquals` now support lambda or lambda handler as argument
8+
- Added `ScriptCtx.$` to get the namespace
9+
- Added `Script.execute` to execute a script
10+
11+
### Fixed
12+
13+
- Script element is not executed correctly
14+
315
## [0.8.3]
416

517
### _Feature_

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "narraleaf-react",
3-
"version": "0.8.3",
3+
"version": "0.8.4",
44
"description": "A React visual novel player framework",
55
"main": "./dist/main.js",
66
"types": "./dist/index.d.ts",

src/game/nlcore/elements/built-in/Gallery.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ export class Gallery<Metadata extends Record<string, any>> extends Service<Galle
203203
game: ctx.game,
204204
liveGame: ctx.liveGame,
205205
storable: ctx.storable,
206+
$: ctx.$,
206207
};
207208
const parsedMetadata = typeof metadata === "function" ? metadata(context) : metadata;
208209
this.unlocked[name] = parsedMetadata;

src/game/nlcore/elements/condition.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ export class Lambda<T = any> {
1515
return value instanceof Lambda && "handler" in value;
1616
}
1717

18+
/**@internal */
19+
public static isLambdaHandler(value: any): value is LambdaHandler {
20+
return typeof value === "function";
21+
}
22+
1823
/**@internal */
1924
public static from<T>(obj: Lambda<T> | LambdaHandler<T>): Lambda<T> {
2025
return Lambda.isLambda(obj) ? obj : new Lambda(obj);
@@ -40,11 +45,14 @@ export class Lambda<T = any> {
4045

4146
/**@internal */
4247
getCtx({ gameState }: { gameState: GameState }): LambdaCtx {
48+
const liveGame = gameState.game.getLiveGame();
49+
const storable = liveGame.getStorable();
4350
return {
4451
gameState,
4552
game: gameState.game,
46-
liveGame: gameState.game.getLiveGame(),
47-
storable: gameState.game.getLiveGame().getStorable(),
53+
liveGame,
54+
storable,
55+
$: (namespace: string) => storable.getNamespace(namespace),
4856
};
4957
}
5058

src/game/nlcore/elements/persistent.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,23 +84,43 @@ export class Persistent<T extends PersistentContent>
8484

8585
/**
8686
* Determine whether the values are equal, can be used in {@link Condition}
87+
* @example
88+
* ```typescript
89+
* persis.equals("id", persis.get("player_id"));
90+
*
91+
* // or
92+
*
93+
* persis.equals("id", (ctx) => ctx.storable.getNamespace("player").get("player_id"));
94+
* ```
8795
*/
88-
public equals<K extends StringKeyOf<T>>(key: K, value: T[K] | ((value: T[K]) => T[K])): Lambda<boolean> {
89-
return new Lambda(({ storable }) => {
90-
const namespace = storable.getNamespace<T>(this.namespace);
91-
const evaluatedValue = typeof value === "function" ? value(namespace.get<K>(key)) : value;
96+
public equals<K extends StringKeyOf<T>>(key: K, value: T[K] | Lambda<T[K]> | LambdaHandler<T[K]>): Lambda<boolean> {
97+
return new Lambda((ctx) => {
98+
const namespace = ctx.storable.getNamespace<T>(this.namespace);
99+
const evaluatedValue = (
100+
Lambda.isLambda(value) || Lambda.isLambdaHandler(value)
101+
) ? Lambda.from(value).evaluate(ctx).value : value;
92102

93103
return namespace.equals<K>(key, evaluatedValue);
94104
});
95105
}
96106

97107
/**
98108
* Determine whether the values aren't equal, can be used in {@link Condition}
109+
* @example
110+
* ```typescript
111+
* persis.notEquals("id", persis.get("player_id"));
112+
*
113+
* // or
114+
*
115+
* persis.notEquals("id", (ctx) => ctx.storable.getNamespace("player").get("player_id"));
116+
* ```
99117
*/
100-
public notEquals<K extends StringKeyOf<T>>(key: K, value: T[K] | ((value: T[K]) => T[K])): Lambda<boolean> {
101-
return new Lambda(({ storable }) => {
102-
const namespace = storable.getNamespace<T>(this.namespace);
103-
const evaluatedValue = typeof value === "function" ? value(namespace.get<K>(key)) : value;
118+
public notEquals<K extends StringKeyOf<T>>(key: K, value: T[K] | Lambda<T[K]> | LambdaHandler<T[K]>): Lambda<boolean> {
119+
return new Lambda((ctx) => {
120+
const namespace = ctx.storable.getNamespace<T>(this.namespace);
121+
const evaluatedValue = (
122+
Lambda.isLambda(value) || Lambda.isLambdaHandler(value)
123+
) ? Lambda.from(value).evaluate(ctx).value : value;
104124

105125
return !namespace.equals<K>(key, evaluatedValue);
106126
});

src/game/nlcore/elements/script.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@ import {LogicAction} from "@core/action/logicAction";
44
import {Actionable} from "@core/action/actionable";
55
import {GameState} from "@player/gameState";
66
import {Chained, Proxied} from "@core/action/chain";
7-
import type {Storable} from "@core/elements/persistent/storable";
7+
import type {Namespace, Storable} from "@core/elements/persistent/storable";
88
import {ScriptAction} from "@core/action/actions/scriptAction";
99
import {LiveGame} from "@core/game/liveGame";
10+
import { NameSpaceContent } from "./persistent/type";
11+
12+
export type NamespaceGetter = <T extends NameSpaceContent<keyof T>>(namespace: string) => Namespace<T>;
1013

1114
export interface ScriptCtx {
1215
gameState: GameState;
1316
game: Game;
1417
liveGame: LiveGame;
1518
storable: Storable;
19+
$: NamespaceGetter;
1620
}
1721

1822
type ScriptRun = (ctx: ScriptCtx) => ScriptCleaner | void;
@@ -22,21 +26,35 @@ export type ScriptCleaner = () => void;
2226
export class Script extends Actionable<object> {
2327
/**@internal */
2428
static getCtx({gameState}: { gameState: GameState }): ScriptCtx {
29+
const liveGame = gameState.game.getLiveGame();
30+
const storable = liveGame.getStorable();
2531
return {
2632
gameState,
2733
game: gameState.game,
28-
liveGame: gameState.game.getLiveGame(),
29-
storable: gameState.game.getLiveGame().getStorable(),
34+
liveGame,
35+
storable,
36+
$: (namespace: string) => storable.getNamespace(namespace),
3037
};
3138
}
3239

40+
public static execute(handler: ScriptRun): Proxied<Script, Chained<LogicAction.Actions>> {
41+
return new Script(handler) as Proxied<Script, Chained<LogicAction.Actions>>;
42+
}
43+
3344
/**@internal */
3445
readonly handler: ScriptRun;
3546

3647
constructor(handler: ScriptRun) {
3748
super();
3849
this.handler = handler;
39-
return this.chain() satisfies Proxied<Script, Chained<LogicAction.Actions>>;
50+
51+
const chain = this.chain();
52+
const action = new ScriptAction(
53+
chain,
54+
ScriptAction.ActionTypes.action,
55+
new ContentNode<Script>().setContent(this)
56+
);
57+
return this.chain(action) satisfies Proxied<Script, Chained<LogicAction.Actions>>;
4058
}
4159

4260
/**@internal */

0 commit comments

Comments
 (0)