Ejemplo n.º 1
0
        } // end of HandleAvailabilitiesSpecialServiceRequest

        #endregion

        #region HandleRequireDocs

        /// <summary>
        /// Handles a request to send doctors for consultation or assisting between departments
        /// </summary>
        /// <param name="del">The original request for doctors to consult or assist</param>
        /// <param name="controlUnit">Control unit that filed request for assistance or consultation</param>
        /// <param name="time">Time request was filed</param>
        /// <param name="simEngine">SimEngine responsible for simulation execution</param>
        /// <returns>True if request has been handled</returns>
        static public bool HandleRequireDocs(IDelegate del, ControlUnit controlUnit, DateTime time, ISimulationEngine simEngine)
        {
            foreach (SkillSet reqSkill in ((DelegateRequestDocsForAssisting)del).RequiredSkillSets)
            {
                List <EntityDoctor> possibleDoc = ((ControlUnitHealthCare)controlUnit).FindDoctorWithSkillSet(reqSkill);

                if (possibleDoc.Count == 0)
                {
                    break;
                }

                EntityDoctor chosenDoc = null;

                foreach (EntityDoctor doc in possibleDoc)
                {
                    if (doc.ParentControlUnit == controlUnit)
                    {
                        ActivityMove possibleMove = doc.GetPossibleMovingActivity();

                        if (possibleMove != null &&
                            (possibleMove.Destination == del.OriginControlUnit ||
                             possibleMove.Destination == doc.BaseControlUnit))
                        {
                            chosenDoc = doc;
                            break;
                        } // end if
                    }     // end if

                    if (((ControlUnitHealthCare)doc.ParentControlUnit).ControlUnitType == Enums.ControlUnitType.Inpatient)
                    {
                        chosenDoc = doc;
                        break;
                    } // end if
                }     // end foreach

                if (chosenDoc == null)
                {
                    chosenDoc = possibleDoc.First();
                }

                if (chosenDoc.ParentControlUnit == controlUnit)
                {
                    ActivityMove possibleMove = chosenDoc.GetPossibleMovingActivity();

                    if (possibleMove != null && possibleMove.Destination == chosenDoc.BaseControlUnit)
                    {
                        simEngine.RemoveScheduledEvent(possibleMove.EndEvent);
                        chosenDoc.StopCurrentActivities(time, simEngine);
                        ActivityMove move = new ActivityMove(controlUnit, chosenDoc, controlUnit, del.OriginControlUnit, del, TimeSpan.FromMinutes(1));
                        move.StartEvent.Trigger(time, simEngine);
                    } // end if
                }
                else
                {
                    controlUnit.SendDelegateTo(chosenDoc.ParentControlUnit, new DelegateSentDocForAssistedTreatment((ControlUnitHealthCare)del.OriginControlUnit, reqSkill));
                } // end if
            }     // end foreach

            return(true);
        } // end of HandleRequireDocs
Ejemplo n.º 2
0
        } // end of TriggerStartEvent

        #endregion

        #region TriggerEndEvent

        /// <summary>
        /// State change of the end event. Adds the enter event of the destination control unit
        /// or in case of pre-emption the scheduled end event is removed from the sim engine
        /// </summary>
        /// <param name="time"> Time of activity start</param>
        /// <param name="simEngine"> SimEngine the handles the activity triggering</param>
        override public void StateChangeEndEvent(DateTime time, ISimulationEngine simEngine)
        {
            if (time < EndTime)
            {
                simEngine.RemoveScheduledEvent(EndEvent);
                return;
            } // end if

            Event enterEvent = Destination.EntityEnterControlUnit(time, simEngine, MovingEntity, DelegateOrigin);

            if (enterEvent != null)
            {
                EndEvent.SequentialEvents.Add(enterEvent);
            }
        } // end of TriggerEndEvent
Ejemplo n.º 3
0
        } // end of TriggerStartEvent

        #endregion

        #region TriggerEndEvent

        /// <summary>
        /// State changes of the activities end event. Most state changes are standardized and configurable via input.
        /// </summary>
        /// <param name="time"> time of activity start</param>
        /// <param name="simEngine"> SimEngine the handles the activity triggering</param>
        override public void StateChangeEndEvent(DateTime time, ISimulationEngine simEngine)
        {
            //--------------------------------------------------------------------------------------------------
            // Some activities define the end of corresponding doctor, nurses for future reference
            //--------------------------------------------------------------------------------------------------

            #region CorrespondingStaff

            if (ActionType.DefinesCorrespondingDocEnd)
            {
                Patient.CorrespondingDoctor = null;
                ResourceSet.MainDoctor.RemovePatient(Patient);
            } // end if

            if (ActionType.DefinesCorrespondingNurseEnd)
            {
                Patient.CorrespondingNurse = null;
                ResourceSet.MainNurse.RemovePatient(Patient);
            } // end if

            #endregion

            //--------------------------------------------------------------------------------------------------
            // Occupation
            //--------------------------------------------------------------------------------------------------

            #region Occupation

            if (ResourceSet.TreatmentFacility is EntityMultiplePatientTreatmentFacility)
            {
                ((EntityMultiplePatientTreatmentFacility)ResourceSet.TreatmentFacility).HoldedEntities.Remove(Patient);
            }
            else
            {
                ResourceSet.TreatmentFacility.Occupied = false;

                //--------------------------------------------------------------------------------------------------
                // in case patient blocking is released required actions are taken
                //--------------------------------------------------------------------------------------------------
                if (ActionType.DefinesFacilitiyOccupationEnd)
                {
                    // facility is released
                    ResourceSet.TreatmentFacility.PatientBlocking = null;

                    // facility is removed from patient
                    Patient.OccupiedFacility = null;
                } // end if
            }     // end if
            #endregion

            //--------------------------------------------------------------------------------------------------
            // If treatment has doctor(s), busyFactors are assigned
            //--------------------------------------------------------------------------------------------------

            #region AssignBusyFactorsDoctors

            if (ResourceSet.MainDoctor != null)
            {
                ResourceSet.MainDoctor.BusyFactor           -= ActionType.BusyFactorDoctor;
                ResourceSet.MainDoctor.BlockedForDispatching = false;
            } // end if

            if (ResourceSet.AssistingDoctors != null)
            {
                if (ResourceSet.AssistingDoctors.Length != ActionType.BusyFactorAssistingDoctors.Length)
                {
                    throw new InvalidOperationException();
                }

                for (int i = 0; i < ResourceSet.AssistingDoctors.Length; i++)
                {
                    ResourceSet.AssistingDoctors[i].BusyFactor           -= ActionType.BusyFactorAssistingDoctors[i];
                    ResourceSet.AssistingDoctors[i].BlockedForDispatching = false;
                } // end for
            }     // end if

            #endregion

            //--------------------------------------------------------------------------------------------------
            // If treatment has nurse(s), busyFactors are assigned
            //--------------------------------------------------------------------------------------------------

            #region AssignBusyFactorsNurses

            if (ResourceSet.MainNurse != null)
            {
                ResourceSet.MainNurse.BusyFactor -= ActionType.BusyFactorNurse;
            }

            if (ResourceSet.AssistingNurses != null)
            {
                if (ResourceSet.AssistingNurses.Length != ActionType.BusyFactorAssistingNurses.Length)
                {
                    throw new InvalidOperationException();
                }

                for (int i = 0; i < ResourceSet.AssistingNurses.Length; i++)
                {
                    ResourceSet.AssistingNurses[i].BusyFactor -= ActionType.BusyFactorAssistingNurses[i];
                } // end for
            }     // end if

            #endregion

            T nextActionType = PatientPath.GetCurrentActionType();

            //--------------------------------------------------------------------------------------------------
            // Preemption
            //--------------------------------------------------------------------------------------------------

            #region Preempted

            if (!HoldingRequired)
            {
                if (Duration.Ticks > 0)
                {
                    DegreeOfCompletion += (double)(time - StartTime).Ticks / Duration.Ticks;
                }
                else
                {
                    DegreeOfCompletion = 1;
                }

                if (Math.Abs(DegreeOfCompletion - 1) > Helpers <double> .GetNumbericalPrecission())
                {
                    RequestHealthCareAction <T> req =
                        new RequestHealthCareAction <T>(Patient,
                                                        DegreeOfCompletion,
                                                        ActionType,
                                                        time,
                                                        ResourceSet);

                    ParentControlUnit.AddRequest(req);
                    simEngine.RemoveScheduledEvent(EndEvent);
                    EndEvent.SequentialEvents.Add(Patient.StartWaitingActivity(ParentDepartmentControl.WaitingAreaPatientForNextActionType(nextActionType)));
                    return;
                } // end if
            }     // end if

            #endregion

            #region NextActions

            //--------------------------------------------------------------------------------------------------
            // In case of an holding treatment the next action was already taken
            //--------------------------------------------------------------------------------------------------

            if (!HoldingRequired)
            {
                if (PatientPath.TakeNextAction(simEngine,
                                               EndEvent,
                                               time,
                                               ParentControlUnit))
                {
                    // either waiting or waiting in the treatment facility is launched
                    if (Patient.OccupiedFacility == null || Patient.OccupiedFacility.ParentDepartmentControl != ParentDepartmentControl)
                    {
                        EndEvent.SequentialEvents.Add(Patient.StartWaitingActivity(ParentDepartmentControl.WaitingAreaPatientForNextActionType(nextActionType)));
                    }
                    else
                    {
                        ActivityWaitInFacility waitInFacility = new ActivityWaitInFacility(ParentControlUnit, Patient, Patient.OccupiedFacility);
                        EndEvent.SequentialEvents.Add(waitInFacility.StartEvent);
                    } // end if
                }     // end if
                  //--------------------------------------------------------------------------------------------------
                  // Possible waiting activities are started
                  //--------------------------------------------------------------------------------------------------

                #region StartWaitingActivities

                if (ResourceSet.MainDoctor != null && ResourceSet.MainDoctor.GetCurrentActivities().Count == 1)
                {
                    EndEvent.SequentialEvents.Add(ResourceSet.MainDoctor.StartWaitingActivity(ParentDepartmentControl.WaitingRoomForStaff(ResourceSet.MainDoctor)));
                }

                if (ResourceSet.AssistingDoctors != null)
                {
                    foreach (EntityDoctor doc in ResourceSet.AssistingDoctors)
                    {
                        if (doc.GetCurrentActivities().Count == 1)
                        {
                            EndEvent.SequentialEvents.Add(doc.StartWaitingActivity(ParentDepartmentControl.WaitingRoomForStaff(doc)));
                        }
                    } // end foreach
                }     // end if

                if (ResourceSet.MainNurse != null && ResourceSet.MainNurse.GetCurrentActivities().Count == 1)
                {
                    EndEvent.SequentialEvents.Add(ResourceSet.MainNurse.StartWaitingActivity(ParentDepartmentControl.WaitingRoomForStaff(ResourceSet.MainDoctor)));
                }

                if (ResourceSet.AssistingNurses != null)
                {
                    foreach (EntityNurse nurse in ResourceSet.AssistingNurses)
                    {
                        if (nurse.GetCurrentActivities().Count == 1)
                        {
                            EndEvent.SequentialEvents.Add(nurse.StartWaitingActivity(ParentDepartmentControl.WaitingRoomForStaff(nurse)));
                        }
                    } // end foreach
                }     // end if

                #endregion
            }

            #endregion

            #region ReleaseHolding

            if (ActionType.IsHold)
            {
                foreach (EntityStaff staff in AffectedEntities.Where(p => p is EntityStaff))
                {
                    staff.OnHold = false;
                } // end foreach
                return;
            }     // end if

            #endregion
        } // end of TriggerEndEvent