From 2cc212f21037e3bc12209dafd34231d0d94629d5 Mon Sep 17 00:00:00 2001 From: Phil Kunz Date: Mon, 23 Sep 2019 18:06:43 +0200 Subject: [PATCH] fix(core): update --- test/test.7.taskloop.ts | 6 +- ts/taskbuffer.classes.bufferrunner.ts | 42 +++++++ ts/taskbuffer.classes.cyclecounter.ts | 36 ++++++ ts/taskbuffer.classes.helpers.ts | 161 -------------------------- ts/taskbuffer.classes.task.ts | 151 +++++++++++++++++++++--- 5 files changed, 214 insertions(+), 182 deletions(-) create mode 100644 ts/taskbuffer.classes.bufferrunner.ts create mode 100644 ts/taskbuffer.classes.cyclecounter.ts diff --git a/test/test.7.taskloop.ts b/test/test.7.taskloop.ts index 233fb85..25d1472 100644 --- a/test/test.7.taskloop.ts +++ b/test/test.7.taskloop.ts @@ -37,12 +37,14 @@ tap.test('should create tasks', async () => { console.log('afterTask executed :)'); return x; }, - preTask, + preTask: () => { + return preTask; + }, afterTask }); }); -tap.test('should execute the mainTasj', async () => { +tap.test('should execute the mainTask', async () => { await mainTask.trigger(); }); diff --git a/ts/taskbuffer.classes.bufferrunner.ts b/ts/taskbuffer.classes.bufferrunner.ts new file mode 100644 index 0000000..a007330 --- /dev/null +++ b/ts/taskbuffer.classes.bufferrunner.ts @@ -0,0 +1,42 @@ +import { Task } from "./taskbuffer.classes.task"; + +export class BufferRunner { + public task: Task; + // initialze by default + public bufferCounter: number = 0; + public running: boolean = false; + constructor(taskArg: Task) { + this.task = taskArg; + } + + public trigger(x): Promise { + if (!(this.bufferCounter >= this.task.bufferMax)) { + this.bufferCounter++; + } + const returnPromise: Promise = this.task.cycleCounter.getPromiseForCycle( + this.bufferCounter + 1 + ); + if (!this.running) { + this._run(x); + } + return returnPromise; + } + + private _run(x) { + const recursiveBufferRunner = x => { + if (this.bufferCounter >= 0) { + this.running = true; + this.task.running = true; + Task.runTask(this.task, { x: x }).then(x => { + this.bufferCounter--; + this.task.cycleCounter.informOfCycle(x); + recursiveBufferRunner(x); + }); + } else { + this.running = false; + this.task.running = false; + } + }; + recursiveBufferRunner(x); + } +} \ No newline at end of file diff --git a/ts/taskbuffer.classes.cyclecounter.ts b/ts/taskbuffer.classes.cyclecounter.ts new file mode 100644 index 0000000..c432fe0 --- /dev/null +++ b/ts/taskbuffer.classes.cyclecounter.ts @@ -0,0 +1,36 @@ +import * as plugins from './taskbuffer.plugins'; +import { Task } from './taskbuffer.classes.task'; + +export interface ICycleObject { + cycleCounter: number; + deferred: plugins.smartpromise.Deferred; +} + +export class CycleCounter { + public task: Task; + public cycleObjectArray: ICycleObject[] = []; + constructor(taskArg: Task) { + this.task = taskArg; + } + public getPromiseForCycle(cycleCountArg: number) { + const done = plugins.smartpromise.defer(); + const cycleObject: ICycleObject = { + cycleCounter: cycleCountArg, + deferred: done + }; + this.cycleObjectArray.push(cycleObject); + return done.promise; + } + public informOfCycle(x) { + const newCycleObjectArray: ICycleObject[] = []; + this.cycleObjectArray.forEach(cycleObjectArg => { + cycleObjectArg.cycleCounter--; + if (cycleObjectArg.cycleCounter <= 0) { + cycleObjectArg.deferred.resolve(x); + } else { + newCycleObjectArray.push(cycleObjectArg); + } + }); + this.cycleObjectArray = newCycleObjectArray; + } +} diff --git a/ts/taskbuffer.classes.helpers.ts b/ts/taskbuffer.classes.helpers.ts index 16a825c..9357f5a 100644 --- a/ts/taskbuffer.classes.helpers.ts +++ b/ts/taskbuffer.classes.helpers.ts @@ -1,166 +1,5 @@ import plugins = require('./taskbuffer.plugins'); import { Task, ITaskFunction } from './taskbuffer.classes.task'; -export const emptyTaskFunction: ITaskFunction = function(x) { - const done = plugins.smartpromise.defer(); - done.resolve(); - return done.promise; -}; -export const isTask = (taskArg: Task): boolean => { - if (taskArg instanceof Task && typeof taskArg.taskFunction === 'function') { - return true; - } else { - return false; - } -}; -export const isTaskTouched = (taskArg: Task, touchedTasksArray: Task[]): boolean => { - let result = false; - for (const keyArg in touchedTasksArray) { - if (taskArg === touchedTasksArray[keyArg]) { - result = true; - } - } - return result; -}; - -export const runTask = async (taskArg: Task, optionsArg: { x?; touchedTasksArray?: Task[] }) => { - const done = plugins.smartpromise.defer(); - - // pay respect to execDelay - if (taskArg.execDelay) { - await plugins.smartdelay.delayFor(taskArg.execDelay); - } - - // set running params - taskArg.running = true; - - done.promise.then(async () => { - taskArg.running = false; - }); - - // handle options - const options = { - ...{ x: undefined, touchedTasksArray: [] }, - ...optionsArg - }; - const x = options.x; - const touchedTasksArray: Task[] = options.touchedTasksArray; - - touchedTasksArray.push(taskArg); - - // run the task cascade - const localDeferred = plugins.smartpromise.defer(); - localDeferred.promise - .then(() => { - // lets run any preTask - if (taskArg.preTask && !isTaskTouched(taskArg.preTask, touchedTasksArray)) { - return runTask(taskArg.preTask, { x, touchedTasksArray }); - } else { - const done2 = plugins.smartpromise.defer(); - done2.resolve(x); - return done2.promise; - } - }) - .then(async x => { - // lets run the main task - try { - return await taskArg.taskFunction(x); - } catch (e) { - console.log(e); - } - }) - .then(x => { - if (taskArg.afterTask && !isTaskTouched(taskArg.afterTask, touchedTasksArray)) { - return runTask(taskArg.afterTask, { x: x, touchedTasksArray: touchedTasksArray }); - } else { - const done2 = plugins.smartpromise.defer(); - done2.resolve(x); - return done2.promise; - } - }) - .then(x => { - done.resolve(x); - }) - .catch(err => { - console.log(err); - }); - localDeferred.resolve(); - return await done.promise; -}; - -export interface cycleObject { - cycleCounter: number; - deferred: plugins.smartpromise.Deferred; -} - -export class CycleCounter { - task: Task; - cycleObjectArray: cycleObject[] = []; - constructor(taskArg: Task) { - this.task = taskArg; - } - getPromiseForCycle(cycleCountArg: number) { - const done = plugins.smartpromise.defer(); - const cycleObject: cycleObject = { - cycleCounter: cycleCountArg, - deferred: done - }; - this.cycleObjectArray.push(cycleObject); - return done.promise; - } - informOfCycle(x) { - const newCycleObjectArray: cycleObject[] = []; - this.cycleObjectArray.forEach(cycleObjectArg => { - cycleObjectArg.cycleCounter--; - if (cycleObjectArg.cycleCounter <= 0) { - cycleObjectArg.deferred.resolve(x); - } else { - newCycleObjectArray.push(cycleObjectArg); - } - }); - this.cycleObjectArray = newCycleObjectArray; - } -} - -export class BufferRunner { - task: Task; - // initialze by default - bufferCounter: number = 0; - running: boolean = false; - constructor(taskArg: Task) { - this.task = taskArg; - } - - trigger(x): Promise { - if (!(this.bufferCounter >= this.task.bufferMax)) { - this.bufferCounter++; - } - const returnPromise: Promise = this.task.cycleCounter.getPromiseForCycle( - this.bufferCounter + 1 - ); - if (!this.running) { - this._run(x); - } - return returnPromise; - } - - private _run(x) { - const recursiveBufferRunner = x => { - if (this.bufferCounter >= 0) { - this.running = true; - this.task.running = true; - runTask(this.task, { x: x }).then(x => { - this.bufferCounter--; - this.task.cycleCounter.informOfCycle(x); - recursiveBufferRunner(x); - }); - } else { - this.running = false; - this.task.running = false; - } - }; - recursiveBufferRunner(x); - } -} diff --git a/ts/taskbuffer.classes.task.ts b/ts/taskbuffer.classes.task.ts index b6a7ba2..90ccf5e 100644 --- a/ts/taskbuffer.classes.task.ts +++ b/ts/taskbuffer.classes.task.ts @@ -1,29 +1,142 @@ import * as plugins from './taskbuffer.plugins'; import * as helpers from './taskbuffer.classes.helpers'; +import { BufferRunner } from './taskbuffer.classes.bufferrunner'; +import { CycleCounter } from './taskbuffer.classes.cyclecounter'; export interface ITaskFunction { (x?: any): PromiseLike; } -export class Task { - // man datory properties - name: string; - taskFunction: ITaskFunction; - buffered: boolean; +export type TPreOrAfterTaskFunction = () => Task; - bufferMax: number; - execDelay: number; +export class Task { + // STATIC + public static extractTask(preOrAfterTaskArg: Task | TPreOrAfterTaskFunction): Task { + switch(true) { + case (!preOrAfterTaskArg): + return null; + case (preOrAfterTaskArg instanceof Task): + return preOrAfterTaskArg as Task; + case typeof preOrAfterTaskArg === "function": + const taskFunction = preOrAfterTaskArg as TPreOrAfterTaskFunction; + return taskFunction(); + default: + return null; + } + } + + + public static emptyTaskFunction: ITaskFunction = function(x) { + const done = plugins.smartpromise.defer(); + done.resolve(); + return done.promise; + }; + + public static isTask = (taskArg: Task): boolean => { + if (taskArg instanceof Task && typeof taskArg.taskFunction === 'function') { + return true; + } else { + return false; + } + }; + + public static isTaskTouched = (taskArg: Task | TPreOrAfterTaskFunction, touchedTasksArray: Task[]): boolean => { + const taskToCheck = Task.extractTask(taskArg); + let result = false; + for (const keyArg in touchedTasksArray) { + if (taskToCheck === touchedTasksArray[keyArg]) { + result = true; + } + } + return result; + }; + + public static runTask = async (taskArg: Task | TPreOrAfterTaskFunction, optionsArg: { x?; touchedTasksArray?: Task[] }) => { + const taskToRun = Task.extractTask(taskArg); + const done = plugins.smartpromise.defer(); + + // pay respect to execDelay + if (taskToRun.execDelay) { + await plugins.smartdelay.delayFor(taskToRun.execDelay); + } + + // set running params + taskToRun.running = true; + + done.promise.then(async () => { + taskToRun.running = false; + }); + + // handle options + const options = { + ...{ x: undefined, touchedTasksArray: [] }, + ...optionsArg + }; + const x = options.x; + const touchedTasksArray: Task[] = options.touchedTasksArray; + + touchedTasksArray.push(taskToRun); + + // run the task cascade + const localDeferred = plugins.smartpromise.defer(); + localDeferred.promise + .then(() => { + // lets run any preTask + + if (taskToRun.preTask && !Task.isTaskTouched(taskToRun.preTask, touchedTasksArray)) { + return Task.runTask(taskToRun.preTask, { x, touchedTasksArray }); + } else { + const done2 = plugins.smartpromise.defer(); + done2.resolve(x); + return done2.promise; + } + }) + .then(async x => { + // lets run the main task + try { + return await taskToRun.taskFunction(x); + } catch (e) { + console.log(e); + } + }) + .then(x => { + if (taskToRun.afterTask && !Task.isTaskTouched(taskToRun.afterTask, touchedTasksArray)) { + return Task.runTask(taskToRun.afterTask, { x: x, touchedTasksArray: touchedTasksArray }); + } else { + const done2 = plugins.smartpromise.defer(); + done2.resolve(x); + return done2.promise; + } + }) + .then(x => { + done.resolve(x); + }) + .catch(err => { + console.log(err); + }); + localDeferred.resolve(); + return await done.promise; + } + + // INSTANCE + // man datory properties + public name: string; + public taskFunction: ITaskFunction; + public buffered: boolean; + + public bufferMax: number; + public execDelay: number; // tasks to run before and after - preTask: Task; - afterTask: Task; + public preTask: Task | TPreOrAfterTaskFunction; + public afterTask: Task | TPreOrAfterTaskFunction; // initialize by default - running: boolean = false; - bufferRunner = new helpers.BufferRunner(this); - cycleCounter = new helpers.CycleCounter(this); + public running: boolean = false; + public bufferRunner = new BufferRunner(this); + public cycleCounter = new CycleCounter(this); - idle: boolean = true; + public idle: boolean = true; private _state: string = 'ready'; constructor(optionsArg: { @@ -34,11 +147,11 @@ export class Task { /** * any other task to run before */ - preTask?: Task; + preTask?: Task | TPreOrAfterTaskFunction; /** * any other task to run after */ - afterTask?: Task; + afterTask?: Task | TPreOrAfterTaskFunction; /** * wether this task should run buffered */ @@ -70,7 +183,7 @@ export class Task { /** * trigger the task. Will trigger buffered if this.buffered is true */ - trigger(x?): Promise { + public trigger(x?): Promise { if (this.buffered) { return this.triggerBuffered(x); } else { @@ -81,14 +194,14 @@ export class Task { /** * trigger task unbuffered. */ - triggerUnBuffered(x?): Promise { - return helpers.runTask(this, { x: x }); + public triggerUnBuffered(x?): Promise { + return Task.runTask(this, { x: x }); } /** * trigger task buffered. */ - triggerBuffered(x?): Promise { + public triggerBuffered(x?): Promise { return this.bufferRunner.trigger(x); }