Skip to content

Instantly share code, notes, and snippets.

@grisevg
Last active June 15, 2016 23:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grisevg/1d732a25866617e19c94 to your computer and use it in GitHub Desktop.
Save grisevg/1d732a25866617e19c94 to your computer and use it in GitHub Desktop.
FlowBlockList.hx
package ;
import List;
import tink.core.Noise;
import tink.core.Signal;
import tink.core.SignalTrigger;
using Lambda;
typedef Flow = Void -> Void;
enum FlowBlock
{
SequentialBlocks(block:Array<FlowBlock>);
ParallelBlocks(blocks:Array<FlowBlock>);
SyncBlock(f:Void->Void);
AsyncBlock(f:Flow->Void);
}
class FlowBlockList
{
public var onFinished(default, null):Signal<Noise>;
public var running(default, null):Bool;
var onFinishedTrigger:SignalTrigger<Noise>;
var queue:List<FlowBlock>; //FIFO queue
public function new(blocks:Array<FlowBlock> = null)
{
queue = (blocks != null) ? Lambda.list(blocks) : new List();
running = false;
onFinishedTrigger = new SignalTrigger();
onFinished = onFinishedTrigger.asSignal();
}
public function getLength():Int
{
return queue.length;
}
public function add(block:FlowBlock):FlowBlockList
{
queue.add(block);//Add to the end of the queue
return this;
}
public function addMany(blocks:Array<FlowBlock>):FlowBlockList
{
for (block in blocks) queue.add(block);//Add to the end of the queue
return this;
}
public function push(block:FlowBlock):FlowBlockList
{
queue.push(block);//Add to the beginning of the queue
return this;
}
public function pushMany(blocks:Array<FlowBlock>):FlowBlockList
{
blocks.reverse(); // Need to reverse so blocks are still in order
for (block in blocks) queue.push(block);//Add to the beginning of the queue
return this;
}
public function execute(callback:Void -> Void = null):FlowBlockList
{
if (callback != null) onFinished.next().handle(callback);
if (running) return this;
running = true;
executeNextBlock();
return this;
}
public function emptyQueue():FlowBlockList
{
queue.clear();
return this;
}
function executeNextBlock():Void
{
if (queue.length == 0) {
running = false;
onFinishedTrigger.trigger(Noise);
return;
};
var nextBlock = queue.pop();//Remove from the begining of the queue
executeBlock(nextBlock, executeNextBlock);
}
static function executeBlock(block:FlowBlock, callback:Void -> Void):Void
{
switch(block) {
case FlowBlock.SequentialBlocks(blocks):
var index = -1;
function handleFinished() (++index < blocks.length) ? executeBlock(blocks[index], handleFinished) : callback();
handleFinished();
case FlowBlock.ParallelBlocks(blocks):
if (blocks.length == 0) callback();
var totalFinished = 0;
function handleFinished() if (++totalFinished == blocks.length) callback();
for (block in blocks) executeBlock(block, handleFinished);
case FlowBlock.SyncBlock(f):
f();
callback();
case FlowBlock.AsyncBlock(f):
f(callback);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment