Exemplo n.º 1
0
        /// <summary>
        /// Registers a transition into this group.
        /// </summary>
        /// <param name="transition">The transition you want to register.</param>
        /// <param name="type">The type of the registered transition.</param>
        public void RegisterTransition(PNTransition transition, PetriNet.PNTransitionType type)
        {
            this.transitions.Add(transition, type);

            /// Every transition is fireable at the beginning.
            TransitionBecameFireable(transition, true);
        }
Exemplo n.º 2
0
        /// <see cref="PetriNet.AttachThread"/>
        public void AttachThread(RCSet <PNTransition> extTransitions, Dictionary <PNTransition, PetriNet.PNCallback> callbacks)
        {
            if (this.threadAttached.WaitOne(0))
            {
                try
                {
                    /// Check the parameters.
                    CheckThreadAttachParameters(extTransitions, callbacks);

                    /// First we only allowed to fire external transitions.
                    PetriNet.PNTransitionType stage = PetriNet.PNTransitionType.EXTERNAL;

                    /// Start the thread control loop.
                    while (true)
                    {
                        /// Wait for a fireable transition.
                        this.releaseEvent.WaitOne();

                        lock (this.lockObject)
                        {
                            while (this.fireableTransitions.Count > 0)
                            {
                                if (stage == PetriNet.PNTransitionType.EXTERNAL)
                                {
                                    /// Find the first fireable external transition
                                    PNTransition firstExtTr = null;
                                    foreach (PNTransition fireableTr in this.fireableTransitions)
                                    {
                                        if (this.transitions[fireableTr] == PetriNet.PNTransitionType.CALLBACK)
                                        {
                                            throw new PetriNetException("Invalid type of fireable transition detected!");
                                        }

                                        if (firstExtTr == null && this.transitions[fireableTr] == PetriNet.PNTransitionType.EXTERNAL &&
                                            extTransitions.Contains(fireableTr))
                                        {
                                            firstExtTr = fireableTr;
                                        }
                                    }

                                    /// Fire the transition.
                                    if (firstExtTr != null)
                                    {
                                        firstExtTr.Fire();
                                        stage = PetriNet.PNTransitionType.INTERNAL;
                                    }
                                    else
                                    {
                                        /// No fireable external transitions have been found.
                                        break;
                                    }
                                }
                                else if (stage == PetriNet.PNTransitionType.INTERNAL)
                                {
                                    /// Find the first fireable internal transition or a callback transition
                                    PNTransition trToFire = null;
                                    foreach (PNTransition fireableTr in this.fireableTransitions)
                                    {
                                        if (this.transitions[fireableTr] == PetriNet.PNTransitionType.INTERNAL)
                                        {
                                            if (trToFire == null)
                                            {
                                                trToFire = fireableTr;
                                            }
                                        }
                                        else if (this.transitions[fireableTr] == PetriNet.PNTransitionType.CALLBACK)
                                        {
                                            if (this.fireableTransitions.Count == 1)
                                            {
                                                /// End of thread attach: fire the transition, invoke the callback and return.
                                                fireableTr.Fire();
                                                callbacks[fireableTr](fireableTr.Index);

                                                /// Detach the thread and exit from the function.
                                                this.threadAttached.Release();
                                                return;
                                            }
                                            else
                                            {
                                                throw new PetriNetException("Invalid state during a thread attach!");
                                            }
                                        }
                                        else
                                        {
                                            throw new PetriNetException("Invalid type of fireable transition detected!");
                                        }
                                    }

                                    if (trToFire != null)
                                    {
                                        trToFire.Fire();
                                    }
                                    else
                                    {
                                        /// No fireable internal transitions have been found.
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                catch
                {
                    /// Error occured --> Detach the thread and re-throw the exception.
                    this.threadAttached.Release();
                    throw;
                }
            }
            else
            {
                throw new PetriNetException("You cannot attach more than one threads to the same transition group at the same time!");
            }
        }