예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }