Browse Source

multistep task

David Sehnal 7 years ago
parent
commit
7f3b2316ee

+ 28 - 6
src/examples/computation.ts

@@ -4,7 +4,7 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { Task, Run, Progress, Scheduler, now } from 'mol-task'
+import { Task, Run, Progress, Scheduler, now, MultistepTask } from 'mol-task'
 
 export async function test1() {
     const t = Task.create('test', async () => 1);
@@ -13,11 +13,17 @@ export async function test1() {
 }
 
 function messageTree(root: Progress.Node, prefix = ''): string {
-    if (!root.children.length) return `${prefix}${root.progress.taskName}: ${root.progress.message}`;
+    const p = root.progress;
+    if (!root.children.length) {
+        if (p.isIndeterminate) return `${prefix}${p.taskName}: ${p.message}`;
+        return `${prefix}${p.taskName}: [${p.current}/${p.max}] ${p.message}`;
+    }
 
     const newPrefix = prefix + '  |_ ';
     const subTree = root.children.map(c => messageTree(c, newPrefix));
-    return `${prefix}${root.progress.taskName}: ${root.progress.message}\n${subTree.join('\n')}`;
+    if (p.isIndeterminate) return `${prefix}${p.taskName}: ${p.message}\n${subTree.join('\n')}`;
+    return `${prefix}${p.taskName}: [${p.current}/${p.max}] ${p.message}\n${subTree.join('\n')}`;
+
 }
 
 function createTask<T>(delayMs: number, r: T): Task<T> {
@@ -38,7 +44,7 @@ export function abortAfter(delay: number) {
     });
 }
 
-function testTree() {
+export function testTree() {
     return Task.create('test o', async ctx => {
         await Scheduler.delay(250);
         if (ctx.shouldUpdate) await ctx.update({ message: 'hi! 1' });
@@ -60,6 +66,17 @@ function testTree() {
     });
 }
 
+const ms = MultistepTask('ms-task', ['step 1', 'step 2', 'step 3'], async (p: { i: number }, step) => {
+    await Scheduler.delay(250);
+    await step(0);
+    await Scheduler.delay(250);
+    await step(1);
+    await Scheduler.delay(250);
+    await step(2);
+    await Scheduler.delay(250);
+    return p.i + 3;
+})
+
 export function abortingObserver(p: Progress) {
     console.log(messageTree(p.root));
     if (now() - p.root.progress.startedTime > 1000) {
@@ -67,11 +84,16 @@ export function abortingObserver(p: Progress) {
     }
 }
 
+export function logP(p: Progress) { console.log(messageTree(p.root)); }
+
 async function test() {
     try {
         //const r = await Run(testTree(), p => console.log(messageTree(p.root)), 250);
-        const r = await Run(testTree(), abortingObserver, 250);
-        console.log(r);
+        //const r = await Run(testTree(), abortingObserver, 250);
+        //console.log(r);
+
+        const m = await Run(ms({ i: 10 }), logP);
+        console.log(m);
     } catch (e) {
         console.error(e);
     }

+ 1 - 1
src/mol-task/execution/observable.ts

@@ -158,9 +158,9 @@ class ObservableRuntimeContext implements RuntimeContext {
         } else {
             if (typeof update.canAbort !== 'undefined') progress.canAbort = update.canAbort;
             if (typeof update.current !== 'undefined') progress.current = update.current;
-            if (typeof update.isIndeterminate !== 'undefined') progress.isIndeterminate = update.isIndeterminate;
             if (typeof update.max !== 'undefined') progress.max = update.max;
             if (typeof update.message !== 'undefined') progress.message = update.message;
+            progress.isIndeterminate = typeof progress.current === 'undefined' || typeof progress.max === 'undefined';
         }
     }
 

+ 2 - 1
src/mol-task/index.ts

@@ -11,6 +11,7 @@ import { ExecuteObservable } from './execution/observable'
 import { Progress } from './execution/progress'
 import { now } from './util/now'
 import { Scheduler } from './util/scheduler'
+import { MultistepTask } from './util/multistep'
 
 // Run the task without the ability to observe its progress.
 function Run<T>(task: Task<T>): Promise<T>;
@@ -21,4 +22,4 @@ function Run<T>(task: Task<T>, observer?: Progress.Observer, updateRateMs?: numb
     return ExecuteSynchronous(task);
 }
 
-export { Task, RuntimeContext, Progress, Run, now, Scheduler }
+export { Task, RuntimeContext, Progress, Run, now, Scheduler, MultistepTask }

+ 2 - 0
src/mol-task/task.ts

@@ -40,6 +40,8 @@ namespace Task {
         max: number
     }
 
+    export type Provider<P, T> = (params: P) => Task<T>
+
     let _id = 0;
     function nextId() {
         const ret = _id;

+ 17 - 0
src/mol-task/util/multistep.ts

@@ -0,0 +1,17 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import { Task } from '../task'
+import { RuntimeContext } from '../execution/runtime-context'
+
+export type MultistepFn<P, T> =
+    (params: P, step: (s: number) => Promise<void> | void, ctx: RuntimeContext) => Promise<T>
+
+function MultistepTask<P, T>(name: string, steps: string[], f: MultistepFn<P, T>, onAbort?: () => void): Task.Provider<P, T> {
+    return params => Task.create(name, async ctx => f(params, n => ctx.update({ message: `${steps[n]}`, current: n + 1, max: steps.length }), ctx), onAbort);
+}
+
+export { MultistepTask }