1 module artemisd.componentmanager;
2 
3 import std.bitmanip;
4 import artemisd.utils.bag;
5 import artemisd.manager;
6 import artemisd.component;
7 import artemisd.entity;
8 import artemisd.utils.ext;
9 import artemisd.utils.type;
10 
11 class ComponentManager : Manager 
12 {
13     mixin TypeDecl;
14 
15     private Bag!(Bag!Component) componentsByType;
16     private Bag!Entity _deleted;
17 
18     this() 
19     {
20         componentsByType = new Bag!(Bag!Component)();
21         _deleted = new Bag!Entity();
22     }
23     
24     protected override void initialize() 
25     {
26     }
27 
28     private void removeComponentsOfEntity(Entity e) 
29     {
30         BitArray componentBits = e.getComponentBits();
31         for (auto i = componentBits.nextSetBit(0); i >= 0; i = componentBits.nextSetBit(i+1)) 
32         {
33             componentsByType.get(i).set(e.getId(), null);
34         }
35         e.clearComponents();
36     }
37     
38     protected void addComponent(T)(Entity e, T component) 
39         if( is(T:Component) )
40     {
41         componentsByType.ensureCapacity(T.TypeId);
42         
43         Bag!Component components = componentsByType.get(T.TypeId);
44         if(components is null) 
45         {
46             components = new Bag!Component();
47             componentsByType.set(T.TypeId, components);
48         }
49         
50         components.set(e.getId(), component);
51 
52         e.getComponentBits()[T.TypeId] = 1;
53     }
54 
55     protected void removeComponent(T)(Entity e)
56         if( is(T:Component) )
57     {
58         if(e.getComponentBits().get(T.TypeId)) 
59         {
60             componentsByType.get(T.TypeId).set(e.getId(), null);
61             e.getComponentBits()[T.TypeId] = 0;
62         }
63     }
64     
65     protected Bag!Component getComponents(T)()
66         if( is(T:Component) )
67     {
68         Bag!Component components = componentsByType.get(T.TypeId);
69         if(components == null) 
70         {
71             components = new Bag!Component();
72             componentsByType.set(T.TypeId, components);
73         }
74         return components;
75     }
76     
77     protected T getComponent(T)(Entity e)
78         if( is(T:Component) )
79     {
80         Bag!Component components = componentsByType.get(T.TypeId);
81         if(components !is null) 
82         {
83             return cast(T)(components.get(e.getId()));
84         }
85         return null;
86     }
87     
88     Bag!Component getComponentsFor(Entity e, Bag!Component fillBag) 
89     {
90         BitArray componentBits = e.getComponentBits();
91 
92         for (auto i = componentBits.nextSetBit(0); i >= 0; i = componentBits.nextSetBit(i+1)) 
93         {
94             fillBag.add(componentsByType.get(i).get(e.getId()));
95         }
96         
97         return fillBag;
98     }
99 
100     
101     override void deleted(Entity e) 
102     {
103         _deleted.add(e);
104     }
105     
106     void clean() 
107     {
108         if(_deleted.size() > 0) 
109         {
110             for(int i = 0; _deleted.size() > i; i++) 
111             {
112                 removeComponentsOfEntity(_deleted.get(i));
113             }
114             _deleted.clear();
115         }
116     }
117 }