/// <summary> /// Add a state using reflection to retrieve the approriate methods on the Entity. /// For example, a key with a value of "Idle" will retrieve the methods "EnterIdle" "UpdateIdle" and "ExitIdle" automatically. /// </summary> /// <param name="key">The key to reference the State with.</param> public void AddState(TState key, Entity e = null) { if (e == null) { e = Entity; // Use the Component's Entity if no entity specified. } if (states.ContainsKey(key)) { return; // Dont add duplicate states. } var state = new State(); var name = key.ToString(); //Using reflection to find all the appropriate functions! MethodInfo mi; mi = e.GetType().GetMethod("Enter" + name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (mi == null) { e.GetType().GetMethod("Enter" + name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); } if (mi != null) { state.OnEnter = (Action)Delegate.CreateDelegate(typeof(Action), e, mi); } mi = e.GetType().GetMethod("Update" + name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (mi == null) { e.GetType().GetMethod("Update" + name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); } if (mi != null) { state.OnUpdate = (Action)Delegate.CreateDelegate(typeof(Action), e, mi); } mi = e.GetType().GetMethod("Exit" + name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (mi == null) { e.GetType().GetMethod("Exit" + name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); } if (mi != null) { state.OnExit = (Action)Delegate.CreateDelegate(typeof(Action), e, mi); } states.Add(key, state); }
/// <summary> /// Add a state and automatically grab functions by their name. /// </summary> /// <param name="names">The common name in all the functions, like "Walking" in "UpdateWalking" "EnterWalking" and "ExitWalking"</param> /// <returns>The id to refer to the state.</returns> public void AddState(params string[] names) { foreach (var name in names) { if (Entity == null) { throw new ArgumentException("State Machine must be Added to an Entity first!"); } var state = new State(); //Using reflection to find all the appropriate functions! MethodInfo mi; mi = Entity.GetType().GetMethod("Enter" + name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (mi != null) { state.OnEnter = (Action)Delegate.CreateDelegate(typeof(Action), Entity, mi); } mi = Entity.GetType().GetMethod("Update" + name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (mi != null) { state.OnUpdate = (Action)Delegate.CreateDelegate(typeof(Action), Entity, mi); } mi = Entity.GetType().GetMethod("Exit" + name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (mi != null) { state.OnExit = (Action)Delegate.CreateDelegate(typeof(Action), Entity, mi); } //Using reflection to assign the id to the right property FieldInfo fi; fi = Entity.GetType().GetField("state" + name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); fi.SetValue(Entity, nextStateId); AddState(state); } }