Пример #1
0
        private static void Add(Type type, List <ISystemAction>[] groupActions)
        {
            ISystemAction systemAction = GetSystemAction(type);

            LE_Log.Log.Info("ActionRegister", "ActionId: {0}  ActionName: {1}", systemAction.Id, systemAction.Name);

            if ((Attribute.GetCustomAttribute(type, typeof(EntityActionAttribute)) is EntityActionAttribute actionAttribute))
            {
                groupActions[EntityTypeManager.GetEntityTypeId(actionAttribute.Type)].Add(systemAction);
            }
Пример #2
0
        /// <summary>
        /// Sends the given <see cref="ISystemAction"/> command.
        /// </summary>
        public void SendSystemCommand(ISystemAction systemCommand)
        {
            lock (locker)
            {
                // Pre-filter incompatible types.
                if (systemCommand is null)
                {
                    throw new ArgumentNullException(nameof(systemCommand));
                }
                if (!SystemCommands.Contains(systemCommand.GetType()))
                {
                    return;
                }

                Log.Debug(this, nameof(SendSystemCommand) + ": " + systemCommand);
                ExecuteSystemCommand?.Invoke(systemCommand);
            }
        }
Пример #3
0
        /// <summary>
        /// Handles the given <see cref="ISystemAction"/> event.
        /// </summary>
        public void HandleSystemEvent(ISystemAction systemEvent)
        {
            lock (locker)
            {
                // Pre-filter incompatible types.
                if (systemEvent is null)
                {
                    throw new ArgumentNullException(nameof(systemEvent));
                }
                if (!SystemEvents.Contains(systemEvent.GetType()))
                {
                    return;
                }

                Log.Debug(this, nameof(HandleSystemEvent) + ": " + systemEvent);
                events.Enqueue(systemEvent);

                // This must now be called manually from the thread that should perform the operations.
                //CheckSystems();
            }
        }
Пример #4
0
        /// <summary>
        /// Checks the <see cref="inputs"/> and <see cref="events"/> queues.
        /// Determines if the <see cref="CurrentSystem"/> can be advanced.
        /// Determines if one of the <see cref="Systems"/> can be started.
        /// </summary>
        public void CheckSystems()
        {
            Log.Debug(this, nameof(CheckSystems) + " inputs: " + inputs.Count + " commands: " + events.Count + "\n" + this);

            bool transitioned = false;

            // If proactive transitions are possible, trigger them!
            if (!transitioned)
            {
                HashSet <Tuple <TransitionSystem, ProactiveTransition> > proactives = PossibleProactiveTransitions();
                if (proactives.Count > 0)
                {
                    Log.Debug(this, "Possible proactive transitions: " + string.Join(", ", proactives.Select(x => x.Item1.ModelAction.Name + ": " + x.Item2).ToArray()));
                    Tuple <TransitionSystem, ProactiveTransition> selected = proactives.Random();
                    Log.Debug(this, "Selected proactive transition: " + selected.Item1.ModelAction.Name + ": " + selected.Item2);
                    IAction generated = ExecuteProactiveTransition(selected);

                    if (generated is ModelAction modelOutput)
                    {
                        SendModelOutput(modelOutput);
                    }
                    else if (generated is ISystemAction systemCommand)
                    {
                        SendSystemCommand(systemCommand);
                    }

                    transitioned = true;
                }
            }

            // If reactive transitions are possible, due to system events, trigger them!
            if (!transitioned)
            {
                if (events.Count > 0)
                {
                    ISystemAction systemEvent = events.Dequeue();
                    Log.Debug(this, "Dequeueing system event: " + systemEvent);
                    HashSet <Tuple <TransitionSystem, ReactiveTransition> > reactives = PossibleReactiveTransitions(systemEvent);
                    if (reactives.Count > 0)
                    {
                        Log.Debug(this, "Possible reactive transitions: " + string.Join(", ", reactives.Select(x => x.Item1.ModelAction.Name + ": " + x.Item2).ToArray()));
                        Tuple <TransitionSystem, ReactiveTransition> selected = reactives.Random();
                        Log.Debug(this, "Selected reactive transition: " + selected.Item1.ModelAction.Name + ": " + selected.Item2);
                        ExecuteReactiveTransition(systemEvent, selected);

                        transitioned = true;
                    }
                    else
                    {
                        // Since all system events are being looped through this, not being able to handle one is not an error per se. (TPE)
                        Log.Warn(this, "No reactive transition possible for system event: " + systemEvent);
                    }
                }
            }

            // If reactive transitions are possible, due to model inputs, trigger them!
            if (!transitioned)
            {
                if (inputs.Count > 0)
                {
                    ModelAction modelInput = inputs.Dequeue();
                    Log.Debug(this, "Dequeueing model input: " + modelInput);
                    HashSet <Tuple <TransitionSystem, ReactiveTransition> > reactives = PossibleReactiveTransitions(modelInput);
                    if (reactives.Count > 0)
                    {
                        Log.Debug(this, "Possible reactive transitions: " + string.Join(", ", reactives.Select(x => x.Item1.ModelAction.Name + ": " + x.Item2).ToArray()));
                        Tuple <TransitionSystem, ReactiveTransition> selected = reactives.Random();
                        Log.Debug(this, "Selected reactive transition: " + selected.Item1.ModelAction.Name + ": " + selected.Item2);
                        ExecuteReactiveTransition(modelInput, selected);

                        transitioned = true;
                    }
                    else
                    {
                        Log.Error(this, "No reactive transition possible for model input: " + modelInput);
                    }
                }
            }

            // If a transition was taken, re-evaluate immediately!
            if (transitioned)
            {
                if (CurrentSystem.CurrentState == CurrentSystem.InitialState)
                {
                    Log.Debug(this, "System has looped: " + CurrentSystem);
                    CurrentSystem = null;
                }
                CheckSystems();
            }
            // If no transition was taken (due to ignored input or event), we still need to check the next input or event.
            else if (inputs.Count > 0 || events.Count > 0)
            {
                CheckSystems();
            }
        }