1 /**
2  * This internal class maintains a pool of deleted nodes for reuse by the framework. This reduces the overhead
3  * from object creation and garbage collection.
4  * 
5  * Because nodes may be deleted from a NodeList while in use, by deleting Nodes from a NodeList
6  * while iterating through the NodeList, the pool also maintains a cache of nodes that are added to the pool
7  * but should not be reused yet. They are then released into the pool by calling the releaseCache method.
8  */
9 module ashd.core.nodepool;
10 
11 import ashd.core.entity   : Entity;
12 import ashd.core.ifamily  : IFamily;
13 import ashd.core.node     : Node;
14 
15 
16 private class NodePool(Class)
17 {
18     private
19     {
20         string[ClassInfo] *mComponents;
21         Node               mTail;
22         Node               mCacheTail;
23         IFamily            mFamily;
24     }
25 
26 
27     /**
28      * Creates a pool for the given node class.
29      */
30     public this( ref string[ClassInfo] components_a, IFamily family_a )
31     {
32         mComponents = &components_a;
33         mFamily = family_a;
34     }
35 
36     /**
37      * Fetches a node from the pool.
38      */
39     public Node get()
40     {
41         if ( mTail )
42         {
43             Node node = mTail;
44             mTail = mTail.previous;
45             node.previous = null;
46             return node;
47         }
48         else
49         {
50             Node tmp = new Class;
51             if ( tmp is null )
52                 throw new Error( "Error creating new class !" );
53             return tmp;
54         }
55     }
56 
57     /**
58      * Adds a node to the pool.
59      */
60     public void dispose( Node node_a )
61     {
62 
63         mFamily.resetNode( node_a );
64         node_a.entity = null;
65         
66         node_a.next = null;
67         node_a.previous = mTail;
68         mTail = node_a;
69     }
70  
71     /**
72      * Adds a node to the cache
73      */
74     public void cache( Node node_a )
75     {
76         node_a.previous = mCacheTail;
77         mCacheTail = node_a;
78     }
79  
80     /**
81      * Releases all nodes from the cache into the pool
82      */
83     public void releaseCache()
84     {
85         while( mCacheTail )
86         {
87             Node node = mCacheTail;
88             mCacheTail = node.previous;
89             this.dispose( node );
90         }
91     }
92 } // private class NodePool