1 module sbylib.graphics.action.sequence; 2 3 public import std.datetime; 4 5 import sbylib.graphics.action.action : IAction, ImplAction; 6 import sbylib.graphics.action.animation : Animation; 7 import sbylib.graphics.action.run : RunAction; 8 import sbylib.graphics.action.wait : WaitAction; 9 import sbylib.event : VoidEvent; 10 import std.container : Array; 11 12 class ActionSequence : IAction { 13 14 mixin ImplAction; 15 16 private ActionNode rootAction; 17 private IAction[] actionList; 18 19 static opCall() { 20 return new typeof(this); 21 } 22 23 override void start() { 24 rootAction.action.start(); 25 } 26 27 auto animate(string mem,T)(T value) { 28 import std.traits : ReturnType; 29 30 alias Type = ReturnType!(mixin("value."~mem)); 31 auto result = new Animation!Type( 32 () => mixin("value."~mem), 33 (Type v) { mixin("value."~mem) = v; } 34 ); 35 add(result); 36 return result; 37 } 38 39 Animation!T animate(T)(ref T value) { 40 auto result = new Animation!T(value); 41 add(result); 42 return result; 43 } 44 45 IAction action(IAction action) { 46 add(action); 47 return action; 48 } 49 50 WaitAction wait(Duration dur) { 51 auto result = new WaitAction(dur); 52 add(result); 53 return result; 54 } 55 56 RunAction run(void delegate() f) { 57 auto result = new RunAction(f); 58 add(result); 59 return result; 60 } 61 62 RunAction run(void delegate(void delegate()) f) { 63 auto result = new RunAction(f); 64 add(result); 65 return result; 66 } 67 68 private void add(IAction action) { 69 if (rootAction is null) { 70 rootAction = new ActionNode(action); 71 } else { 72 rootAction.add(new ActionNode(action)); 73 } 74 } 75 76 private void onFinish() { 77 for (int j = 0; j < callbackList.length; j++) { 78 callbackList[j](); 79 } 80 callbackList.clear(); 81 } 82 83 private class ActionNode { 84 IAction action; 85 ActionNode next; 86 87 this(IAction action) { 88 import sbylib.graphics.action.action : when; 89 import sbylib.event.event : then; 90 91 this.action = action; 92 when(action.finish).then({ 93 if (next is null) { 94 onFinish(); 95 } else { 96 next.action.start(); 97 } 98 rootAction = next; 99 }); 100 } 101 102 void add(ActionNode node) { 103 if (next is null) { 104 next = node; 105 } else { 106 next.add(node); 107 } 108 } 109 } 110 }