Add (and use) a Sequencer library for orchestrating the mechanical door; this will eventually have wide reuse applicability.
This commit is contained in:
14
Mixins/Sequencer/ISequenceable.cs
Normal file
14
Mixins/Sequencer/ISequenceable.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace IngameScript
|
||||
{
|
||||
partial class Program
|
||||
{
|
||||
public interface ISequenceable
|
||||
{
|
||||
bool Running { get; }
|
||||
int Step { get; }
|
||||
void Start(bool reverse = true);
|
||||
bool Check();
|
||||
void Finish();
|
||||
}
|
||||
}
|
||||
}
|
30
Mixins/Sequencer/SequenceableFactory.cs
Normal file
30
Mixins/Sequencer/SequenceableFactory.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// I hate Factories, but when the shoe fits...
|
||||
|
||||
using Sandbox.ModAPI.Ingame;
|
||||
using SpaceEngineers.Game.ModAPI.Ingame;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
partial class Program
|
||||
{
|
||||
public class SequenceableFactory
|
||||
{
|
||||
public static ISequenceable MakeSequenceable(IMyTerminalBlock block, int step = 0)
|
||||
{
|
||||
if (block is IMyMotorStator)
|
||||
{
|
||||
return new SequenceableRotor(block as IMyMotorStator, step);
|
||||
}
|
||||
if (block is IMyPistonBase)
|
||||
{
|
||||
// return new SequenceablePiston(block as IMyPistonBase, step);
|
||||
}
|
||||
if (block is IMyShipMergeBlock)
|
||||
{
|
||||
// return new SequenceableMergeBlock(block as IMyShipMergeBlock, step);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
64
Mixins/Sequencer/SequenceableRotor.cs
Normal file
64
Mixins/Sequencer/SequenceableRotor.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using Sandbox.ModAPI.Ingame;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
partial class Program
|
||||
{
|
||||
public class SequenceableRotor : ISequenceable
|
||||
{
|
||||
public bool Running { get; private set; } = false;
|
||||
public int Step { get; private set; }
|
||||
|
||||
private float _targetAngle;
|
||||
private float _lastAngle;
|
||||
|
||||
private float _velocity;
|
||||
private float _openAngle;
|
||||
private float _closedAngle;
|
||||
private IMyMotorStator _rotor;
|
||||
|
||||
public SequenceableRotor(IMyMotorStator rotor, int defaultStep = 0)
|
||||
{
|
||||
_rotor = rotor;
|
||||
|
||||
ConfigParser config = new ConfigParser(_rotor);
|
||||
_openAngle = config.GetValue("OpenAngle", 90F);
|
||||
_closedAngle = config.GetValue("ClosedAngle", 0F);
|
||||
_velocity = config.GetValue("Velocity", 5F);
|
||||
Step = config.GetValue("Step", defaultStep);
|
||||
}
|
||||
|
||||
public void Start(bool reverse)
|
||||
{
|
||||
float degAngle = reverse ? _closedAngle : _openAngle;
|
||||
_targetAngle = degToRad(degAngle);
|
||||
_rotor.RotorLock = false;
|
||||
_rotor.RotateToAngle(MyRotationDirection.AUTO, degAngle, _velocity);
|
||||
Running = true;
|
||||
}
|
||||
|
||||
public bool Check()
|
||||
{
|
||||
if (Math.Abs(_rotor.Angle - _targetAngle) < 0.1 && _rotor.Angle == _lastAngle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_lastAngle = _rotor.Angle;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Finish()
|
||||
{
|
||||
_rotor.RotorLock = true;
|
||||
Running = false;
|
||||
}
|
||||
|
||||
private float degToRad(float degrees)
|
||||
{
|
||||
return degrees * ((float)Math.PI / 180F);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
80
Mixins/Sequencer/Sequencer.cs
Normal file
80
Mixins/Sequencer/Sequencer.cs
Normal file
@ -0,0 +1,80 @@
|
||||
// Represents a single set of blocks to run in order, waiting for each group's completion before
|
||||
// moving on to the next one.
|
||||
|
||||
using Sandbox.ModAPI.Ingame;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
partial class Program
|
||||
{
|
||||
public class Sequencer
|
||||
{
|
||||
public bool Running { get; private set; }
|
||||
|
||||
private IConsole _console;
|
||||
private string _name;
|
||||
|
||||
private SortedDictionary<int, List<ISequenceable>> _sequence;
|
||||
|
||||
public Sequencer(string name, IConsole console)
|
||||
{
|
||||
_name = name;
|
||||
_console = console;
|
||||
_sequence = new SortedDictionary<int, List<ISequenceable>>();
|
||||
}
|
||||
|
||||
public void AddBlock(ISequenceable block)
|
||||
{
|
||||
if (!_sequence.ContainsKey(block.Step)) _sequence[block.Step] = new List<ISequenceable>();
|
||||
_sequence[block.Step].Add(block);
|
||||
}
|
||||
|
||||
// To activate the Sequencer, call this once, then call `MoveNext()` once per tick
|
||||
// on the returned object until it returns false.
|
||||
// (then be sure to call `Dispose() on that object`)
|
||||
public IEnumerator<bool> RunSequence(bool reverse = false)
|
||||
{
|
||||
if (Running)
|
||||
{
|
||||
_console.Print("Already running, ignoring invocation.");
|
||||
yield break;
|
||||
}
|
||||
|
||||
// This is a bit convoluted, but we're extracting the iterator for use in the foreach directly.
|
||||
// This allows us to iterate in reverse when reversing/"closing" the sequence.
|
||||
IEnumerable<KeyValuePair<int, List<ISequenceable>>> steps = reverse ? _sequence.Reverse() : _sequence;
|
||||
foreach (KeyValuePair<int, List<ISequenceable>> kvp in steps)
|
||||
{
|
||||
List<ISequenceable> blocks = kvp.Value;
|
||||
Running = true;
|
||||
|
||||
foreach (ISequenceable block in blocks)
|
||||
{
|
||||
// TODO: add some sort of handling for block.Running == true
|
||||
block.Start(reverse);
|
||||
}
|
||||
yield return true;
|
||||
|
||||
while (Running)
|
||||
{
|
||||
Running = false;
|
||||
foreach (ISequenceable block in blocks)
|
||||
{
|
||||
if (block.Check()) Running = true;
|
||||
}
|
||||
yield return true;
|
||||
}
|
||||
|
||||
foreach (ISequenceable block in blocks)
|
||||
{
|
||||
block.Finish();
|
||||
}
|
||||
}
|
||||
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Mixins/Sequencer/Sequencer.projitems
Normal file
11
Mixins/Sequencer/Sequencer.projitems
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' < '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<SharedGUID>8a3cdcc5-4b55-4d87-a415-698a0e1ff06f</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)/**/*.cs" Visible=" '$(ShowCommonFiles)' == 'true' " />
|
||||
</ItemGroup>
|
||||
</Project>
|
19
Mixins/Sequencer/Sequencer.shproj
Normal file
19
Mixins/Sequencer/Sequencer.shproj
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>8a3cdcc5-4b55-4d87-a415-698a0e1ff06f</ProjectGuid>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')"/>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props"/>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props"/>
|
||||
<PropertyGroup/>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="Sequencer.projitems" Label="Shared"/>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets"/>
|
||||
</Project>
|
Reference in New Issue
Block a user