diff --git a/Airlock/Airlock.cs b/Airlock/Airlock.cs index e24fb61..8f15cc2 100644 --- a/Airlock/Airlock.cs +++ b/Airlock/Airlock.cs @@ -55,7 +55,7 @@ namespace IngameScript { if (innerDoor.Status == DoorStatus.Closed || outerDoor.Status == DoorStatus.Open || OxygenBalanced) { return false; } - _p.Echo("DEBUG: Balancing Oxygen Tank"); + _console.Print($"{_name}: Balancing Oxygen Tank"); // Configure the vent to suck in Oxygen. airVent.Depressurize = true; @@ -64,6 +64,7 @@ namespace IngameScript } private string _name; + private PrefixedConsole _console; private MyGridProgram _p; private float targetOxygenLevel = 0.0F; @@ -75,10 +76,11 @@ namespace IngameScript private IMyAirVent airSensor; private const int CooldownTicks = 120; - public Airlock(MyGridProgram p, string name) + public Airlock(MyGridProgram program, Console console, string name) { - _p = p; + _p = program; _name = name; + _console = console.CreatePrefixedConsole(_name); // Find the appropriate blocks given the airlock name initDoors(); @@ -204,17 +206,19 @@ namespace IngameScript // Cooldown period int cooldown = 0; - while(cooldown < CooldownTicks) { + while (cooldown < CooldownTicks) + { cooldown++; yield return true; } setLights(AirlockLightState.Off); + _console.Print("Cycling Complete."); } private void closeDoors() { - _p.Echo("DEBUG: Closing Doors"); + _console.Print("Closing Doors"); // close the doors innerDoor.Enabled = true; @@ -225,7 +229,7 @@ namespace IngameScript private void pressurizeDepressurize() { - _p.Echo("DEBUG: Cycling"); + _console.Print("Cycling"); // toggle the current state airVent.Depressurize = !airVent.Depressurize; @@ -236,14 +240,14 @@ namespace IngameScript if (airVent.Depressurize && airSensor != null) { targetOxygenLevel = airSensor.GetOxygenLevel(); - _p.Echo($"Set depressurization target to {targetOxygenLevel}"); + _console.Print($"Set depressurization target to {targetOxygenLevel}"); } } // Open the appropriate door based on pressure state. private void openDoor() { - _p.Echo("DEBUG: Opening Door"); + _console.Print($"Opening Door"); if (airVent.Status == VentStatus.Pressurized) { @@ -298,7 +302,7 @@ namespace IngameScript private void error(string error) { - _p.Echo(error); + _console.Print(error); setLights(AirlockLightState.Error); } } diff --git a/Airlock/Airlock.csproj b/Airlock/Airlock.csproj index f2006f4..7b595e0 100644 --- a/Airlock/Airlock.csproj +++ b/Airlock/Airlock.csproj @@ -23,4 +23,6 @@ + + \ No newline at end of file diff --git a/Airlock/Program.cs b/Airlock/Program.cs index 769f47b..2ebc5f3 100644 --- a/Airlock/Program.cs +++ b/Airlock/Program.cs @@ -11,9 +11,11 @@ namespace IngameScript private int _tickCount = 0; private MyCommandLine _cli; + private Console _console; public Program() { + _console = new Console(this); _cli = new MyCommandLine(); _jobs = new List>(); _airlocks = new Dictionary(); @@ -25,32 +27,32 @@ namespace IngameScript if (!door.CustomName.StartsWith("Airlock")) continue; string airlockName = door.CustomName.Split(' ')[0]; if (_airlocks.ContainsKey(airlockName)) continue; - Airlock newAirlock = new Airlock(this, airlockName); + Airlock newAirlock = new Airlock(this, _console, airlockName); if (!newAirlock.Functional) { - Echo($"{airlockName} is missing one or more required blocks."); + _console.Print($"{airlockName} is missing one or more required blocks."); continue; } _airlocks[airlockName] = newAirlock; } - Echo($"Found {_airlocks.Count} airlocks."); + _console.Print($"Found {_airlocks.Count} airlocks."); } public void Main(string argument, UpdateType updateSource) { - Echo($"index: {_tickCount++}"); + _console.PrintLower($"Total Ticks: {_tickCount++}"); if (updateSource == UpdateType.Trigger || updateSource == UpdateType.Terminal) { _cli.TryParse(argument); - if (_cli.ArgumentCount == 0) { Echo("You must provide an airlock ID."); } + if (_cli.ArgumentCount == 0) { _console.Print("You must provide an airlock ID."); } else { string airlockName = $"Airlock{_cli.Argument(0)}"; if (!_airlocks.ContainsKey(airlockName)) { - Echo($"Invalid airlock ID {_cli.Argument(0)}"); + _console.Print($"Invalid airlock ID {_cli.Argument(0)}"); } else { @@ -68,7 +70,7 @@ namespace IngameScript job.Dispose(); _jobs.Remove(job); i--; - Echo("Airlock Cycling Complete."); + _console.Print("Job Removed From Queue."); } } diff --git a/Mixins/ConfigParser/ConfigParser.cs b/Mixins/ConfigParser/ConfigParser.cs new file mode 100644 index 0000000..19e1204 --- /dev/null +++ b/Mixins/ConfigParser/ConfigParser.cs @@ -0,0 +1,44 @@ +using Sandbox.ModAPI.Ingame; +using System; +using System.Collections.Generic; + +namespace IngameScript +{ + public class ConfigParser + { + private Dictionary _config; + private IMyTerminalBlock _input; + + public ConfigParser(IMyTerminalBlock input) + { + _input = input; + _config = new Dictionary(); + Parse(); + } + + // Get a config value, or a default value. + // that also does type inference, but the type of `defaultValue` must contain a `Parse()` method. + public T GetValue(string key, T defaultValue) + { + if (!_config.ContainsKey(key)) + { + return defaultValue; + + } + return (T)Convert.ChangeType(_config[key], typeof(T)); + } + + // Only call this method manually if you are monitoring CustomData for changes. + public void Parse() + { + _config.Clear(); + string[] lines = _input.CustomData.Split('\n'); + foreach (string line in lines) + { + string[] tokens = line.Split('='); + if (tokens.Length != 2) continue; + _config[tokens[0]] = tokens[1]; + } + } + } +} \ No newline at end of file diff --git a/Mixins/ConfigParser/ConfigParser.projitems b/Mixins/ConfigParser/ConfigParser.projitems new file mode 100644 index 0000000..141cea5 --- /dev/null +++ b/Mixins/ConfigParser/ConfigParser.projitems @@ -0,0 +1,11 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 8a3cdcc5-4b55-4d87-a415-698a0e1ff06f + + + + + \ No newline at end of file diff --git a/Mixins/ConfigParser/ConfigParser.shproj b/Mixins/ConfigParser/ConfigParser.shproj new file mode 100644 index 0000000..2d68160 --- /dev/null +++ b/Mixins/ConfigParser/ConfigParser.shproj @@ -0,0 +1,19 @@ + + + + 8a3cdcc5-4b55-4d87-a415-698a0e1ff06f + 14.0 + + + + + + + bin\Debug\ + + + bin\Release\ + + + + diff --git a/Mixins/Console/Console.cs b/Mixins/Console/Console.cs new file mode 100644 index 0000000..dd7c8a5 --- /dev/null +++ b/Mixins/Console/Console.cs @@ -0,0 +1,77 @@ +// A utility class representing output to the console. +// Provides a Print() function that will both call MyGridProgram.Echo() +// and also output to the Programmable Block's LCD. + +using Sandbox.ModAPI.Ingame; +using System.Collections.Generic; +using System.Text; + +namespace IngameScript +{ + public class Console + { + private MyGridProgram _program; + private int _maxLines; + private List _buffer; + + private const int DefaultMaxLines = 10; + + public Console(MyGridProgram program) + { + _program = program; + _buffer = new List(); + + // Check the PB's custom data for a maxlines directive. + ConfigParser config = new ConfigParser(_program.Me); + _maxLines = config.GetValue("ConsoleMaxLines", DefaultMaxLines); + } + + public PrefixedConsole CreatePrefixedConsole(string prefix) + { + return new PrefixedConsole(this, prefix); + } + + public void Print(string text) + { + _program.Echo(text); + _program.Me.GetSurface(0).WriteText(writeToBuffer(text)); + } + + // Text written with this method goes to the lower screen / keyboard, + // with no buffering. + public void PrintLower(string text) + { + _program.Me.GetSurface(1).WriteText(text); + } + + // Adds the text to the buffer, trims the top if necessary, and builds a printable + // string. + private string writeToBuffer(string text) + { + _buffer.Add(text); + if (_buffer.Count > _maxLines) _buffer.RemoveAt(0); + StringBuilder result = new StringBuilder("", 800); + foreach (string line in _buffer) result.AppendLine(line); + return result.ToString(); + } + } + + // This class is necessary because we need to keep a *single* buffer + // to write to. So we can ask the primary Console for a prefixer. + public class PrefixedConsole + { + private Console _console; + private string _prefix; + + public PrefixedConsole(Console console, string prefix) + { + _console = console; + _prefix = prefix + ": "; + } + + public void Print(string text) + { + _console.Print(_prefix + text); + } + } +} \ No newline at end of file diff --git a/Mixins/Console/Console.projitems b/Mixins/Console/Console.projitems new file mode 100644 index 0000000..c8c60c5 --- /dev/null +++ b/Mixins/Console/Console.projitems @@ -0,0 +1,11 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 8a3cdcc5-4b55-4d87-a415-698a0e1ff06f + + + + + \ No newline at end of file diff --git a/Mixins/Console/Console.shproj b/Mixins/Console/Console.shproj new file mode 100644 index 0000000..0b9c07c --- /dev/null +++ b/Mixins/Console/Console.shproj @@ -0,0 +1,19 @@ + + + + 8a3cdcc5-4b55-4d87-a415-698a0e1ff06f + 14.0 + + + + + + + bin\Debug\ + + + bin\Release\ + + + +