1 module artemisd.systems.delayedentityprocessingsystem; 2 3 import artemisd.aspect; 4 import artemisd.entity; 5 import artemisd.entitysystem; 6 import artemisd.utils.type; 7 import artemisd.utils.bag; 8 9 abstract class DelayedEntityProcessingSystem : EntitySystem 10 { 11 mixin TypeDecl; 12 13 private float delay; 14 private bool running; 15 private float acc; 16 17 public this(Aspect aspect) 18 { 19 super(aspect); 20 } 21 22 protected final override void processEntities(Bag!Entity entities) 23 { 24 for (size_t i = 0, s = entities.size(); s > i; i++) 25 { 26 Entity entity = entities.get(i); 27 processDelta(entity, acc); 28 float remaining = getRemainingDelay(entity); 29 if(remaining <= 0) 30 { 31 processExpired(entity); 32 } 33 else 34 { 35 offerDelay(remaining); 36 } 37 } 38 stop(); 39 } 40 41 protected override void inserted(Entity e) 42 { 43 float delay = getRemainingDelay(e); 44 if(delay > 0) 45 { 46 offerDelay(delay); 47 } 48 } 49 50 protected abstract float getRemainingDelay(Entity e); 51 52 protected final override bool checkProcessing() 53 { 54 if(running) 55 { 56 acc += world.getDelta(); 57 58 if(acc >= delay) 59 { 60 return true; 61 } 62 } 63 return false; 64 } 65 66 protected abstract void processDelta(Entity e, float accumulatedDelta); 67 protected abstract void processExpired(Entity e); 68 69 public void restart(float delay) 70 { 71 this.delay = delay; 72 this.acc = 0; 73 running = true; 74 } 75 76 public void offerDelay(float delay) 77 { 78 if(!running || delay < getRemainingTimeUntilProcessing()) 79 { 80 restart(delay); 81 } 82 } 83 84 public float getInitialTimeDelay() 85 { 86 return delay; 87 } 88 89 public float getRemainingTimeUntilProcessing() 90 { 91 if(running) 92 { 93 return delay-acc; 94 } 95 return 0; 96 } 97 98 public bool isRunning() 99 { 100 return running; 101 } 102 103 public void stop() 104 { 105 this.running = false; 106 this.acc = 0; 107 } 108 }