public void AddDoBehavior(TState state, Action <IUnityContainer> doAction, string doName = null)
        {
            var stateObj = this[state];
            var name     = doName ?? $"{BehavioralState.DoBehaviorName} {stateObj.DoBehaviorCount + 1}";

            if (stateObj.Editable)
            {
                stateObj.AddDoBehavior(name, doAction);
            }
            else if (RuntimeContainer.IsRegistered <object>(GlobalSynchronizerKey))
            {
                var synchronizer = RuntimeContainer.TryGetInstance <object>(GlobalSynchronizerKey);
                lock (synchronizer)
                {
                    stateObj.AddDoBehaviorUnsafe(stateObj.CreateBehavior(name, doAction));
                }
            }
            else if (BehaviorScheduler != null)
            {
                BehaviorScheduler.Schedule(() => { stateObj.AddDoBehaviorUnsafe(stateObj.CreateBehavior(name, doAction)); });
            }
            else
            {
                throw new InvalidOperationException($"{Name}: State '{stateObj.Name}' must be editable in order to add a DO behavior.");
            }
        }
示例#2
0
        public RuntimeContainer Generate(ITestProject testProject, RuntimePlatform platform, params object[] param)
        {
            RuntimeContainer runtimeContainer = RuntimeContainer.CreateContainer(Constants.TestProjectSessionId,
                                                                                 platform, _globalInfo, param);

            _runtimeContainers.Add(runtimeContainer.Session, runtimeContainer);
            return(runtimeContainer);
        }
        /// <summary>
        /// Construct a machine.
        /// If the runtime container has a trigger scheduler, asynchronous triggering is established.
        /// If the runtime container has a behavior scheduler, asynchronous behaviors are established.
        /// If no trigger scheduler is provided, then triggering is done synchronously using the provided synchronizing object.
        /// If no external synchronizer is provided, a default is supplied.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="runtimeContainer">Keys of interest: BehaviorSchedulerKey, TriggerSchedulerKey, GlobalSynchronizerKey.
        /// Types of interest: IClock.</param>
        /// <param name="logger"></param>
        protected StateMachineBase(string name, IUnityContainer runtimeContainer, ILog logger)
        {
            Name             = name;
            Logger           = new Logger(logger);
            RuntimeContainer = runtimeContainer ?? new UnityContainer();
            RuntimeContainer.RegisterInstance(Logger);

            // If a clock hasn't been provided, then register a standard system clock.
            if (!RuntimeContainer.IsRegistered <IClock>())
            {
                RuntimeContainer.RegisterInstance <IClock>(SystemClock.Instance);
            }

            if (logger == null && RuntimeContainer.IsRegistered <ILog>())
            {
                Logger.Log = RuntimeContainer.Resolve <ILog>();
            }

            if (Logger.Log != null)
            {
                Logger.Enable = true;
            }

            try
            {
                // A synchronizer is not used when a trigger scheduler is provided because the scheduler
                // already serializes work items by way of an work queue.
                TriggerScheduler = RuntimeContainer.Resolve <IScheduler>(TriggerSchedulerKey);
                Logger.Debug($"{Name}:  was initialized with asynchronous triggers.");
            }
            catch
            {
                // When configured with synchronous triggers, this machine must have a local synchronization context.
                // If a synchronizing object hasn't been provided, then register a new one.
                if (!RuntimeContainer.IsRegistered <object>(GlobalSynchronizerKey))
                {
                    Logger.Debug($"{Name}:  was initialized for synchronous operation using a default synchronization object.");
                    RuntimeContainer.RegisterInstance(GlobalSynchronizerKey, new object());
                }
                else
                {
                    Logger.Debug($"{Name}:  was initialized for synchronous operation.");
                }
            }

            _synchronizer = RuntimeContainer.TryGetInstance <object>(GlobalSynchronizerKey);

            try
            {
                BehaviorScheduler = RuntimeContainer.Resolve <IScheduler>(BehaviorSchedulerKey);
                Logger.Debug($"{Name}:  was initialized with asynchronous behaviors.");
            }
            catch
            {
                Logger.Debug($"{Name}:  was initialized with synchronous behaviors.");
            }
        }
示例#4
0
        protected void BeginExit(TripEventArgs tripArgs)
        {
            _logger.Trace($"{_context}: Exiting {GetType().Name} '{Name}'.");
            IsCurrentState = false;
            Disable();

            var exitOn = tripArgs?.FindLastTransition() as Transition;

            RuntimeContainer.RegisterInstance(typeof(IState), StateMachineBase.ExitedStateKey, this, new ExternallyControlledLifetimeManager());
            RuntimeContainer.RegisterInstance(typeof(ITransition), StateMachineBase.ExitedOnKey, exitOn, new ExternallyControlledLifetimeManager());
        }
示例#5
0
        public RuntimeContainer Generate(ISequenceGroup sequenceGroup, RuntimePlatform platform, params object[] param)
        {
            // 如果是SequenceGroup并且还有入参,则必须和包含上级TestProject一起运行
            if (null != sequenceGroup && null == sequenceGroup.Parent && 0 != sequenceGroup.Arguments.Count)
            {
                ModuleUtils.LogAndRaiseDataException(LogLevel.Error, "SequenceGroup with input arguments cannot run with out test project.", ModuleErrorCode.SequenceDataError, null, "UnexistArgumentSource");
            }
            RuntimeContainer runtimeContainer = RuntimeContainer.CreateContainer(0, platform, _globalInfo, param);

            _runtimeContainers.Add(runtimeContainer.Session, runtimeContainer);
            return(runtimeContainer);
        }
示例#6
0
        protected void BeginEntry(TripEventArgs tripArgs)
        {
            _logger.Debug($"{_context}: Entering {GetType().Name} '{Name}'.");
            var enterOn = tripArgs?.FindLastTransition() as Transition;

            IsCurrentState = true;
            RuntimeContainer.RegisterInstance(typeof(IState), StateMachineBase.EnteredStateKey, this, new ExternallyControlledLifetimeManager());
            RuntimeContainer.RegisterInstance(typeof(ITransition), StateMachineBase.EnteredOnKey, enterOn, new ExternallyControlledLifetimeManager());

            if (tripArgs != null)
            {
                tripArgs.Waypoints.AddLast(new Waypoint(this));
            }
        }
        internal IBehavior CreateBehavior(string name, Action <IUnityContainer> action)
        {
            IBehavior behavior;

            if (RuntimeContainer.IsRegistered <IScheduler>(StateMachineBase.BehaviorSchedulerKey))
            {
                behavior = new ScheduledBehavior(name, action, RuntimeContainer.Resolve <IScheduler>(StateMachineBase.BehaviorSchedulerKey));
            }
            else
            {
                behavior = new Behavior(name, action);
            }

            return(behavior);
        }
 public void FreeHost(int id)
 {
     try
     {
         lock (_operationLock)
         {
             if (_runtimeContainers.ContainsKey(id))
             {
                 RuntimeContainer runtimeContainer = _runtimeContainers[id];
                 _runtimeContainers.Remove(id);
                 runtimeContainer.Dispose();
             }
         }
     }
     catch (Exception ex)
     {
         _globalInfo.LogService.Print(LogLevel.Warn, CommonConst.PlatformLogSession, ex,
                                      "Exception raised when free host.");
     }
 }
示例#9
0
 public static void Initialize()
 {
     Current = new RuntimeContainer();
 }