Skip to content

Commit

Permalink
Cascade disabling of Guidance Controller to PVG Autopilot
Browse files Browse the repository at this point in the history
This fixes the problem where PVG would finish but the staging controller
would still run once and jettison a stage.

The largest bug here was that PVG would disable itself but then the
autopilot+glueball wouldn't run until later and see that it should
terminate.

This change makes the disabling of the guidance controller fire an
action to disable the "calling" module as well.

It does this via the introduction of an events API into ComputerModule
with one supported event ModuleDisabledEvent and the addition of an
API CascadeDisable() which lets a computer module call that on another
computer module to setup an event to have itself disabled when the
target module disables itself.

This places the calling module in control, which seems right (rather
than making the GuidanceController know to poke the PVG autopilot which
seems very, very wrong).

There's other jankiness going on in here with the weird coupling between
the PVG Autopilot, the Guidance Controller and the PVG Glueball where
they're all touching all kinds of different modules without being
'subscribed' to those modules.

But this gets the right behavior since when the GuidanceController
disables itself that executes the callback which disables the PVG
autopilot and since the PVG autopilot is the "process group leader"
and it has an OnModuleDisabled that disables the whole tree, that
makes sure that this works more or less like killing the process
group leader in Unix.  By the time that "Enabled = false" returns
to the GuidanceController method the whole set of modules is disabled.

I took a little bit of care to have the callbacks execute in the reverse
order that CascadeDelete() was called and to have them be
non-duplicated.

The event is called ModuleDisabledEvent instead of onModuleDisabled or
OnModuleDisabled because that already exists as the abstract API for
the ComputerModule itself, naming things is hard.

Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
  • Loading branch information
lamont-granquist committed Jul 20, 2023
1 parent ee36930 commit d9df5df
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 6 deletions.
72 changes: 72 additions & 0 deletions MechJeb2/ComputerModule.cs
Expand Up @@ -55,10 +55,17 @@ public bool Enabled
if (_enabled)
OnModuleEnabled();
else
{
OnModuleDisabled();
ModuleDisabledEvents.Fire(true);
ModuleDisabledEvents.Clear();
}
}
}

[UsedImplicitly]
public readonly ModuleEvent ModuleDisabledEvents = new ModuleEvent();

public readonly string ProfilerName;

// Has this module config changed and should it be saved
Expand Down Expand Up @@ -239,6 +246,23 @@ protected static void Print(object message)
{
MonoBehaviour.print("[MechJeb2] " + message);
}

[UsedImplicitly]
public void Disable()
{
Enabled = false;
}

[UsedImplicitly]
public void Enable()
{
Enabled = true;
}

public void CascadeDisable(ComputerModule m)
{
ModuleDisabledEvents.Add(m.Disable);
}
}

[Flags]
Expand All @@ -249,6 +273,54 @@ public enum Pass
GLOBAL = 4
}

public class ModuleEvent
{
public delegate void OnEvent();

private readonly List<OnEvent> _events = new List<OnEvent>();
private readonly Dictionary<OnEvent, int> _eventIndex = new Dictionary<OnEvent, int>();

public void Add(OnEvent evt)
{
if (_eventIndex.ContainsKey(evt))
return;

_events.Add(evt);
_eventIndex.Add(evt, _events.Count - 1);
}

[UsedImplicitly]
public void Remove(OnEvent evt)
{
if (!_eventIndex.ContainsKey(evt))
return;

_events.RemoveAt(_eventIndex[evt]);
_eventIndex.Remove(evt);
}

public void Clear()
{
_events.Clear();
_eventIndex.Clear();
}

public void Fire(bool reverse)
{

if (reverse)
{
for (int i = _events.Count - 1; i >= 0; i--)
_events[i]();
}
else
{
for (int i = 0; i < _events.Count; i++)
_events[i]();
}
}
}

//Lets multiple users enable and disable a computer module, such that the
//module only gets disabled when all of its users have disabled it.
public class UserPool : List<object>
Expand Down
9 changes: 5 additions & 4 deletions MechJeb2/MechJebModuleAscentPVGAutopilot.cs
Expand Up @@ -21,15 +21,16 @@ protected override void OnModuleEnabled()
{
base.OnModuleEnabled();
_mode = AscentMode.VERTICAL_ASCENT;
Core.Guidance.Enabled = true;
Core.Glueball.Enabled = true;
Core.Guidance.Users.Add(this);
Core.Guidance.CascadeDisable(this);
Core.Glueball.Users.Add(this);
}

protected override void OnModuleDisabled()
{
base.OnModuleDisabled();
Core.Guidance.Enabled = false;
Core.Glueball.Enabled = false;
Core.Guidance.Users.Remove(this);
Core.Glueball.Users.Remove(this);
}

private enum AscentMode
Expand Down
4 changes: 2 additions & 2 deletions MechJeb2/MechJebModuleAscentSettings.cs
Expand Up @@ -123,11 +123,11 @@ public bool Autostage
if (!changed) return;
if (_autostage && Enabled)
{
Core.Staging.Users.Add(this);
Core.Staging.Users.Add(AscentAutopilot);
}
else if (!_autostage)
{
Core.Staging.Users.Remove(this);
Core.Staging.Users.Remove(AscentAutopilot);
}
}
}
Expand Down

0 comments on commit d9df5df

Please sign in to comment.