1 module artemisd.entitymanager;
2 
3 import std.bitmanip;
4 import artemisd.utils.bag;
5 import artemisd.entity;
6 import artemisd.manager;
7 import artemisd.world;
8 import artemisd.utils.type;
9 
10 class EntityManager : Manager
11 {
12     mixin TypeDecl;
13 
14 private:
15     Bag!Entity entities;
16     BitArray disabled_;
17 
18     int active;
19     long added_;
20     long created;
21     long deleted_;
22 
23     IdentifierPool identifierPool;
24 
25 public:
26     this()
27     {
28         entities = new Bag!Entity();
29         identifierPool = new IdentifierPool();
30     }
31 
32     protected override void initialize()
33     {
34     }
35 
36     Entity createEntityInstance()
37     {
38         Entity e = new Entity(world, identifierPool.checkOut());
39         created++;
40         return e;
41     }
42 
43     override void added(Entity e)
44     {
45         active++;
46         added_++;
47         entities.set(e.getId(), e);
48     }
49 
50     override void enabled(Entity e)
51     {
52         auto eId = e.getId();
53         if (disabled_.length <= eId)
54             disabled_.length = eId + 1;
55         disabled_[e.getId()] = 0;
56     }
57 
58     override void disabled(Entity e)
59     {
60         auto eId = e.getId();
61         if (disabled_.length <= eId)
62             disabled_.length = eId + 1;
63         disabled_[e.getId()] = 1;
64     }
65 
66     override void deleted(Entity e)
67     {
68         entities.set(e.getId(), null);
69         auto eId = e.getId();
70         if (disabled_.length <= eId)
71             disabled_.length = eId + 1;
72         disabled_[e.getId()] = 0;
73         identifierPool.checkIn(e.getId());
74 
75         active--;
76         deleted_++;
77     }
78 
79     bool isActive(int entityId)
80     {
81         return entities.get(entityId) !is null;
82     }
83 
84     bool isEnabled(int entityId)
85     {
86         return !disabled_[entityId];
87     }
88 
89     Entity getEntity(int entityId)
90     {
91         return entities.get(entityId);
92     }
93 
94     int getActiveEntityCount()
95     {
96         return active;
97     }
98 
99     long getTotalCreated()
100     {
101         return created;
102     }
103 
104     long getTotalAdded()
105     {
106         return added_;
107     }
108 
109     long getTotalDeleted()
110     {
111         return deleted_;
112     }
113 
114     private class IdentifierPool
115     {
116         private Bag!int ids;
117         private int nextAvailableId;
118 
119         this()
120         {
121             ids = new Bag!int();
122         }
123 
124         int checkOut()
125         {
126             if(ids.size() > 0)
127             {
128                 return ids.removeLast();
129             }
130             return nextAvailableId++;
131         }
132 
133         void checkIn(int id)
134         {
135             ids.add(id);
136         }
137     }
138 }