public Guid GetNextGuid() { lock (this){ LastAssignedGuid = GuidOps.Increment(LastAssignedGuid); return(LastAssignedGuid); } }
internal Guid GetNextExecutionInstanceUid() { Debug.Assert(!m_nextExecutionInstanceUid.Equals(Guid.Empty)); Guid retval = m_nextExecutionInstanceUid; m_nextExecutionInstanceUid = GuidOps.Increment(m_nextExecutionInstanceUid); m_numberOfIterations++; return(retval); }
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!"); }
/// <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++; } }
/// <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); }