Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 59 additions & 46 deletions Source/DynamicBatteryStorage/Data/VesselDataManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using UnityEngine;

namespace DynamicBatteryStorage
{
Expand All @@ -7,74 +8,85 @@ namespace DynamicBatteryStorage
/// </summary>
public class VesselDataManager : VesselModule
{
#region Accessors
public VesselElectricalData ElectricalData => GetElectricalData();

public VesselElectricalData ElectricalData { get { return electricalData; } }
public bool Ready { get { return dataReady; } }

#endregion
VesselElectricalData electricalData;

#region PrivateVariables
VesselElectricalData GetElectricalData()
{
if (electricalData != null)
return electricalData;

bool dataReady = false;
bool vesselLoaded = false;
try
{
RefreshVesselData();
}
catch (Exception e)
{
Utils.Error("RefreshVesselData threw an exception");
Debug.LogException(e);
return null;
}

VesselElectricalData electricalData;
#endregion
return electricalData;
}

protected override void OnStart()
// This module is only active in the flight scene for loaded vessels.
public override bool ShouldBeActive()
{
base.OnStart();
if (!HighLogic.LoadedSceneIsFlight)
return false;

// These events need to trigger a refresh
GameEvents.onVesselGoOnRails.Add(new EventData<Vessel>.OnEvent(RefreshVesselData));
GameEvents.onVesselWasModified.Add(new EventData<Vessel>.OnEvent(RefreshVesselData));
return vessel.loaded;
}

void OnDestroy()
// Use OnEnable and OnDisable because ShouldBeActive will cause us to switch
// between being enabled and disabled in response to events.
void OnEnable()
{
// Clean up events when the item is destroyed
GameEvents.onVesselGoOnRails.Remove(RefreshVesselData);
GameEvents.onVesselWasModified.Remove(RefreshVesselData);
GameEvents.onVesselGoOnRails.Add(RefreshVesselData);
GameEvents.onVesselWasModified.Add(InvalidateVesselData);

if (vessel == FlightGlobals.ActiveVessel)
RefreshVesselData();
}

void FixedUpdate()
void OnDisable()
{
if (HighLogic.LoadedSceneIsFlight && !dataReady)
{
if (!vesselLoaded && FlightGlobals.ActiveVessel == vessel)
{
RefreshVesselData();
vesselLoaded = true;
}
if (vesselLoaded && FlightGlobals.ActiveVessel != vessel)
{
vesselLoaded = false;
}
}
GameEvents.onVesselGoOnRails.Remove(RefreshVesselData);
GameEvents.onVesselWasModified.Remove(InvalidateVesselData);

electricalData = null;
}

/// <summary>
/// Referesh the data, given a Vessel event
/// </summary>
protected void RefreshVesselData(Vessel eventVessel)
{
if (vessel != null && vessel.loaded)
{
Utils.Log(String.Format("[{0}]: Refreshing VesselData from Vessel event", this.GetType().Name), Utils.LogType.VesselData);
RefreshVesselData();
}
if (vessel != eventVessel)
return;
if (vessel == null || !vessel.loaded)
return;

if (Settings.DebugVesselData)
Utils.Log($"[{GetType().Name}]: Refreshing VesselData from Vessel event", Utils.LogType.VesselData);
RefreshVesselData();
}

/// <summary>
/// Referesh the data, given a ConfigNode event
/// Invalidate the current electrical data, given a vessel event.
/// </summary>
protected void RefreshVesselData(ConfigNode node)
/// <param name="eventVessel"></param>
protected void InvalidateVesselData(Vessel eventVessel)
{
if (vessel != null && vessel.loaded)
{
Utils.Log(String.Format("[{0}]: Refreshing VesselData from save node event", this.GetType().Name), Utils.LogType.VesselData);
RefreshVesselData();
}
if (vessel != eventVessel)
return;

electricalData = null;

if (Settings.DebugVesselData)
Utils.Log($"[{GetType().Name}]: Invalidated VesselData from Vessel event", Utils.LogType.VesselData);
}

/// <summary>
Expand All @@ -86,8 +98,9 @@ protected void RefreshVesselData()
return;

electricalData = new VesselElectricalData(vessel.Parts);
dataReady = true;
Utils.Log(String.Format("Dumping electrical database: \n{0}", electricalData.ToString()), Utils.LogType.VesselData);

if (Settings.DebugVesselData)
Utils.Log($"Dumping electrical database: \n{electricalData}", Utils.LogType.VesselData);
}
}
}
140 changes: 57 additions & 83 deletions Source/DynamicBatteryStorage/DynamicBatteryStorage.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace DynamicBatteryStorage
Expand Down Expand Up @@ -41,95 +38,88 @@ public class ModuleDynamicBatteryStorage : VesselModule
PartResource bufferStorage;
Part bufferPart;

protected override void OnAwake()
// Only run on loaded vessels in the flight scene.
public override bool ShouldBeActive()
{
base.OnAwake();
enabled = Settings.Enabled;
if (!Settings.Enabled)
return false;

if (!HighLogic.LoadedSceneIsFlight)
return false;

return vessel.loaded;
}
public override Activation GetActivation()

void OnEnabled()
{
if (Settings.Enabled)
{
return Activation.Always;
}
else
return Activation.Never;
GameEvents.onVesselGoOnRails.Add(CalculateElectricalData);
GameEvents.onVesselWasModified.Add(InvalidateElectricalData);
}
protected override void OnStart()
{
base.OnStart();

if (!Settings.Enabled) return;
void OnDisable()
{
GameEvents.onVesselGoOnRails.Add(CalculateElectricalData);
GameEvents.onVesselWasModified.Add(InvalidateElectricalData);
}

bufferScale = Settings.BufferScaling;
timeWarpLimit = Settings.TimeWarpLimit;
void FixedUpdate()
{
if (!vesselLoaded)
{
vesselData = vessel.GetComponentCached(ref vesselData);
if (!vesselData)
{
Utils.Error(CreateVesselLogString("Could not find vessel data manager"));
return;
}

GameEvents.onVesselDestroy.Add(new EventData<Vessel>.OnEvent(CalculateElectricalData));
GameEvents.onVesselGoOnRails.Add(new EventData<Vessel>.OnEvent(CalculateElectricalData));
GameEvents.onVesselWasModified.Add(new EventData<Vessel>.OnEvent(CalculateElectricalData));
CalculateElectricalData();
vesselLoaded = true;
}

FindDataManager();
analyticMode = TimeWarp.CurrentRate < timeWarpLimit;
if (!analyticMode)
DoLowWarpSimulation();
else
DoHighWarpSimulation();
}

protected override void OnSave(ConfigNode node)
protected void InvalidateElectricalData(Vessel eventVessel)
{
// Saving needs to trigger a buffer clear
ClearBufferStorage();
base.OnSave(node);
}
if (vessel != eventVessel)
return;

void OnDestroy()
{
GameEvents.onVesselDestroy.Remove(CalculateElectricalData);
GameEvents.onVesselGoOnRails.Remove(CalculateElectricalData);
GameEvents.onVesselWasModified.Remove(CalculateElectricalData);
vesselLoaded = false;
bufferPart = null;
bufferStorage = null;
}

void FindDataManager()
protected void CalculateElectricalData(Vessel eventVessel)
{
vesselData = vessel.GetComponent<VesselDataManager>();
if (!vesselData)
{
Utils.Error(CreateVesselLogString("Could not find vessel data manager"));
}
if (vessel != eventVessel)
return;
if (!vessel.loaded)
return;

CalculateElectricalData();
}

void FixedUpdate()
protected override void OnSave(ConfigNode node)
{
if (HighLogic.LoadedSceneIsFlight)
{
if (!vesselLoaded && FlightGlobals.ActiveVessel == vessel)
{
FindDataManager();
CalculateElectricalData();
vesselLoaded = true;
}
if (vesselLoaded && FlightGlobals.ActiveVessel != vessel)
{
vesselLoaded = false;
}
if (TimeWarp.CurrentRate < timeWarpLimit)
{
analyticMode = false;
DoLowWarpSimulation();
}
else
{
analyticMode = true;
DoHighWarpSimulation();
}
}
// Saving needs to trigger a buffer clear
ClearBufferStorage();
base.OnSave(node);
}

/// <summary>
/// Runs the compensation at low warp. This typically means do nothing
/// </summary>
protected void DoLowWarpSimulation()
{
if (bufferStorage != null && bufferStorage.maxAmount != originalMax)
{
bufferStorage.maxAmount = originalMax;
}
if (bufferStorage == null)
return;

bufferStorage.maxAmount = originalMax;
}

/// <summary>
Expand Down Expand Up @@ -202,22 +192,6 @@ protected void CalculateElectricalData()
}
}


protected void CalculateElectricalData(Vessel eventVessel)
{
if (vessel != null && vessel.loaded)
{
CalculateElectricalData();
}
}
protected void CalculateElectricalData(ConfigNode node)
{
if (vessel != null && vessel.loaded)
{
CalculateElectricalData();
}
}

/// <summary>
/// Clears the buffer (reverts it to its initial state)
/// </summary>
Expand Down