public void ChangeState(T newState) { if (m_StateLookup == null) { throw new Exception("States have not been configured, please call initialized before trying to set state"); } if (!m_StateLookup.ContainsKey(newState)) { throw new Exception("No state with the name " + newState + " can be found. Please make sure you are called the correct type the statemachine was initialized with"); } StateMapping nextState = m_StateLookup[newState]; if (CurrentStateMap == nextState) { return; } CurrentStateMap?.ExitCall(); m_LastState = CurrentStateMap; CurrentStateMap = nextState; if (CurrentStateMap != null) { CurrentStateMap.EnterCall(); OnChanged((T)CurrentStateMap.State); } }
protected State() { //Define States Array values = Enum.GetValues(typeof(T)); if (values.Length < 1) { throw new ArgumentException("Enum provided to create this state must have at least 1 visible definition"); } m_StateLookup = new Dictionary <object, StateMapping>(); for (int i = 0; i < values.Length; i++) { StateMapping mapping = new StateMapping((Enum)values.GetValue(i)); m_StateLookup.Add(mapping.State, mapping); } //Reflect methods MethodInfo[] methods = GetType().GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic); //Bind methods to states char[] separator = "_".ToCharArray(); for (int i = 0; i < methods.Length; i++) { if (methods[i].GetCustomAttributes(typeof(CompilerGeneratedAttribute), true).Length != 0) { continue; } string[] names = methods[i].Name.Split(separator); //Ignore functions without an underscore if (names.Length <= 1) { continue; } Enum key; try { key = (Enum)Enum.Parse(typeof(T), names[0]); } catch (ArgumentException) { //Not an method as listed in the state enum continue; } StateMapping targetState = m_StateLookup[key]; switch (names[1]) { case "Enter": targetState.EnterCall = CreateDelegate <Action>(methods[i], this); break; case "Exit": targetState.ExitCall = CreateDelegate <Action>(methods[i], this); break; case "Update": targetState.Update = CreateDelegate <Action <float> >(methods[i], this); break; } } //Create nil state mapping CurrentStateMap = new StateMapping(null); }