コード例 #1
0
ファイル: Metronomes.cs プロジェクト: sjvannTMU/Sage
        /// <summary>
        /// Creates a metronome with the specified parameters. It uses a static factory method
        /// because if there is already an existing metronome with the same parameters, that
        /// metronome is returned, rather than creating another one - after all, the whole
        /// point is to avoid a large number of tick events on the executive's event list.
        /// </summary>
        /// <param name="exec">The executive that will issue the ticks.</param>
        /// <param name="startAt">The time at which the metronome's ticks are to start.</param>
        /// <param name="finishAfter">The time at which the metronome's ticks are to stop.</param>
        /// <param name="period">The period of the ticking.</param>
        /// <returns>A metronome that meets the criteria.</returns>
        public static Metronome_Simple CreateMetronome(IExecutive exec, DateTime startAt, DateTime finishAfter, TimeSpan period)
        {
            Metronome_Simple retval = null;

            foreach (Metronome_Simple ms in m_channels)
            {
                if (ms.Executive.Equals(exec) && ms.StartAt.Equals(startAt) && ms.FinishAt.Equals(finishAfter) && ms.Period.Equals(period))
                {
                    retval = ms;
                    break;
                }
            }
            if (retval == null)
            {
                retval = new Metronome_Simple(exec, startAt, finishAfter, period);
                m_channels.Add(exec, retval);
                exec.ExecutiveFinished += exec_ExecutiveFinished;
            }
            return(retval);
        }
コード例 #2
0
ファイル: Model.cs プロジェクト: sjvannTMU/Sage
        /// <summary>
        /// Adds an error to the model, and iterates over all of the error handlers,
        /// allowing each in turn to respond to the error. As soon as any errorHandler
        /// indicates that it has HANDLED the error (by returning true from 'HandleError'),
        /// the error is cleared, and further handlers are not called.
        /// </summary>
        /// <param name="theError">The error that is to be added to the model's error list.</param>
        /// <returns>True if the error was successfully added to the model, false if it was cleared by a handler.</returns>
        public bool AddError(IModelError theError)
        {
            foreach (IErrorHandler errorHandler in ErrorHandlers)
            {
                if (errorHandler.HandleError(theError))
                {
                    if (ErrorCleared != null)
                    {
                        ErrorCleared(theError);
                    }
                    return(false);
                }
            }

            if (theError.Target == null)
            {
                throw new ApplicationException("An error was added to the model with its target set to null. This is illegal.");
            }
            m_errors.Add(theError.Target, theError);
            if (ErrorHappened != null)
            {
                ErrorHappened(theError);
            }

            // IF WE ARE TRANSITIONING, We are not going to abort on the
            // addition of an error, since there may be intermediate situations
            // where an error is okay. If a 'fail on the first sign of an error'
            // behavior is desired, then the developer can hook the
            // 'ErrorHappened' event. Instead, we will have the model register a
            // handler as the last thing done on attempting a transition, to
            // check that we are error-free. But, IF WE ARE NOT TRANSITIONING,
            // then anything that causes an error will abort the model, and move
            // it back to the 'Idle' state.
            if (!StateMachine.IsTransitioning)
            {
                if (s_diagnostics)
                {
                    _Debug.WriteLine("Model.Abort() requested as a result of the addition of an error : " + theError);
                }
                if (!StateMachine.State.Equals(GetAbortEnum()))
                {
                    StateMachine.DoTransition(GetAbortEnum());
                }
            }
            return(true);
        }
コード例 #3
0
        private ITuple BlockingRead(object key)
        {
            lock ( m_ts ) {
                while (true)
                {
                    ITuple tuple = NonBlockingRead(key);
                    if (tuple != null)
                    {
                        return(tuple);
                    }

                    #region Wait 'til next post against this key.
                    IDetachableEventController idec = m_exec.CurrentEventController;
                    m_waitersToRead.Add(key, idec);
                    idec.Suspend();
                    #endregion
                }
            }
        }
コード例 #4
0
        public void Post(ITuple tuple)
        {
            m_ts.Add(tuple.Key, tuple);
            tuple.OnPosted(this);
            if (TuplePosted != null)
            {
                TuplePosted(this, tuple);
            }
            IList wtr = m_waitersToRead[tuple.Key];
            IList wtt = m_waitersToTake[tuple.Key];

            m_waitersToRead.Clear(tuple.Key);
            m_waitersToTake.Clear(tuple.Key);
            foreach (IDetachableEventController idec in wtr)
            {
                idec.Resume(double.MaxValue);
            }
            foreach (IDetachableEventController idec in wtt)
            {
                idec.Resume(double.MaxValue - double.Epsilon);
            }
        }