Пример #1
0
 public Guid GetNextGuid()
 {
     lock (this){
         LastAssignedGuid = GuidOps.Increment(LastAssignedGuid);
         return(LastAssignedGuid);
     }
 }
Пример #2
0
            internal Guid GetNextExecutionInstanceUid()
            {
                Debug.Assert(!m_nextExecutionInstanceUid.Equals(Guid.Empty));
                Guid retval = m_nextExecutionInstanceUid;

                m_nextExecutionInstanceUid = GuidOps.Increment(m_nextExecutionInstanceUid);
                m_numberOfIterations++;
                return(retval);
            }
Пример #3
0
        protected void GetPermissionToStart(PfcExecutionContext myPfcec, StepStateMachine ssm)
        {
            PfcExecutionContext root = myPfcec;
            int ascents = m_rootHeight;

            while (ascents > 0)
            {
                root = (PfcExecutionContext)myPfcec.Parent.Payload;
                ascents--;
            }

            Exchange exchange = null;

            if (m_myIndex == 0)
            {
                //Console.WriteLine(myPfcec.Name + " is creating an exchange and injecting it into pfcec " + root.Name + " under key " + m_sequenceKey);
                exchange = new Exchange(myPfcec.Model.Executive);
                root.Add(m_sequenceKey, exchange);
            }
            else
            {
                //Console.WriteLine(myPfcec.Name + " is looking for an exchange in pfcec " + root.Name + " under key " + m_sequenceKey);
                DictionaryChange dc = new DictionaryChange(myPfcec_EntryAdded);
                while (true)
                {
                    exchange = (Exchange)root[m_sequenceKey];
                    if (exchange == null)
                    {
                        root.EntryAdded += dc;
                        m_idec           = myPfcec.Model.Executive.CurrentEventController;
                        m_idec.Suspend();
                    }
                    else
                    {
                        root.EntryAdded -= dc;
                        break;
                    }
                }
                exchange.Take(m_myKey, true); // Only indices 1,2, ... take (and wait?). Index 0 only posts.
                //Console.WriteLine(myPfcec.Name + " got the key I was looking for!");
            }
            Guid nextGuysKey = GuidOps.Increment(m_myKey);

            exchange.Post(nextGuysKey, nextGuysKey, false);
            //Console.WriteLine(myPfcec.Name + " posted the key the next guy is looking for!");
        }
Пример #4
0
        /// <summary>
        /// Creates pfc execution contexts, one per action under the step that is currently running. Each
        /// is given an instance count of zero, as a step can run its action only once, currently.
        /// </summary>
        /// <param name="parentContext">The parent context, that of the step that is currently running.</param>
        /// <param name="kids">The procedure function charts that live in the actions under the step that is currently running.</param>
        /// <param name="kidContexts">The pfc execution contexts that will correspond to the running of each of the child PFCs.</param>
        protected virtual void CreateChildContexts(PfcExecutionContext parentContext, out IProcedureFunctionChart[] kids, out PfcExecutionContext[] kidContexts)
        {
            int kidCount = MyStep.Actions.Count;

            kids        = new ProcedureFunctionChart[kidCount];
            kidContexts = new PfcExecutionContext[kidCount];
            int i = 0;

            foreach (KeyValuePair <string, IProcedureFunctionChart> kvp in MyStep.Actions)
            {
                IProcedureFunctionChart kid = kvp.Value;
                kids[i] = kid;
                Guid kidGuid = GuidOps.XOR(parentContext.Guid, kid.Guid);
                while (parentContext.Contains(kidGuid))
                {
                    kidGuid = GuidOps.Increment(kidGuid);
                }
                kidContexts[i] = new PfcExecutionContext(kid, kvp.Key, null, kidGuid, parentContext);
                kidContexts[i].InstanceCount = 0;
                i++;
            }
        }
Пример #5
0
        /// <summary>
        /// Causes the reaction to take place, if possible, in (and perform modifications to, the provided target mixture.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <returns></returns>
        public ReactionInstance React(Mixture target)
        {
            // We will handle a reaction's completion percentage/equilibrium
            // calculation by first using the reverse reaction to move all of
            // the already-existent (in proportion) products over to the
            // reactant side, and then move rxnPct % back to the product side.
            double fwdScale = double.MaxValue;
            double revScale = double.MaxValue;

            if (m_reactants.Count != 0)
            {
                foreach (ReactionParticipant rp in m_reactants)
                {
                    double howMuch = target.ContainedMassOf(rp.MaterialType);
                    if (howMuch > 0 && rp.IsCatalyst)
                    {
                        howMuch = double.MaxValue;
                    }
                    fwdScale = Math.Min(fwdScale, howMuch / rp.Mass);
                    if (s_diagnostics)
                    {
                        _Debug.WriteLine("target contains " + howMuch + " of reactant " + rp.MaterialType.Name + " so fwdScale is " + fwdScale);
                    }
                }
                if (fwdScale == double.MaxValue)
                {
                    fwdScale = 0.0;
                }
            }
            else
            {
                fwdScale = 0.0;
            }
            fwdScale *= m_rxPct;

            if (m_products.Count != 0)
            {
                foreach (ReactionParticipant rp in m_products)
                {
                    double howMuch = target.ContainedMassOf(rp.MaterialType);
                    if (howMuch > 0 && rp.IsCatalyst)
                    {
                        howMuch = double.MaxValue;
                    }
                    revScale = Math.Min(revScale, howMuch / rp.Mass);
                    if (s_diagnostics)
                    {
                        _Debug.WriteLine("target contains " + howMuch + " of product " + rp.MaterialType.Name + " so revScale is " + revScale);
                    }
                }

                if (revScale == double.MaxValue)
                {
                    revScale = 0.0;
                }
            }
            else
            {
                revScale = 0.0;
            }
            revScale *= (1 - m_rxPct);

            // If we're going to undo and then redo the same thing, the reaction didn't happen.
            if ((fwdScale == 0.0 && revScale == 0.0) || (Math.Abs(fwdScale - revScale) < 0.000001))
            {
                if (s_diagnostics)
                {
                    _Debug.WriteLine("Reaction " + Name + " won't happen in mixture " + target);
                }
                return(null);
            }

            if (s_diagnostics)
            {
                _Debug.WriteLine("Mixture is " + target);
            }
            if (s_diagnostics)
            {
                _Debug.WriteLine("Reaction " + Name + " is happening. " + ToString());
            }

            ReactionGoingToHappenEvent?.Invoke(this, target);
            target.ReactionGoingToHappen(this);

            Mixture mixtureWas = (Mixture)target.Clone();

            target.SuspendChangeEvents();

            if (s_diagnostics)
            {
                _Debug.WriteLine(revScale > 0.0 ? "Performing reverse reaction..." : "Reverse reaction won't happen.");
            }
            if (revScale > 0.0)
            {
                React(target, m_products, m_reactants, revScale);
            }

            if (s_diagnostics)
            {
                _Debug.WriteLine(fwdScale > 0.0 ? "Performing forward reaction..." : "Forward reaction won't happen.");
            }
            if (fwdScale > 0.0)
            {
                React(target, m_reactants, m_products, fwdScale * m_rxPct);
            }

            // Percent completion is pulled out of the Reaction object.

            ReactionInstance ri = new ReactionInstance(this, fwdScale, revScale, m_nextRiGuid);

            m_nextRiGuid = GuidOps.Increment(m_nextRiGuid);

            ReactionHappenedEvent?.Invoke(ri);
            target.ReactionHappened(ri);

            target.AddEnergy(m_energy * (fwdScale - revScale));

            target.ResumeChangeEvents(!mixtureWas.ToString("F2", "F3").Equals(target.ToString("F2", "F3"))); // Only emit summary events if the mixture has changed.

            return(ri);
        }