Cleanup old sequencer references.

This commit is contained in:
2025-02-14 15:57:46 -05:00
parent f5d3dbc275
commit 372e9e22d2
15 changed files with 3 additions and 145 deletions

View File

@ -0,0 +1,62 @@
// Represents a series of ActionSequences
// that are mutually exclusive. Typically
// this is designed to represent multiple ActionSequences
// that act on the same set of blocks, such as an
// "Extend" and "Retract" action for a multi-stage mechanical
// construction, or perhaps "Open" and "Close" sequences for a set of
// mechanical doors.
using System.Collections.Generic;
using System.Linq;
namespace IngameScript
{
partial class Program
{
public class ActionGroup
{
public string Name { get; private set; }
public bool Running { get; private set; } = false;
private Dictionary<string, ActionSequence> _actions = new Dictionary<string, ActionSequence>();
private IConsole _console;
public ActionGroup(IConsole console, string name)
{
// Todo: use a PrefixedConsole here?
_console = console;
Name = name;
}
// Add an action to the sequence called actionName, which will be created if it doesn't already exist.
public void AddActionBlock(string actionName, int step, IBlockAction actionBlock)
{
if (!_actions.ContainsKey(actionName)) _actions[actionName] = new ActionSequence(actionName);
_actions[actionName].Add(step, actionBlock);
}
public IEnumerator<bool> RunAction(string actionName)
{
if (Running)
{
_console.Print($"Ignoring action '{actionName}' on '{Name}'. Already running an action.");
yield break;
}
if (!_actions.ContainsKey(actionName))
{
_console.Print($"No action '{actionName}' defined for '{Name}'");
yield break;
}
Running = true;
IEnumerator<bool> job = _actions[actionName].Run();
while (job.MoveNext()) yield return true;
Running = false;
}
}
}
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<SharedGUID>8a3cdcc5-4b55-4d87-a415-698a0e1ff06f</SharedGUID>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)ActionGroup.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ActionSequence.cs" />
<Compile Include="$(MSBuildThisFileDirectory)BlockActionDoor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)BlockActionPiston.cs" />
<Compile Include="$(MSBuildThisFileDirectory)BlockActionRotor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)IBlockAction.cs" />
</ItemGroup>
</Project>

View 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>

View File

@ -0,0 +1,65 @@
// An ActionSequence encapsulates a series of IBlockActions to perform.
// It represents a single logical coordinated "action". The action may have
// multiple steps, each with multiple actions. It provides a method to asynchronously
// perform those steps in sequence.
using System.Collections.Generic;
namespace IngameScript
{
partial class Program
{
public class ActionSequence
{
public string Name { get; private set; }
public bool Running { get; private set; } = false;
private SortedDictionary<int, List<IBlockAction>> _steps = new SortedDictionary<int, List<IBlockAction>>();
public ActionSequence(string name)
{
Name = name;
}
public void Add(int step, IBlockAction action)
{
if (!_steps.ContainsKey(step)) _steps[step] = new List<IBlockAction>();
_steps[step].Add(action);
}
public IEnumerator<bool> Run()
{
if (Running) yield break;
Running = true;
List<IEnumerator<bool>> jobs = new List<IEnumerator<bool>>();
foreach (List<IBlockAction> step in _steps.Values)
{
foreach (IBlockAction action in step)
{
jobs.Add(action.Run());
}
bool stepRunning = true;
while (stepRunning)
{
stepRunning = false;
foreach (IEnumerator<bool> job in jobs)
{
if (job.MoveNext()) stepRunning = true;
}
yield return true;
}
foreach (IEnumerator<bool> job in jobs)
{
job.Dispose();
}
jobs.Clear();
}
Running = false;
}
}
}
}

View File

@ -0,0 +1,52 @@
using System.Collections.Generic;
using Sandbox.ModAPI.Ingame;
namespace IngameScript
{
partial class Program
{
public class BlockActionDoor : IBlockAction
{
public enum DoorAction
{
Open,
Close,
}
public bool Running { get; private set; } = false;
private IMyDoor _door;
private DoorAction _action;
private bool _lockDoor;
public BlockActionDoor(
IMyDoor door,
DoorAction action,
bool lockDoor = true
)
{
_door = door;
_action = action;
_lockDoor = lockDoor;
}
public IEnumerator<bool> Run()
{
switch (_action)
{
case DoorAction.Open:
_door.Enabled = true;
_door.OpenDoor();
while (_door.Status != DoorStatus.Open) yield return true;
break;
case DoorAction.Close:
_door.Enabled = true;
_door.CloseDoor();
while (_door.Status != DoorStatus.Closed) yield return true;
break;
}
if (_lockDoor) _door.Enabled = false;
}
}
}
}

View File

@ -0,0 +1,40 @@
using System.Collections.Generic;
using Sandbox.ModAPI.Ingame;
namespace IngameScript
{
partial class Program
{
public class BlockActionPiston : IBlockAction
{
public bool Running { get; private set; } = false;
private IMyPistonBase _piston;
private float _position;
private float _velocity;
public BlockActionPiston(
IMyPistonBase piston,
float position,
float velocity = 2f
)
{
_piston = piston;
_position = position;
_velocity = velocity;
}
public IEnumerator<bool> Run()
{
_piston.MoveToPosition(_position, _velocity);
float lastValue = -1f;
while (lastValue != _piston.CurrentPosition)
{
lastValue = _piston.CurrentPosition;
yield return true;
}
}
}
}
}

View File

@ -0,0 +1,46 @@
using System.Collections.Generic;
using Sandbox.ModAPI.Ingame;
namespace IngameScript
{
partial class Program
{
public class BlockActionRotor : IBlockAction
{
public bool Running { get; private set; } = false;
private IMyMotorStator _rotor;
private float _angle;
private float _velocity;
private MyRotationDirection _direction;
public BlockActionRotor(
IMyMotorStator rotor,
float angle,
float velocity = 5f,
MyRotationDirection direction = MyRotationDirection.AUTO
)
{
_rotor = rotor;
_angle = angle;
_velocity = velocity;
_direction = direction;
}
public IEnumerator<bool> Run()
{
_rotor.RotorLock = false;
_rotor.RotateToAngle(_direction, _angle, _velocity);
float _lastAngle = -1;
while (_rotor.Angle != _lastAngle)
{
_lastAngle = _rotor.Angle;
yield return true;
}
_rotor.RotorLock = true;
}
}
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using Sandbox.ModAPI.Ingame;
namespace IngameScript
{
partial class Program
{
public class BlockActionRotor : IBlockAction
{
private IMyMotorRotor _rotor;
private float _targetAngle;
private float _velocity = 5f;
private RotationDirection _direction = RotationDirection.AUTO;
public BlockActionRotor(
IMyMotorRotor rotor,
float targetAngle,
float velocity = 5f,
)
{
_rotor = rotor;
}
public IEnumerator<bool> Run()
{
// code to actually execute the action goes here
// any loops that wait for a condition to be true should
// `yield return true` inside the loop.
// If the action ends prematurely, use `yield break`
yield return true;
}
}
}
}

View File

@ -0,0 +1,17 @@
// An interface to represent a pre-configured action performed asynchronously
// on a block. Implements a Run() method that executes the action and provides an
// Enumerator to monitor when the action is complete.
using System.Collections.Generic;
namespace IngameScript
{
partial class Program
{
public interface IBlockAction
{
bool Running { get; }
IEnumerator<bool> Run();
}
}
}