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(); }
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; }
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) { }