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 }