123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /// <reference path="../../Functions.ts" />
- interface RulebookOptions<T> {
- noun? : T;
- }
- /**
- * Without the Runner, Rulebooks were not "thread-safe", so we need the runner.
- */
- class RulebookRunner<T> {
- public noun : T;
- private rulesToExecute : Array<Rule> = [];
- public rulebook : Rulebook<T>;
- public rule : Rule;
- private ruleRunner : number = -1;
- public constructor (rulebook : Rulebook<T>, noun : T) {
- this.rulebook = rulebook;
- this.noun = noun;
- }
- public addRulebooks (...rulebooks : Array<Rulebook<T>>) {
- rulebooks = arrayUniqueNewArray(rulebooks);
- rulebooks.forEach((rulebook) => {
- this.addRules(...rulebook.rules);
- });
- }
- public addRules (...rules) {
- if (this.ruleRunner < 0) {
- this.rulesToExecute.push(...rules);
- }
- }
- public skipRule (rule : Rule) {
- if (this.ruleRunner >= 0) {
- let index = this.rulesToExecute.indexOf(rule);
- if (index > this.ruleRunner) {
- this.rulesToExecute.splice(index, 1);
- console.debug("[Rulebook]" + this.rulebook.name + ", skipping Rule " + rule.name + " due to request.");
- } else {
- console.warn("[Rulebook]" + this.rulebook.name + ": uname to skip Rule" + rule.name + " due to it being too late to stop it.");
- }
- }
- }
- public async execute () {
- arrayUnique(this.rulesToExecute).sort(function (a: Rule, b: Rule) {
- return a.compareTo(b);
- });
- for (this.ruleRunner = 0; this.ruleRunner < this.rulesToExecute.length; this.ruleRunner++) {
- this.rule = this.rulesToExecute[this.ruleRunner];
- let result = await this.rule.execute(this);
- if (result != undefined) {
- return result;
- }
- }
- }
- }
- class Rulebook<T> {
- public rules : Array<Rule> = [];
- public name : string;
- private static indentantionSpaces = 2;
- public static rulebookStack : Array<any> = [];
- public static getStack () {
- let stack = [];
- Rulebook.rulebookStack.forEach((rl) => {
- if (rl instanceof Object && rl.name != undefined) {
- stack.push(rl.name);
- } else if (typeof rl == "string") {
- stack.push(rl);
- } else if (rl instanceof Object && rl.id != undefined) {
- stack.push(rl.id);
- } else {
- stack.push("Undefined");
- }
- });
- return stack;
- }
- public static getIndentation () {
- return " ".repeat(Rulebook.indentantionSpaces).repeat(Rulebook.rulebookStack.length);
- }
- public static increaseIndentation (rulebook : any) {
- Rulebook.rulebookStack.push(rulebook);
- }
- public static decreaseIndentation () {
- Rulebook.rulebookStack.pop();
- }
- public static isRunning (r : Rule | Rulebook<any>) {
- return Rulebook.rulebookStack.indexOf(r) != -1;
- }
- public isRunning () {
- return Rulebook.isRunning(this);
- }
- public constructor (name : string) {
- this.name = name;
- }
- public async execute (options : RulebookOptions<T>, ...rulebooks) : Promise<any>{
- options = options == undefined ? {} : options;
- let runner = new RulebookRunner<T>(this, options.noun); // duplicate array
- runner.addRulebooks(this, ...rulebooks);
- var names = [];
- for (let i = 0; i < rulebooks.length; i++) {
- if (rulebooks[i] === this) continue;
- names.push(rulebooks[i].name);
- }
- console.debug(Rulebook.getIndentation() + "[RULEBOOK] " + this.name + (names.length > 0 ? (" merged with " + names.join(", ")) : ""));
- Rulebook.increaseIndentation(this);
- let result = await runner.execute();
- Rulebook.decreaseIndentation();
- return result;
- }
- public createAndAddRule (r : RuleOptions<T>) : Rule {
- let rule = new Rule(r);
- this.addRule(rule);
- return rule;
- }
- public addRule (r : Rule) {
- this.rules.push(r);
- }
- public sortRules () {
- this.rules.sort(function (a : Rule, b : Rule) {
- return a.compareTo(b);
- });
- }
- }
|