private void ThreadRoutine()
        {
            while (canRun)
            {
                //Make sure that we can run.
                mutex.WaitOne();
                if (!canRun)
                {
                    mutex.ReleaseMutex();
                    return;
                }

                //Grab a simulator if one is available.
                if (jobList.Count > 0)
                {
                    simulator = jobList[0];
                    jobList.RemoveAt(0);
                }
                else
                {
                    simulator = null;
                }

                //Done with mutex for now
                mutex.ReleaseMutex();

                //Run the simulator if we have one
                if (simulator != null)
                {
                    //Run a cycle until we are told to exit.
                    while (!simulator.exitSimulation && canRun)
                    {
                        simulator.RunSimulatorCycle();

                        //Check for errors
                        if (simulator.exception != null)
                        {
                            mutex.WaitOne();
                            OnSimulatorException?.Invoke(simulator, simulator.exception);
                            mutex.ReleaseMutex();
                            break;
                        }

                        //Inform delegate that cycle is complete.
                        mutex.WaitOne();
                        OnSimulatorCycleComplete?.Invoke(simulator);

                        //Make sure that we can run.
                        if (!canRun || simulator.exitSimulation)
                        {
                            mutex.ReleaseMutex();
                            OnSimulationComplete?.Invoke(simulator);
                            simulator = null;
                            break;
                        }
                        mutex.ReleaseMutex();
                    }
                }
            }
        }
        /// <summary>
        /// Adds a simulator to the job list.
        /// </summary>
        /// <param name="simulator">The SimSnacks simulator to add to the list.</param>
        public void AddSimulatorJob(SimSnacks simulator)
        {
            mutex.WaitOne();

            jobList.Add(simulator);

            mutex.ReleaseMutex();
        }
        /// <summary>
        /// Handles the completion of a thread's simulation.
        /// </summary>
        /// <param name="simulator">The simulator that just finished.</param>
        private void OnThreadSimulationComplete(SimSnacks simulator)
        {
            //Record the vessel and its consumed resource durations.
            mutex.WaitOne();
            if (vesselResourceDurations.ContainsKey(simulator.vessel))
            {
                vesselResourceDurations.Remove(simulator.vessel);
            }
            vesselResourceDurations.Add(simulator.vessel, simulator.consumedResourceDurations);

            if (simulator.convertersAssumedActive && !convertersAssumedActive.ContainsKey(simulator.vessel))
            {
                convertersAssumedActive.Add(simulator.vessel, true);
            }

            mutex.ReleaseMutex();
        }
Exemple #4
0
        private void OnSimulationComplete(SimSnacks simSnacks)
        {
            simulationComplete = true;

            //Snackshot list
            int       count = snackshots.Count;
            Snackshot snackshot;

            for (int index = 0; index < count; index++)
            {
                snackshot = snackshots[index];

                if (simSnacks.consumedResourceDurations.ContainsKey(snackshot.resourceName))
                {
                    snackshot.isSimulatorRunning     = false;
                    snackshot.estimatedTimeRemaining = simSnacks.consumedResourceDurations[snackshot.resourceName];
                }
            }

            convertersAssumedActive = simSnacks.convertersAssumedActive;
        }
Exemple #5
0
        private void setupSimulatorIfNeeded()
        {
            //If the vessel parts have changed or crew count has changed then run a new simulation.
            ShipConstruct      ship     = EditorLogic.fetch.ship;
            VesselCrewManifest manifest = CrewAssignmentDialog.Instance.GetManifest();
            int consumerCount           = SnacksScenario.Instance.resourceProcessors.Count;
            List <BaseResourceProcessor> resourceProcessors = SnacksScenario.Instance.resourceProcessors;
            List <ProcessedResource>     consumerResources;
            int       resourceCount;
            int       resourceIndex;
            string    resourceName;
            Snackshot snackshot;

            if (manifest != null)
            {
                currentCrewCount = manifest.CrewCount;
            }

            //Get crew capacity
            crewCapacity = 0;
            int partCrewCapacity = 0;

            for (int index = 0; index < ship.parts.Count; index++)
            {
                if (ship.parts[index].partInfo.partConfig.HasValue("CrewCapacity"))
                {
                    int.TryParse(ship.parts[index].partInfo.partConfig.GetValue("CrewCapacity"), out partCrewCapacity);
                    crewCapacity += partCrewCapacity;
                }
            }

            if (ship.parts.Count != partCount || currentCrewCount != previousCrewCount)
            {
                previousCrewCount = currentCrewCount;
                partCount         = ship.parts.Count;

                //No parts? Nothing to do.
                if (partCount == 0)
                {
                    snackshots.Clear();
                    simulationResults  = "<color=yellow><b>Vessel has no crewed parts to simulate.</b></color>";
                    simulationComplete = false;
                }
                else if (currentCrewCount == 0)
                {
                    snackshots.Clear();
                    simulationResults  = "<color=yellow><b>Vessel needs crew to run simulation.</b></color>";
                    simulationComplete = false;
                }

                //Clear existing simulation if any
                snackThread.ClearJobs();

                SimSnacks simSnacks = SimSnacks.CreateSimulator(ship);
                if (simSnacks != null)
                {
                    simulationComplete = false;
                    simulationResults  = "<color=white><b>Simulation in progress, please wait...</b></color>";
                    snackshots.Clear();

                    //Get consumer resource lists
                    for (int consumerIndex = 0; consumerIndex < consumerCount; consumerIndex++)
                    {
                        resourceProcessors[consumerIndex].AddConsumedAndProducedResources(currentCrewCount, simSnacks.secondsPerCycle, simSnacks.consumedResources, simSnacks.producedResources);

                        //First check input list for resources to add to the snapshots window
                        consumerResources = resourceProcessors[consumerIndex].inputList;
                        resourceCount     = consumerResources.Count;
                        for (resourceIndex = 0; resourceIndex < resourceCount; resourceIndex++)
                        {
                            resourceName = consumerResources[resourceIndex].resourceName;

                            if (consumerResources[resourceIndex].showInSnapshot && simSnacks.resources.ContainsKey(resourceName))
                            {
                                snackshot = new Snackshot();
                                snackshot.showTimeRemaining = true;
                                snackshot.resourceName      = consumerResources[resourceIndex].resourceName;
                                snackshot.amount            = simSnacks.resources[resourceName].amount;
                                snackshot.maxAmount         = simSnacks.resources[resourceName].maxAmount;

                                //Add to snackshots
                                snackshots.Add(snackshot);
                            }
                        }

                        //Next check outputs
                        consumerResources = resourceProcessors[consumerIndex].outputList;
                        resourceCount     = consumerResources.Count;
                        for (resourceIndex = 0; resourceIndex < resourceCount; resourceIndex++)
                        {
                            resourceName = consumerResources[resourceIndex].resourceName;

                            if (consumerResources[resourceIndex].showInSnapshot && simSnacks.resources.ContainsKey(resourceName))
                            {
                                snackshot = new Snackshot();
                                snackshot.showTimeRemaining = true;
                                snackshot.resourceName      = consumerResources[resourceIndex].resourceName;
                                snackshot.amount            = simSnacks.resources[resourceName].amount;
                                snackshot.maxAmount         = simSnacks.resources[resourceName].maxAmount;

                                //Add to snackshots
                                snackshots.Add(snackshot);
                            }
                        }
                    }

                    //Give mods a chance to add custom converters not already covered by Snacks.
                    SimulatorContext context = new SimulatorContext();
                    context.shipConstruct       = ship;
                    context.simulatedVesselType = SimulatedVesselTypes.simEditor;
                    SnacksScenario.onSimulatorCreated.Fire(simSnacks, context);

                    //Now start the simulation
                    snackThread.AddJob(simSnacks);
                }
                else
                {
                    simulationResults = "<color=yellow><b>Vessel has no crewed parts to simulate.</b></color>";
                }
            }
        }
 /// <summary>
 /// Adds a simulator job to the job list.
 /// </summary>
 /// <param name="simSnacks">The simulator to add to the jobs list.</param>
 public void AddJob(SimSnacks simSnacks)
 {
     mutex.WaitOne();
     jobList.Add(simSnacks);
     mutex.ReleaseMutex();
 }
 /// <summary>
 /// Handles the exception generated by a simulator.
 /// </summary>
 /// <param name="simulator">The simulator that generated the exception.</param>
 /// <param name="ex">The Exception generated.</param>
 private void OnSimulatorException(SimSnacks simulator, Exception ex)
 {
 }
 /// <summary>
 /// Handles completion of a thread's simulation cycle.
 /// </summary>
 /// <param name="simulator">The simulator that just completed its cycle.</param>
 private void OnThreadSimulatorCycleComplete(SimSnacks simulator)
 {
 }