﻿func Wait(n) := "Waited" if Range(n * 1_000_000)->Sum() > 0 else "";

"";
"*** Prime, use in expression should take a snapshot";
prime T0 as Pipe(Range(5));
(T0$State, T0$ResultNames);
T0.Count;

// Takes a snapshot.
A := T0.SData;
A;

play T0;
Wait(1);
pause T0;

// Takes a snapshot.
B := T0.SData;
B;

poll T0;
(T0$State, T0$ResultNames);
T0.Data;

"";
"*** Play, prime, poke, pause, finish";
task T0 as StepPipe(Range(5), 3);
(T0$State, T0$ResultNames);
T0.Count;

play T0;
prime T0;
poke T0;
poke T0;
Wait(1);
pause T0;
T0.Count;

poke T0;
finish T0;
T0.Count;
T0.Data;

"";
"*** Prime, play, poke, pause, finish";
prime T0 as StepPipe(Range(5));
(T0$State, T0$ResultNames);
T0.Count;

play T0;
Wait(1);
poke T0;
poke T0;
poke T0;
pause T0;
T0.Count;

finish T0;
T0.Count;
T0.Data;

"";
"*** Two tasks: Prime, play, poke, pause, finish";
prime T0 as StepPipe(Range(5));
(T0$State, T0$ResultNames);
T0.Count;
task T1 as Pipe(T0.SData);
(T1$State, T1$ResultNames);
T1.Count;

play T1;
poke T0;
poke T0;
Wait(1);

pause T1;
// Not stable: (T0.Count, T1.Count);

"";
"*** Two tasks: Create second while first is playing";
prime T0 as StepPipe(Range(5));
(T0$State, T0$ResultNames);
T0.Count;

play T0;
poke T0;
poke T0;

task T1 as Pipe(T0.SData);
(T1$State, T1$ResultNames);
T1.Count;

play T1;
Wait(1);

pause T1;
// Not stable: (T0.Count, T1.Count);

"";
"*** Two tasks: Allow play, control at end";
prime T0 as StepPipe(Range(5), 1);
(T0$State, T0$ResultNames);
T0.Count;
task T1 as Pipe(T0.SData);
(T1$State, T1$ResultNames);
T1.Count;

play T1;
pause T1;
// Not stable: T1.Count;
poke T0;
finish T1;
T1.Count;

"";
"*** Three sequential tasks: Allow play, control at end";
prime T0 as StepPipe(Range(5), 1);
(T0$State, T0$ResultNames);
T0.Count;
prime T1 as Pipe(T0.SData);
(T1$State, T1$ResultNames);
T1.Count;
prime T2 as Pipe(T1.SData);
(T2$State, T2$ResultNames);
T2.Count;

play T2;
pause T2;
// Not stable: (T0.Count, T1.Count, T2.Count);
poke T0;
finish T2;
T2.Count;

"";
"*** Parallel tasks: Allow play, control at ends";
prime T0 as StepPipe(Range(5), 2);
(T0$State, T0$ResultNames);
T0.Count;
task T1 as Pipe(T0.SData);
(T1$State, T1$ResultNames);
T1.Count;
task T2 as Pipe(T0.SData);
(T2$State, T2$ResultNames);
T2.Count;

play T2;
pause T2;
// Not stable: (T0.Count, T1.Count, T2.Count);

poke T0;
play T1;
pause T1;
// Not stable: (T0.Count, T1.Count, T2.Count);

poke T0;
finish T2;
T2.Count;

finish T1;
T1.Count;

"";
"*** Diamond";
prime T0 as StepPipe(Range(1, 6), 2);
(T0$State, T0$ResultNames);
T0.Count;
prime T1 as Pipe(T0.SData);
(T1$State, T1$ResultNames);
T1.Count;
prime T2 as Pipe(-T0.SData);
(T2$State, T2$ResultNames);
T2.Count;
task T3 as Pipe(T1.SData, T2.SData);
(T3$State, T3$ResultNames);
T3.Count;
(T0.Count, T1.Count, T2.Count, T3.Count);

poke T0;
play T3;
pause T3;
// Not stable: (T0.Count, T1.Count, T2.Count, T3.Count);

poke T0;
play T1;
pause T1;
// Not stable: (T0.Count, T1.Count, T2.Count, T3.Count);

finish T3;
T3.Count;
(T0.Count, T1.Count, T2.Count, T3.Count);

poll T0;
poll T1;
poll T2;

T0.Data;
T1.Data;
T2.Data;
T3.Data;

"";
"*** Non-stable result not available while playing";
prime T0 as Pipe(Range(1, 6));
(T0$State, T0$ResultNames);
T0.Count;
T0.SData; // Should take a snapshot.

play T0;
(T0$State, T0$ResultNames);
Wait(1);
T0.Count; // Error. Non-stable not available.

T0.SData; // Should take a snapshot, even while playing.

poll T0; // Should be finished (because of the wait).
T0.Count; // No longer an error.
