1 /** 2 * Represents a state for a SystemStateMachine. The state contains any number of SystemProviders which 3 * are used to add Systems to the Engine when this state is entered. 4 */ 5 module ashd.fsm.engineState; 6 7 import std.conv: to; 8 9 import ashd.core.system : System; 10 import ashd.fsm.dynamicSystemProvider : DynamicSystemProvider; 11 import ashd.fsm.ISystemProvider : ISystemProvider; 12 import ashd.fsm.systemInstanceProvider : SystemInstanceProvider; 13 import ashd.fsm.systemSingletonProvider: SystemSingletonProvider; 14 15 16 17 public class EngineState 18 { 19 private 20 { 21 ISystemProvider[ClassInfo] mProviders; 22 } 23 24 ISystemProvider[ClassInfo] providers() { return mProviders; } 25 26 /** 27 * Creates a mapping for the System type to a specific System instance. A 28 * SystemInstanceProvider is used for the mapping. 29 * 30 * @param system The System instance to use for the mapping 31 * @return This StateSystemMapping, so more modifications can be applied 32 */ 33 public StateSystemMapping addInstance(T)( T system_a ) 34 { 35 return this.addProvider( new SystemInstanceProvider!T( system_a ), T.classinfo ); 36 } 37 38 /** 39 * Creates a mapping for the System type to a single instance of the provided type. 40 * The instance is not created until it is first requested. The type should be the same 41 * as or extend the type for this mapping. A SystemSingletonProvider is used for 42 * the mapping. 43 * 44 * @param type The type of the single instance to be created. If omitted, the type of the 45 * mapping is used. 46 * @return This StateSystemMapping, so more modifications can be applied 47 */ 48 public StateSystemMapping addSingleton( ClassInfo type_a ) 49 { 50 return addProvider( new SystemSingletonProvider( type_a ), type_a ); 51 52 } 53 54 /** 55 * Creates a mapping for the System type to a method call. 56 * The method should return a System instance. A DynamicSystemProvider is used for 57 * the mapping. 58 * 59 * @param method The method to provide the System instance. 60 * @return This StateSystemMapping, so more modifications can be applied. 61 */ 62 public StateSystemMapping addMethod(T)( T delegate() method_a ) 63 { 64 return addProvider( new DynamicSystemProvider( method_a ), T.classinfo ); 65 } 66 67 /** 68 * Adds any SystemProvider. 69 * 70 * @param provider The component provider to use. 71 * @return This StateSystemMapping, so more modifications can be applied. 72 */ 73 public StateSystemMapping addProvider( ISystemProvider provider_a, ClassInfo class_a ) 74 { 75 StateSystemMapping mapping = new StateSystemMapping( this, provider_a ); 76 mProviders[class_a] = provider_a; 77 return mapping; 78 } 79 } 80 81 82 83 class StateSystemMapping 84 { 85 private 86 { 87 EngineState mCreatingState; 88 ISystemProvider mProvider; 89 } 90 91 /** 92 * Used internally, the constructor creates a component mapping. The constructor 93 * creates a SystemSingletonProvider as the default mapping, which will be replaced 94 * by more specific mappings if other methods are called. 95 * 96 * @param creatingState The SystemState that the mapping will belong to 97 * @param type The System type for the mapping 98 */ 99 private this( EngineState creatingState_a, ISystemProvider provider_a ) 100 { 101 mCreatingState = creatingState_a; 102 mProvider = provider_a; 103 } 104 105 /** 106 * Applies the priority to the provider that the System will be. 107 * 108 * @param priority The component provider to use. 109 * @return This StateSystemMapping, so more modifications can be applied. 110 */ 111 public StateSystemMapping withPriority( int priority_a ) 112 { 113 mProvider.priority = priority_a; 114 return this; 115 } 116 117 /** 118 * Creates a mapping for the System type to a specific System instance. A 119 * SystemInstanceProvider is used for the mapping. 120 * 121 * @param system The System instance to use for the mapping 122 * @return This StateSystemMapping, so more modifications can be applied 123 */ 124 public StateSystemMapping addInstance(T)( System system_a ) 125 { 126 return mCreatingState.addInstance!T( system_a ); 127 } 128 129 /** 130 * Creates a mapping for the System type to a single instance of the provided type. 131 * The instance is not created until it is first requested. The type should be the same 132 * as or extend the type for this mapping. A SystemSingletonProvider is used for 133 * the mapping. 134 * 135 * @param type The type of the single instance to be created. If omitted, the type of the 136 * mapping is used. 137 * @return This StateSystemMapping, so more modifications can be applied 138 */ 139 public StateSystemMapping addSingleton( ClassInfo type_a ) 140 { 141 return mCreatingState.addSingleton( type_a ); 142 } 143 144 /** 145 * Creates a mapping for the System type to a method call. 146 * The method should return a System instance. A DynamicSystemProvider is used for 147 * the mapping. 148 * 149 * @param method The method to provide the System instance. 150 * @return This StateSystemMapping, so more modifications can be applied. 151 */ 152 public StateSystemMapping addMethod( Object delegate() method_a ) 153 { 154 return mCreatingState.addMethod( method_a ); 155 } 156 157 /** 158 * Maps through to the addProvider method of the SystemState that this mapping belongs to 159 * so that a fluent interface can be used when configuring entity states. 160 * 161 * @param provider The component provider to use. 162 * @return This StateSystemMapping, so more modifications can be applied. 163 */ 164 public StateSystemMapping addProvider( ISystemProvider provider_a, ClassInfo class_a ) 165 { 166 return mCreatingState.addProvider( provider_a, class_a ); 167 } 168 } 169