Skip to content

Commit

Permalink
Status is now stored in Process, not returned
Browse files Browse the repository at this point in the history
  • Loading branch information
NQNStudios committed Jun 8, 2018
1 parent 0ed9d06 commit f3a7dd4
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 113 deletions.
22 changes: 11 additions & 11 deletions src/AddIdeaProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ import {BotProcess, BotStatus} from "./DaVinciBot";

export class AddIdeaProcess extends BotProcess
{
description(): string { return 'Add ideas to the idea pool.'; }

start(): BotStatus {
return BotStatus.HasOutput;
start(): void {
this.status = BotStatus.HasOutput;
}

getOutput(): [string, BotStatus] {
return [`Enter as many ideas as you want, followed by ENTER. To stop entering ideas, type 'quit'`, BotStatus.NeedsInput];
getOutput(): string {
this.status = BotStatus.NeedsInput;
return `Enter as many ideas as you want, followed by ENTER. To stop entering ideas, type 'quit'`;
}

handleInput(input: string): BotStatus {
handleInput(input: string): void {
if (input === 'quit') {
return BotStatus.Idle;
this.status = BotStatus.Idle;
}
else {
this.rootIdea.addChild(input);
this.status = BotStatus.NeedsInput;
}

this.rootIdea.addChild(input);
return BotStatus.NeedsInput;
}

finish(): void {
Expand Down
72 changes: 32 additions & 40 deletions src/DaVinciBot.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,47 @@
import { Idea } from "./Idea";

// Manages core state and functionality of the program.
// Manages a call stack of BotProcesses
export class DaVinciBot
{
private _rootIdea: Idea = new Idea();
private _processes: Array<BotProcess> = [];

private _processes: { [name: string]: BotProcess } = {};
private _currentProcess: string = '';

private _status: BotStatus = BotStatus.Idle;

get currentProcess(): string {
return this._currentProcess;
}

get processes(): { [name: string]: BotProcess } {
return this._processes;
get currentProcess(): BotProcess {
return this._processes[this._processes.length-1];
}

get status(): BotStatus {
return this._status;
}
if (this._processes.length == 0) {
return BotStatus.Idle;
}

addProcess(name: string, process: BotProcess) {
this._processes[name] = process.init(this._rootIdea);
return this.currentProcess.status;
}

startProcess(process: string) {
if (this._status !== BotStatus.Idle) {
throw new Error(`Tried to switch BotProcess without first finishing process ${this._currentProcess}`);
}

this._currentProcess = process;
this._status = this._processes[process].start();
startProcess(process: BotProcess) {
this._processes.push(process);
process.start();
}

getOutput(): string {
let outputTuple = this._processes[this._currentProcess].getOutput();

this._status = outputTuple[1];
return outputTuple[0];
let output = this.currentProcess.getOutput();
this.finishProcessIfIdle();
return output;
}

handleInput(input: string) {
this._status = this._processes[this._currentProcess].handleInput(input);
this.currentProcess.handleInput(input);
this.finishProcessIfIdle();
}

finishCurrentProcess() {
this._processes[this._currentProcess].finish();
this._status = BotStatus.Idle;
this.currentProcess.finish();
this._processes.pop();
}

finishProcessIfIdle() {
if (this.status === BotStatus.Idle) {
this.finishCurrentProcess();
}
}
}

Expand All @@ -62,18 +55,17 @@ export enum BotStatus
// TODO make this its own file
export class BotProcess
{
// TODO there could be real problems if a bot is started with null root idea
rootIdea: Idea = Idea.None;
description(): string { return ''; }
bot: DaVinciBot;
rootIdea: Idea;
status: BotStatus = BotStatus.Idle;

init(rootIdea: Idea): any {
constructor(bot: DaVinciBot, rootIdea: Idea) {
this.bot = bot;
this.rootIdea = rootIdea;
return this;
}
start(): BotStatus { throw new Error(`Custom BotProcess must define a start method: ${typeof this}`); }

getOutput(): [string, BotStatus] { return ['', BotStatus.Idle]; }
handleInput(input: string): BotStatus { return BotStatus.Idle; }

start(): void { }
getOutput(): string { return ''; }
handleInput(input: string): void { }
finish(): void { }
}
1 change: 0 additions & 1 deletion src/Idea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export class Idea
// need to be serialized because each deserialization will increment count
// in the constructor before restoring the Idea's original id
static TotalCount: number = 0;
static None: Idea = new Idea();

@JsonProperty("id", Number)
id: number;
Expand Down
44 changes: 21 additions & 23 deletions src/Serialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,47 @@ import {BotProcess, BotStatus} from "./DaVinciBot";

export class LoadFileProcess extends BotProcess
{
description(): string { return 'Load ideas from a file.'; }

start(): BotStatus {
return BotStatus.NeedsInput;
start(): void {
this.status = BotStatus.NeedsInput;
}

handleInput(input: string): BotStatus {
handleInput(input: string): void {
if (fs.existsSync(input)) {
return new LoadProcess().init(this.rootIdea).handleInput(fs.readFileSync(input, 'utf8'));
this.bot.startProcess(new LoadProcess(this.bot, this.rootIdea));
this.bot.handleInput(fs.readFileSync(input, 'utf8'));
}
else {
// TODO sometimes it might be error behavior if there's no file to
// load
return BotStatus.Idle;
}

this.status = BotStatus.Idle;
}
}

export class SaveFileProcess extends BotProcess
{
description(): string { return 'Save ideas to a file.'; }

start(): BotStatus {
return BotStatus.NeedsInput;
start(): void {
this.status = BotStatus.NeedsInput;
}

handleInput(input: string) {
let output = new SaveProcess().init(this.rootIdea).getOutput()[0];
fs.writeFileSync(input, output);
return BotStatus.Idle;
handleInput(input: string): void {
this.bot.startProcess(new SaveProcess(this.bot, this.rootIdea));
let output = this.bot.getOutput();
fs.writeFileSync(input, output, 'utf8');
this.status = BotStatus.Idle;
}
}

export class LoadProcess extends BotProcess
{
static converter = new JsonConvert();

description(): string { return 'Load ideas from a JSON string.'; }

start(): BotStatus {
return BotStatus.NeedsInput;
start() {
this.status = BotStatus.NeedsInput;
}

handleInput(input: string) {
handleInput(input: string): void {
let jsonStart = input.indexOf('{');
let countInput = input.substr(0, jsonStart);
let jsonInput = input.substr(jsonStart);
Expand All @@ -61,7 +58,7 @@ export class LoadProcess extends BotProcess
// Make sure TotalCount is properly set
Idea.TotalCount = parseInt(countInput);

return BotStatus.Idle;
this.status = BotStatus.Idle;
}

finish(): void {
Expand All @@ -78,7 +75,8 @@ export class SaveProcess extends BotProcess
return BotStatus.HasOutput;
}

getOutput(): [string, BotStatus] {
return [Idea.TotalCount + JSON.stringify(this.rootIdea), BotStatus.Idle];
getOutput(): string {
this.status = BotStatus.Idle;
return Idea.TotalCount + JSON.stringify(this.rootIdea);
}
}
55 changes: 17 additions & 38 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {Idea} from "./Idea";
import {DaVinciBot, BotStatus, BotProcess} from "./DaVinciBot";
import {AddIdeaProcess} from "./AddIdeaProcess";
import {LoadProcess, SaveProcess, LoadFileProcess, SaveFileProcess} from "./Serialization";
Expand All @@ -22,48 +23,26 @@ import * as path from "path";
/*console.log(jsonString);*/
/*console.log(deserializedIdea);*/

let rootIdea = new Idea();
let bot: DaVinciBot = new DaVinciBot();
bot.addProcess('AddIdeaProcess', new AddIdeaProcess());
bot.addProcess('SaveProcess', new SaveProcess());
bot.addProcess('LoadProcess', new LoadProcess());
bot.addProcess('SaveFileProcess', new SaveFileProcess());
bot.addProcess('LoadFileProcess', new LoadFileProcess());

// Automatically save and load state
bot.startProcess('LoadFileProcess');
// Automatically load state
bot.startProcess(new LoadFileProcess(bot, rootIdea));
bot.handleInput(path.join(os.homedir(), '.davinci.json'));

while (true) {
// TODO print all available processes
let availableProcesses = bot.processes;
for (let name in availableProcesses) {
let process = availableProcesses[name];
console.log(`${name} - ${process.description()}`);
bot.startProcess(new AddIdeaProcess(bot, rootIdea));

while (bot.status !== BotStatus.Idle) {
switch (bot.status) {
case BotStatus.HasOutput:
console.log(bot.getOutput());
break;
case BotStatus.NeedsInput:
let input = readlineSync.prompt();
bot.handleInput(input);
break;
}

console.log(`Choose which process to run, or type 'quit'`);
let process = readlineSync.prompt();

if (process === 'quit') {
break;
}

bot.startProcess(process);

while (bot.status !== BotStatus.Idle) {
switch (bot.status) {
case BotStatus.HasOutput:
console.log(bot.getOutput());
break;
case BotStatus.NeedsInput:
let input = readlineSync.prompt();
bot.handleInput(input);
break;
}
}

bot.finishCurrentProcess();
bot.startProcess('SaveFileProcess');
bot.handleInput(path.join(os.homedir(), '.davinci.json'));
}

bot.startProcess(new SaveFileProcess(bot, rootIdea));
bot.handleInput(path.join(os.homedir(), '.davinci.json'));

0 comments on commit f3a7dd4

Please sign in to comment.