1 /**
2  * A useful class for systems which simply iterate over a set of nodes, performing the same action 
3  * on each node. This class removes the need for a lot of boilerplate code in such systems.
4  * Extend this class and pass the node type and a node update method into the constructor.
5  * The node update method will be called once per node on the update cycle
6  * with the node instance and the frame time as parameters. e.g.
7  *
8  *   public class MySystem: ListIteratingSystem
9  *   {
10  *     override public void MySystem()
11  *     {
12  *       super( MyNode, updateNode );
13  *     }
14  *
15  *     override private void updateNode( MyNode node, Duration time )
16  *     {
17  *       // process the node here
18  *     }
19  *   }
20  * }
21  */
22 module ashd.tools.listIteratingSystem;
23 
24 
25 import ashd.core.system   : System;
26 import ashd.core.iengine  : IEngine;
27 import ashd.core.engine   : Engine;
28 import ashd.core.node     : Node;
29 import ashd.core.nodelist : NodeList;
30 
31 
32 import std.datetime       : Duration;
33 
34 
35 public class ListIteratingSystem(N): System
36 {
37     private
38     {
39         NodeList mNodeList;
40         void delegate( Node, Duration ) mNodeUpdateFunction;
41         void delegate( Node ) mNodeAddedFunction;
42         void delegate( Node ) mNodeRemovedFunction;
43     }
44 
45     public this( void delegate( Node, Duration ) nodeUpdateFunction_a,
46                  void delegate( Node ) nodeAddedFunction_a = null,
47                  void delegate( Node ) nodeRemovedFunction_a = null )
48     {
49         this.mNodeUpdateFunction = nodeUpdateFunction_a;
50         this.mNodeAddedFunction = nodeAddedFunction_a;
51         this.mNodeRemovedFunction = nodeRemovedFunction_a;
52     }
53 
54 
55 
56     override public void addToEngine( IEngine engine_a )
57     {
58         mNodeList = engine_a.getNodeList( N.classinfo );
59         if ( mNodeAddedFunction !is null )
60         {
61             for ( Node node = mNodeList.head; node; node = node.next )
62             {
63                 mNodeAddedFunction( node );
64             }
65             mNodeList.nodeAdded.connect( mNodeAddedFunction );
66 
67         }
68         if( mNodeRemovedFunction !is null )
69         {
70             mNodeList.nodeRemoved.connect( mNodeRemovedFunction );
71         }
72     }
73     
74     override public void removeFromEngine( IEngine engine_a )
75     {
76         if ( mNodeAddedFunction !is null )
77         {
78             mNodeList.nodeAdded.disconnect( mNodeAddedFunction );
79         }
80         if( mNodeRemovedFunction !is null )
81         {
82             mNodeList.nodeRemoved.disconnect( mNodeRemovedFunction );
83         }
84         mNodeList = null;
85     }
86     
87     override public void update( Duration time_a )
88     {
89         for ( Node node = mNodeList.head; node; node = node.next )
90         {
91             mNodeUpdateFunction( node, time_a );
92         }
93     }
94 }