Skip to content

Commit

Permalink
fix: execution bugs #1
Browse files Browse the repository at this point in the history
Bugs fixing
  • Loading branch information
RigidStudios authored Mar 10, 2023
2 parents 80bfce4 + 9d4b7f6 commit d6773b5
Show file tree
Hide file tree
Showing 24 changed files with 415 additions and 445 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@
/include
/build
*.tsbuildinfo

# misc
.DS_Store
*.pem
275 changes: 146 additions & 129 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"test:watch": "rbxtsc -w --verbose --type game --rojo test.project.json",
"test:serve": "rojo serve ./test.project.json",
"test:rojo": "mkdir build & npm run test:build && rojo build -o ./build/test.rbxlx test.project.json",
"test:run": "npm run prepublish && npm run test:serve",
"test:run": "npm run test:build && npm run test:serve",
"prepublish": "npm run build && mkdir build && npm pack --pack-destination=build",
"test": "npm run test:run"
},
Expand Down Expand Up @@ -43,7 +43,7 @@
"typescript": "^4.9.5"
},
"dependencies": {
"@aethergames/mkscribe": "^0.1.0",
"@aethergames/mkscribe": "^0.3.0",
"@rbxts/services": "^1.5.1",
"@rbxts/testez": "^0.4.2-ts.0"
}
Expand Down
78 changes: 0 additions & 78 deletions src/ast-interpreter/index.ts

This file was deleted.

40 changes: 39 additions & 1 deletion src/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1 +1,39 @@
export = (): void => {}
/// <reference types="@rbxts/testez/globals" />

import { Scribe } from "."

export = (): void => {
describe("creating a new ScribeRuntime", () => {
const ScribeRuntime = Scribe.load(`
actor BEATRIZ "beatriz_id"
default objective hello "My objective!"
echo $test
interact BEATRIZ {
echo "Interacted with Beatriz!"
}
`, {
test: "Hello, world!"
})

it("should not throw when instantiating a new ScribeRuntime.", () => {
expect(() => Scribe.load("", {})).never.to.throw()
})

it("should not throw when retrieving an objective.", () => {
expect(() => {
ScribeRuntime.getCurrentObjective()
ScribeRuntime.getObjective("hello")
}).never.to.throw()
})

it("should interact correctly with the actor", () => {
expect(() => {
ScribeRuntime.interact("beatriz_id")
}).never.to.throw()
})
})
}
13 changes: 4 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import { Runtime } from "./ast-interpreter";
import { ExecutionType, ModuleSource, ScribeEnviroment, StringSource, StringValueSource } from "./types";
import { ScribeVM } from "./vm";
import { Runtime } from "./runtime";
import { ModuleSource, ScribeEnviroment, StringSource, StringValueSource } from "./types";

export namespace Scribe {
export function load<T extends ExecutionType>(
file: string | StringValue | ModuleScript,
env: ScribeEnviroment,
executionType: T,
): T extends "ast-interpreter" ? Runtime : ScribeVM {
export function load(file: string | StringValue | ModuleScript, env: ScribeEnviroment): Runtime {
const toRetrieveFrom = typeOf(file);
let source!: string;

Expand All @@ -29,6 +24,6 @@ export namespace Scribe {
}
}

return (executionType === "ast-interpreter" ? new Runtime(source, env) : new ScribeVM(source, env)) as never;
return new Runtime(source, env);
}
}
158 changes: 158 additions & 0 deletions src/runtime/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { MkScribe } from "@aethergames/mkscribe";
import { ScribeEnviroment } from "../types";
import {
DialogCallbackInput,
InteractionJob,
Objective,
ObjectiveChangeCallbackInput,
PipeToCallbackInput,
ScribeProgramProperties,
ScribeRuntimeImplementation,
} from "./types";
import { TokenLiteral } from "@aethergames/mkscribe/out/mkscribe/scanner/types";
import { ScribeVisitor, StatusInterpretationCode } from "./visitor";
import { RunService } from "@rbxts/services";

export class Runtime implements ScribeRuntimeImplementation {
public dialogCallback!: (input: DialogCallbackInput) => void;
public objectiveChangeCallback!: (input: ObjectiveChangeCallbackInput) => void;
public pipeTo!: (config: PipeToCallbackInput) => void;

private interpreter!: ScribeVisitor;

private interactions: Map<string, InteractionJob> = new Map();
private interactionsCooldown = 1 / 60;

constructor(private readonly source: string, private readonly env: ScribeEnviroment) {}

public start(): StatusInterpretationCode {
this.interpreter = new ScribeVisitor(
MkScribe.build(this.source),
{
onDialog: this.dialogCallback,
onStoreChange: this.pipeTo,
onObjectiveChange: this.objectiveChangeCallback,
},
this.env,
);

return this.interpreter.interpret();
}

public getObjective(objective: string): Objective | undefined {
return this.interpreter.records.objectives[objective];
}

public getCurrentObjective(): Objective | undefined {
const current = this.interpreter.records.objectives.current;

if (current !== undefined) {
return this.interpreter.records.objectives[current];
}
}

public getProperty(property: string): TokenLiteral {
return this.interpreter.programProperties[property];
}

public getProperties(): ScribeProgramProperties {
return this.interpreter.programProperties;
}

public incrementStore(valueTo: string, increment: number): void {
let head = this.interpreter.refs[valueTo];

while (head !== undefined) {
const { ref } = head;

if (typeOf(this.interpreter.records.stores[ref][0]) === "number") {
(this.interpreter.records.stores[ref][0] as number) += increment;
} else {
warn(`[Interpreter:incrementValue]: ${ref} isn't of type number, it can't be incremented.`);
}

head = head._next;
}
}

public setStore(valueTo: string, value: unknown): void {
let head = this.interpreter.refs[valueTo];

while (head !== undefined) {
this.interpreter.records.stores[head.ref][0] = value as TokenLiteral;

head = head._next;
}
}

public setCurrentObjective(objective: string): void {
this.interpreter.records.objectives.current = objective;
}

public play(id: string): void {
const scene = this.interpreter.records.scenes[id];

if (scene !== undefined) {
this.interpreter.resolve(this.interpreter.records.scenes[id]);
} else {
throw `Scene specified [${id}] isn't defined on the Scribe's program.`;
}
}

public async interact(id: string): Promise<void> {
if (this.interactions.has(id) === false) {
this.interactions.set(id, {
cleanup: undefined,
lastInteraction: 0,
queue: new Array(),
});
}

// eslint-disable-next-line prefer-const
let { cleanup, lastInteraction, queue } = this.interactions.get(id)!;

if (cleanup !== undefined) {
cleanup.Disconnect();
}

const interaction = this.interpreter.records.interactions[id];
if (os.clock() - lastInteraction > this.interactionsCooldown && queue.size() === 0) {
lastInteraction = os.clock();

return this.interpreter.resolve(interaction);
} else {
queue.push(interaction);

// eslint-disable-next-line no-constant-condition
while (true) {
if (os.clock() - lastInteraction > this.interactionsCooldown && queue[1] === interaction) {
this.clean(id);

return this.interpreter.resolve(interaction);
} else {
task.wait();
}
}
}
}

private clean(id: string): void {
const interactionJob = this.interactions.get(id);

if (interactionJob !== undefined) {
const { cleanup, lastInteraction, queue } = interactionJob;

if (cleanup !== undefined) {
interactionJob.cleanup = RunService.PostSimulation.Connect(() => {
if (os.clock() - lastInteraction > this.interactionsCooldown && queue.size() === 0) {
if (this.interactions.has(id)) {
this.interactions.delete(id);
}

cleanup.Disconnect();
}
});
}
}
}
}
27 changes: 26 additions & 1 deletion src/ast-interpreter/types.d.ts → src/runtime/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,20 @@ import { Statement } from "@aethergames/mkscribe";
import { TokenLiteral } from "@aethergames/mkscribe/out/mkscribe/scanner/types";
import { StatusInterpretationCode } from "./visitor";

declare type ScribeProperties = "title" | "description";
export declare type InteractionJob = {
cleanup: RBXScriptConnection | undefined;
lastInteraction: number;
queue: Array<Statement>;
};

export declare type ScribeProperties = "title" | "description";

export declare type Objective = {
id: number;
name: string;
desc: string;
active: boolean;
};

export declare type ScribeProgramProperties = Record<string | ScribeProperties, TokenLiteral>;

Expand All @@ -23,6 +36,11 @@ export declare type DialogCallbackInput = {
step: (id?: number) => void;
};

export declare type ObjectiveChangeCallbackInput = {
id: string;
description: string;
};

export declare type PipeToCallbackInput = {
identifier: string;
data: unknown;
Expand Down Expand Up @@ -52,6 +70,13 @@ export interface ScribeRuntimeImplementation {
*/
start(): StatusInterpretationCode;

getObjective(objective: string): Objective | undefined;

/**
*
*/
getCurrentObjective(): Objective | undefined;

/**
* Retrieve's a property's value.
*
Expand Down
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit d6773b5

Please sign in to comment.