Example #1
0
        internal override void End()
        {
            OnEnd();
            var finalState = FinalState;

            Debug.Assert(!InFinalState && (FinalStatesMask & finalState) > 0);
            // Final state must be assigned before triggering conditions, because they will use it
            // to determine whether or not undo the events they control.
            SetFinalState(finalState);
            //
            if (_callbacks != null)
            {
                // Debug.Assert(_callbacks.Count > 0);
                // Assert above is potentially false, since the user may call
                // Clear on _callbacks, as it is an ICollection.
                foreach (var callback in _callbacks)
                {
                    callback(this as TEv);
                }
                _callbacks = null;
            }
            // Following piece of code is optimezed for cases in which an event
            // belongs to a single event, which represents the great majority of situations.
            if (Conditions != null)
            {
                Debug.Assert(Conditions.Count > 0);
                // Triggers all conditions to which this event belongs.
                IParentCondition condition;
                if (Conditions.Count == 1 && !(condition = Conditions.First).Succeeded)
                {
                    condition.Trigger(this);
                }
                else
                {
                    var en = Conditions.GetEnumerator();
                    while (en.MoveNext())
                    {
                        if (!(condition = en.Current).Succeeded)
                        {
                            condition.Trigger(this);
                        }
                    }
                }
                Conditions = null;
            }
            // Following piece of code is optimezed for cases in which an event
            // is "yielded" by a single process, which represents the great majority of situations.
            if (Subscribers != null)
            {
                Debug.Assert(Subscribers.Count > 0);
                // Reschedules all processes which are not completed yet.
                // The "where" clause filters yielders, so that only those processes
                // which are still running are picked up for scheduling.
                SimProcess subscriber;
                if (Subscribers.Count == 1 && (subscriber = Subscribers.First).IsAlive)
                {
                    Env.ScheduleProcess(subscriber);
                }
                else
                {
                    var en = Subscribers.GetEnumerator();
                    while (en.MoveNext())
                    {
                        if ((subscriber = en.Current).IsAlive)
                        {
                            Env.ScheduleProcess(subscriber);
                        }
                    }
                }
                Subscribers = null;
            }
        }