Last active
June 15, 2016 23:41
-
-
Save grisevg/1d732a25866617e19c94 to your computer and use it in GitHub Desktop.
FlowBlockList.hx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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