Skip to content

Commit

Permalink
Fix a stupid race condition that I fixed in the past but clealy did n…
Browse files Browse the repository at this point in the history
…ot commit...

And some inital work on the use of OnWaitForFixedUpdate
  • Loading branch information
sarbian committed Jul 17, 2017
1 parent 446a642 commit 57be08f
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 15 deletions.
4 changes: 4 additions & 0 deletions MechJeb2/ComputerModule.cs
Expand Up @@ -113,6 +113,10 @@ public virtual void OnFixedUpdate()
{
}

public virtual void OnWaitForFixedUpdate()
{
}

public virtual void OnUpdate()
{
}
Expand Down
5 changes: 3 additions & 2 deletions MechJeb2/MechJebModuleInfoItems.cs
Expand Up @@ -844,11 +844,12 @@ public void AllStageStats()
MechJebModuleStageStats stats = core.GetComputerModule<MechJebModuleStageStats>();
if (Event.current.type == EventType.Layout)
{
vacStats = stats.vacStats;
atmoStats = stats.atmoStats;
stats.RequestUpdate(this);
}

vacStats = stats.vacStats;
atmoStats = stats.atmoStats;

Profiler.EndSample();

Profiler.BeginSample("AllStageStats.UI1");
Expand Down
73 changes: 60 additions & 13 deletions MechJeb2/MechJebModuleStageStats.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;

namespace MuMech
{
Expand All @@ -18,21 +19,35 @@ public class MechJebModuleStageStats : ComputerModule
public FuelFlowSimulation.Stats[] atmoStats = { };
public FuelFlowSimulation.Stats[] vacStats = { };


// Those are used to store the next result from the thread since we must move result
// to atmoStats/vacStats only in the main thread.
private FuelFlowSimulation.Stats[] newAtmoStats;
private FuelFlowSimulation.Stats[] newVacStats;
private bool resultReady = false;

public void RequestUpdate(object controller, bool wait = false)
{
users.Add(controller);
updateRequested = true;

if (HighLogic.LoadedSceneIsEditor && editorBody != null)
IsResultReady();

// In the editor this is our only entry point
if (HighLogic.LoadedSceneIsEditor)
{
if (TryStartSimulation() && wait)
TryStartSimulation();
}

// wait means the code needs some result to run so we wait if we do not have any result yet
if (wait && atmoStats.Length == 0 && (simulationRunning || TryStartSimulation()))
{
while (simulationRunning)
{
while (simulationRunning)
{
// wait for a sim to be ready. Risked ?
Thread.Sleep(1);
}
// wait for a sim to be ready. Risked ?
Thread.Sleep(1);
}
IsResultReady();
}
}

Expand Down Expand Up @@ -96,12 +111,36 @@ public override void OnModuleDisabled()

public override void OnFixedUpdate()
{
// Check if we have a result ready from the previous physic frame
IsResultReady();

TryStartSimulation();
}

public bool TryStartSimulation()
public override void OnWaitForFixedUpdate()
{
// Check if we managed to get a result while the physic frame was running
IsResultReady();
}

public override void OnUpdate()
{
IsResultReady();
}

private void IsResultReady()
{
if ((HighLogic.LoadedSceneIsEditor || (vessel != null && vessel.isActiveVessel)) && !simulationRunning)
if (resultReady)
{
atmoStats = newAtmoStats;
vacStats = newVacStats;
resultReady = false;
}
}

private bool TryStartSimulation()
{
if (!simulationRunning && ((HighLogic.LoadedSceneIsEditor && editorBody != null) || (vessel != null && vessel.isActiveVessel)))
{
//We should be running simulations periodically, but one is not running right now.
//Check if enough time has passed since the last one to start a new one:
Expand All @@ -128,9 +167,11 @@ public bool TryStartSimulation()

protected void StartSimulation()
{
Profiler.BeginSample("StartSimulation");
try
{
simulationRunning = true;
resultReady = false;
stopwatch.Start(); //starts a timer that times how long the simulation takes

//Create two FuelFlowSimulations, one for vacuum and one for atmosphere
Expand All @@ -149,12 +190,18 @@ protected void StartSimulation()
vessel.UpdateResourceSetsIfDirty();
}

Profiler.BeginSample("StartSimulation_Init");

sims[0].Init(parts, dVLinearThrust);
sims[1].Init(parts, dVLinearThrust);

Profiler.EndSample();

//Run the simulation in a separate thread
ThreadPool.QueueUserWorkItem(RunSimulation, sims);
//Profiler.BeginSample("StartSimulation_Run");
//RunSimulation(sims);
//Profiler.EndSample();
}
catch (Exception e)
{
Expand All @@ -169,6 +216,7 @@ protected void StartSimulation()
stopwatch.Start();
simulationRunning = false;
}
Profiler.EndSample();
}

protected void RunSimulation(object o)
Expand All @@ -182,10 +230,8 @@ protected void RunSimulation(object o)
double mach = HighLogic.LoadedSceneIsEditor ? this.mach : vessel.mach;

//Run the simulation
FuelFlowSimulation.Stats[] newAtmoStats = sims[0].SimulateAllStages(1.0f, staticPressureKpa, atmDensity, mach);
FuelFlowSimulation.Stats[] newVacStats = sims[1].SimulateAllStages(1.0f, 0.0, 0.0 , mach);
atmoStats = newAtmoStats;
vacStats = newVacStats;
newAtmoStats = sims[0].SimulateAllStages(1.0f, staticPressureKpa, atmDensity, mach);
newVacStats = sims[1].SimulateAllStages(1.0f, 0.0, 0.0, mach);
}
catch (Exception e)
{
Expand All @@ -202,6 +248,7 @@ protected void RunSimulation(object o)

//start the stopwatch that will count off this delay
stopwatch.Start();
resultReady = true;
simulationRunning = false;
}
}
Expand Down

0 comments on commit 57be08f

Please sign in to comment.