Convert mechanical door script to use MDK2.
This commit is contained in:
parent
f0f7aa9030
commit
13e1f9d63c
32
.gitignore
vendored
Normal file
32
.gitignore
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
*.swp
|
||||
*.*~
|
||||
project.lock.json
|
||||
.DS_Store
|
||||
*.pyc
|
||||
nupkg/
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
msbuild.log
|
||||
msbuild.err
|
||||
msbuild.wrn
|
57
MechanicalDoor/Door.cs
Normal file
57
MechanicalDoor/Door.cs
Normal file
|
@ -0,0 +1,57 @@
|
|||
using Sandbox.ModAPI.Ingame;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
public class Door
|
||||
{
|
||||
public Door()
|
||||
{
|
||||
Hinges = new List<DoorHinge>();
|
||||
}
|
||||
|
||||
// Add a hinge to the door
|
||||
public void AddHinge(IMyMotorStator hinge)
|
||||
{
|
||||
Hinges.Add(new DoorHinge(hinge));
|
||||
}
|
||||
|
||||
public void OpenDoor()
|
||||
{
|
||||
foreach (DoorHinge hinge in Hinges)
|
||||
{
|
||||
hinge.OpenDoorHinge();
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseDoor()
|
||||
{
|
||||
foreach (DoorHinge hinge in Hinges)
|
||||
{
|
||||
hinge.CloseDoorHinge();
|
||||
}
|
||||
}
|
||||
|
||||
// Process the door's movement. This will return true when the door is done moving.
|
||||
public bool Actuate()
|
||||
{
|
||||
bool done = true;
|
||||
foreach (DoorHinge hinge in Hinges)
|
||||
{
|
||||
if (!hinge.Actuate()) done = false;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
public bool Locked()
|
||||
{
|
||||
foreach (DoorHinge hinge in Hinges)
|
||||
{
|
||||
if (!hinge.Locked()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<DoorHinge> Hinges;
|
||||
}
|
||||
}
|
84
MechanicalDoor/DoorHinge.cs
Normal file
84
MechanicalDoor/DoorHinge.cs
Normal file
|
@ -0,0 +1,84 @@
|
|||
using Sandbox.ModAPI.Ingame;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
public class DoorHinge
|
||||
{
|
||||
public DoorHinge(IMyMotorStator hinge)
|
||||
{
|
||||
Hinge = hinge;
|
||||
}
|
||||
|
||||
// For these two functions, IMyMotorStator.Angle reports radians, but
|
||||
// IMyMotorStator.RotateToAngle() expects degrees...
|
||||
public void OpenDoorHinge()
|
||||
{
|
||||
Hinge.RotorLock = false;
|
||||
TargetAngle = DegToRad(OpenAngle);
|
||||
Hinge.RotateToAngle(MyRotationDirection.AUTO, OpenAngle, Velocity);
|
||||
}
|
||||
|
||||
public void CloseDoorHinge()
|
||||
{
|
||||
Hinge.RotorLock = false;
|
||||
TargetAngle = DegToRad(ClosedAngle);
|
||||
Hinge.RotateToAngle(MyRotationDirection.AUTO, ClosedAngle, Velocity);
|
||||
}
|
||||
|
||||
// Process the hinge's movement.
|
||||
// It will return true when the panel has finished moving.
|
||||
// TODO: Add a mechanism to determine when a door gets stuck or can't reach the target angle.
|
||||
public bool Actuate()
|
||||
{
|
||||
if (Math.Abs(Hinge.Angle - TargetAngle) < 0.1 && Hinge.Angle == LastAngle)
|
||||
{
|
||||
Hinge.RotorLock = true;
|
||||
}
|
||||
LastAngle = Hinge.Angle;
|
||||
return Locked();
|
||||
}
|
||||
|
||||
public bool Locked()
|
||||
{
|
||||
return Hinge.RotorLock;
|
||||
}
|
||||
|
||||
private IMyMotorStator Hinge { get; set; }
|
||||
private float TargetAngle { get; set; }
|
||||
private float LastAngle { get; set; }
|
||||
private float OpenAngle { get; set; } = 90F;
|
||||
private float ClosedAngle { get; set; } = 0F;
|
||||
private float Velocity { get; set; } = 5F;
|
||||
|
||||
private void ParseConfig()
|
||||
{
|
||||
string[] lines = Hinge.CustomData.Split('\n');
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string[] tokens = line.Split('=');
|
||||
if (tokens.Length != 2) continue;
|
||||
switch (tokens[0])
|
||||
{
|
||||
case "OpenAngle":
|
||||
OpenAngle = float.Parse(tokens[1]);
|
||||
break;
|
||||
case "ClosedAngle":
|
||||
ClosedAngle = float.Parse(tokens[1]);
|
||||
break;
|
||||
case "Velocity":
|
||||
Velocity = float.Parse(tokens[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: a utility class or function would be lovely...
|
||||
// In general, the encapsulation feels a little screwy here.
|
||||
private float DegToRad(float degrees)
|
||||
{
|
||||
return degrees * ((float)Math.PI / 180F);
|
||||
}
|
||||
}
|
||||
}
|
27
MechanicalDoor/MechanicalDoor.csproj
Normal file
27
MechanicalDoor/MechanicalDoor.csproj
Normal file
|
@ -0,0 +1,27 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netframework48</TargetFramework>
|
||||
<RootNamespace>IngameScript</RootNamespace>
|
||||
<LangVersion>6</LangVersion>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<Configurations>Release;Debug</Configurations>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Mal.Mdk2.PbAnalyzers" Version="2.1.11">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Mal.Mdk2.PbPackager" Version="2.1.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Mal.Mdk2.References" Version="2.2.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Instructions.readme" />
|
||||
<AdditionalFiles Include="Instructions.readme" />
|
||||
<AdditionalFiles Include="thumb.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="../Mixins/JobDispatcher/JobDispatcher.projitems" Label="JobDispatcher" />
|
||||
</Project>
|
22
MechanicalDoor/MechanicalDoor.mdk.ini
Normal file
22
MechanicalDoor/MechanicalDoor.mdk.ini
Normal file
|
@ -0,0 +1,22 @@
|
|||
; This file is project specific and should be checked in to source control.
|
||||
|
||||
[mdk]
|
||||
; This is a programmable block script project.
|
||||
; You should not change this.
|
||||
type=programmableblock
|
||||
|
||||
; Toggle trace (on|off) (verbose output)
|
||||
trace=off
|
||||
|
||||
; What type of minification to use (none|trim|stripcomments|lite|full)
|
||||
; none: No minification
|
||||
; trim: Removes unused types (NOT members).
|
||||
; stripcomments: trim + removes comments.
|
||||
; lite: stripcomments + removes leading/trailing whitespace.
|
||||
; full: lite + renames identifiers to shorter names.
|
||||
minify=none
|
||||
|
||||
; A list of files and folder to ignore when creating the script.
|
||||
; This is a comma separated list of glob patterns.
|
||||
; See https://code.visualstudio.com/docs/editor/glob-patterns
|
||||
ignores=obj/**/*,MDK/**/*,**/*.debug.cs
|
7
MechanicalDoor/MechanicalDoor.mdk.local.ini
Normal file
7
MechanicalDoor/MechanicalDoor.mdk.local.ini
Normal file
|
@ -0,0 +1,7 @@
|
|||
; This file is _local_ to your machine and should not be checked in to source control.
|
||||
|
||||
[mdk]
|
||||
; Where to output the script to (auto|specific path)
|
||||
output=auto
|
||||
; Override the default binary path (auto|specific path)
|
||||
binarypath=auto
|
165
MechanicalDoor/Program.cs
Normal file
165
MechanicalDoor/Program.cs
Normal file
|
@ -0,0 +1,165 @@
|
|||
using Sandbox.Game.EntityComponents;
|
||||
using Sandbox.ModAPI.Ingame;
|
||||
using Sandbox.ModAPI.Interfaces;
|
||||
using SpaceEngineers.Game.ModAPI.Ingame;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using VRage;
|
||||
using VRage.Collections;
|
||||
using VRage.Game;
|
||||
using VRage.Game.Components;
|
||||
using VRage.Game.GUI.TextPanel;
|
||||
using VRage.Game.ModAPI.Ingame;
|
||||
using VRage.Game.ModAPI.Ingame.Utilities;
|
||||
using VRage.Game.ObjectBuilders.Definitions;
|
||||
using VRageMath;
|
||||
|
||||
namespace IngameScript
|
||||
{
|
||||
public partial class Program : MyGridProgram
|
||||
{
|
||||
MyCommandLine cli;
|
||||
List<IEnumerator<bool>> jobs;
|
||||
Dictionary<string, Door> doors;
|
||||
int tickCount;
|
||||
|
||||
|
||||
public Program()
|
||||
{
|
||||
tickCount = 0;
|
||||
cli = new MyCommandLine();
|
||||
jobs = new List<IEnumerator<bool>>();
|
||||
|
||||
doors = new Dictionary<string, Door>();
|
||||
|
||||
List<IMyMotorStator> allHinges = new List<IMyMotorStator>();
|
||||
GridTerminalSystem.GetBlocksOfType(allHinges);
|
||||
foreach (IMyMotorStator hinge in allHinges)
|
||||
{
|
||||
if (hinge.CustomName.StartsWith("Door"))
|
||||
{
|
||||
string doorName = hinge.CustomName.Split(' ')[0];
|
||||
if (!doors.ContainsKey(doorName))
|
||||
{
|
||||
doors[doorName] = new Door();
|
||||
}
|
||||
doors[doorName].AddHinge(hinge);
|
||||
}
|
||||
}
|
||||
|
||||
Echo($"Found {doors.Keys.Count} doors.");
|
||||
}
|
||||
|
||||
public void Main(string argument, UpdateType updateSource)
|
||||
{
|
||||
Echo($"index: {tickCount++}");
|
||||
|
||||
if (updateSource == UpdateType.Trigger || updateSource == UpdateType.Terminal)
|
||||
{
|
||||
// Create a new job
|
||||
cli.TryParse(argument);
|
||||
List<Door> doorsToControl = new List<Door>();
|
||||
|
||||
if (cli.ArgumentCount == 0)
|
||||
{
|
||||
Echo("No arguments passed. Controlling all doors.");
|
||||
foreach (Door door in doors.Values)
|
||||
{
|
||||
if (!door.Locked())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
doorsToControl.Add(door);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < cli.ArgumentCount; i++)
|
||||
{
|
||||
string key = "Door" + cli.Argument(i);
|
||||
if (!doors.ContainsKey(key))
|
||||
{
|
||||
Echo($"Door with identifier {key} not found. Skipping.");
|
||||
continue;
|
||||
}
|
||||
if (!doors[key].Locked())
|
||||
{
|
||||
Echo($"Door {key} already moving. Skipping.");
|
||||
continue;
|
||||
}
|
||||
doorsToControl.Add(doors[key]);
|
||||
}
|
||||
|
||||
if (doorsToControl.Count == 0)
|
||||
{
|
||||
Echo("No doors found. Not creating new job.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Echo("Creating new job.");
|
||||
if (cli.Switch("close")) jobs.Add(CloseDoors(doorsToControl));
|
||||
else jobs.Add(OpenDoors(doorsToControl));
|
||||
Runtime.UpdateFrequency = UpdateFrequency.Update1;
|
||||
}
|
||||
}
|
||||
|
||||
// Process running jobs
|
||||
for (int i = 0; i < jobs.Count; i++)
|
||||
{
|
||||
if (!jobs[i].MoveNext())
|
||||
{
|
||||
jobs[i].Dispose();
|
||||
jobs.Remove(jobs[i]);
|
||||
i--;
|
||||
Echo("Operation Complete.");
|
||||
}
|
||||
}
|
||||
|
||||
if (jobs.Count == 0)
|
||||
{
|
||||
Runtime.UpdateFrequency = UpdateFrequency.None;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator<bool> OpenDoors(List<Door> doorsToControl)
|
||||
{
|
||||
Echo("Opening doors.");
|
||||
foreach (Door door in doorsToControl)
|
||||
{
|
||||
door.OpenDoor();
|
||||
}
|
||||
return ActuateDoors(doorsToControl);
|
||||
}
|
||||
|
||||
private IEnumerator<bool> CloseDoors(List<Door> doorsToControl)
|
||||
{
|
||||
Echo("Closing doors.");
|
||||
foreach (Door door in doorsToControl)
|
||||
{
|
||||
door.CloseDoor();
|
||||
}
|
||||
return ActuateDoors(doorsToControl);
|
||||
}
|
||||
|
||||
private IEnumerator<bool> ActuateDoors(List<Door> doorsToControl)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Echo("Actuating doors.");
|
||||
bool done = true; // assume we've finished, then falsify it below
|
||||
foreach (Door door in doorsToControl)
|
||||
{
|
||||
if (!door.Actuate())
|
||||
{
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
if (done) yield break;
|
||||
yield return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
20
MechanicalDoor/instructions.readme
Normal file
20
MechanicalDoor/instructions.readme
Normal file
|
@ -0,0 +1,20 @@
|
|||
Script for controlling "mechanical" doors, aka custom doors using hinges.
|
||||
|
||||
Future features:
|
||||
* Rotor and piston support.
|
||||
* "Multi-stage doors", e.g. actuate a hinge, then a piston.
|
||||
|
||||
Currently this operates on hinges whose names start with "DoorX", where X is an arbitrary identifier.
|
||||
Usage:
|
||||
Script argument should be a space-separated list of identifiers and either
|
||||
`-open` (default behavior) or `-close`.
|
||||
Failing to pass any identifiers will cause the action to happen to all doors on the grid.
|
||||
|
||||
By default "open" is assumed to be 90 degrees and "closed" is assumed to be 0 degrees.
|
||||
However, each hinge can have this behavior configured via custom data. A sample config
|
||||
(with the default values):
|
||||
|
||||
OpenAngle=90
|
||||
ClosedAngle=0
|
||||
Velocity=5
|
||||
|
BIN
MechanicalDoor/thumb.png
Normal file
BIN
MechanicalDoor/thumb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 389 KiB |
|
@ -1,246 +0,0 @@
|
|||
// Script for controlling "mechanical" doors, aka custom doors using hinges.
|
||||
//
|
||||
// Future features:
|
||||
// * Rotor and piston support.
|
||||
// * "Multi-stage doors", e.g. actuate a hinge, then a piston.
|
||||
//
|
||||
// Currently this operates on hinges whose names start with "DoorX", where X is an arbitrary identifier.
|
||||
// Usage:
|
||||
// Script argument should be a space-separated list of identifiers and either
|
||||
// `-open` (default behavior) or `-close`.
|
||||
// Failing to pass any identifiers will cause the action to happen to all doors on the grid.
|
||||
//
|
||||
// By default "open" is assumed to be 90 degrees and "closed" is assumed to be 0 degrees.
|
||||
// However, each hinge can have this behavior configured via custom data. A sample config
|
||||
// (with the default values):
|
||||
//
|
||||
// OpenAngle=90
|
||||
// ClosedAngle=0
|
||||
// Velocity=5
|
||||
|
||||
|
||||
|
||||
MyCommandLine cli;
|
||||
List<IEnumerator<bool>> jobs;
|
||||
Dictionary<string, Door> doors;
|
||||
int tickCount;
|
||||
|
||||
public class DoorHinge {
|
||||
public DoorHinge(Program p, IMyMotorStator hinge) {
|
||||
P = p;
|
||||
Hinge = hinge;
|
||||
}
|
||||
|
||||
// For these two functions, IMyMotorStator.Angle reports radians, but
|
||||
// IMyMotorStator.RotateToAngle() expects degrees...
|
||||
public void OpenDoorHinge() {
|
||||
Hinge.RotorLock = false;
|
||||
TargetAngle = DegToRad(OpenAngle);
|
||||
Hinge.RotateToAngle(MyRotationDirection.AUTO, OpenAngle, Velocity);
|
||||
}
|
||||
|
||||
public void CloseDoorHinge() {
|
||||
Hinge.RotorLock = false;
|
||||
TargetAngle = DegToRad(ClosedAngle);
|
||||
Hinge.RotateToAngle(MyRotationDirection.AUTO, ClosedAngle, Velocity);
|
||||
}
|
||||
|
||||
// Process the hinge's movement.
|
||||
// It will return true when the panel has finished moving.
|
||||
// TODO: Add a mechanism to determine when a door gets stuck or can't reach the target angle.
|
||||
public bool Actuate() {
|
||||
if (Math.Abs(Hinge.Angle - TargetAngle) < 0.1 && Hinge.Angle == LastAngle) {
|
||||
Hinge.RotorLock = true;
|
||||
}
|
||||
LastAngle = Hinge.Angle;
|
||||
return Locked();
|
||||
}
|
||||
|
||||
public bool Locked() {
|
||||
return Hinge.RotorLock;
|
||||
}
|
||||
|
||||
private Program P; // for access to Echo, etc.
|
||||
private IMyMotorStator Hinge { get; set; }
|
||||
private float TargetAngle { get; set; }
|
||||
private float LastAngle {get; set; }
|
||||
private float OpenAngle { get; set; } = 90F;
|
||||
private float ClosedAngle { get; set; } = 0F;
|
||||
private float Velocity { get; set; } = 5F;
|
||||
|
||||
private void ParseConfig() {
|
||||
string[] lines = Hinge.CustomData.Split('\n');
|
||||
foreach (string line in lines) {
|
||||
string[] tokens = line.Split('=');
|
||||
if (tokens.Length != 2) continue;
|
||||
switch(tokens[0]) {
|
||||
case "OpenAngle":
|
||||
OpenAngle = float.Parse(tokens[1]);
|
||||
break;
|
||||
case "ClosedAngle":
|
||||
ClosedAngle = float.Parse(tokens[1]);
|
||||
break;
|
||||
case "Velocity":
|
||||
Velocity = float.Parse(tokens[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: a utility class or function would be lovely...
|
||||
// In general, the encapsulation feels a little screwy here.
|
||||
private float DegToRad(float degrees) {
|
||||
return degrees * ((float)Math.PI / 180F);
|
||||
}
|
||||
}
|
||||
|
||||
public class Door {
|
||||
public Door(Program p) {
|
||||
P = p;
|
||||
Hinges = new List<DoorHinge>();
|
||||
}
|
||||
|
||||
// Add a hinge to the door
|
||||
public void AddHinge(IMyMotorStator hinge) {
|
||||
Hinges.Add(new DoorHinge(P, hinge));
|
||||
}
|
||||
|
||||
public void OpenDoor() {
|
||||
foreach (DoorHinge hinge in Hinges) {
|
||||
hinge.OpenDoorHinge();
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseDoor() {
|
||||
foreach (DoorHinge hinge in Hinges) {
|
||||
hinge.CloseDoorHinge();
|
||||
}
|
||||
}
|
||||
|
||||
// Process the door's movement. This will return true when the door is done moving.
|
||||
public bool Actuate() {
|
||||
bool done = true;
|
||||
foreach (DoorHinge hinge in Hinges) {
|
||||
if (!hinge.Actuate()) done = false;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
public bool Locked() {
|
||||
foreach (DoorHinge hinge in Hinges) {
|
||||
if (!hinge.Locked()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<DoorHinge> Hinges;
|
||||
private Program P;
|
||||
}
|
||||
|
||||
public Program() {
|
||||
tickCount = 0;
|
||||
cli = new MyCommandLine();
|
||||
jobs = new List<IEnumerator<bool>>();
|
||||
|
||||
doors = new Dictionary<string, Door>();
|
||||
|
||||
List<IMyMotorStator> allHinges = new List<IMyMotorStator>();
|
||||
GridTerminalSystem.GetBlocksOfType(allHinges);
|
||||
foreach(IMyMotorStator hinge in allHinges) {
|
||||
if (hinge.CustomName.StartsWith("Door")) {
|
||||
string doorName = hinge.CustomName.Split(' ')[0];
|
||||
if (!doors.ContainsKey(doorName)) {
|
||||
doors[doorName] = new Door(this);
|
||||
}
|
||||
doors[doorName].AddHinge(hinge);
|
||||
}
|
||||
}
|
||||
|
||||
Echo($"Found {doors.Keys.Count} doors.");
|
||||
}
|
||||
|
||||
public void Main(string argument, UpdateType updateSource) {
|
||||
Echo($"index: {tickCount++}");
|
||||
|
||||
if (updateSource == UpdateType.Trigger || updateSource == UpdateType.Terminal) {
|
||||
// Create a new job
|
||||
cli.TryParse(argument);
|
||||
List<Door> doorsToControl = new List<Door>();
|
||||
|
||||
if (cli.ArgumentCount == 0) {
|
||||
Echo("No arguments passed. Controlling all doors.");
|
||||
foreach (Door door in doors.Values) {
|
||||
if (!door.Locked()) {
|
||||
continue;
|
||||
}
|
||||
doorsToControl.Add(door);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i < cli.ArgumentCount; i++) {
|
||||
string key = "Door" + cli.Argument(i);
|
||||
if (!doors.ContainsKey(key)) {
|
||||
Echo($"Door with identifier {key} not found. Skipping.");
|
||||
continue;
|
||||
}
|
||||
if (!doors[key].Locked()) {
|
||||
Echo($"Door {key} already moving. Skipping.");
|
||||
continue;
|
||||
}
|
||||
doorsToControl.Add(doors[key]);
|
||||
}
|
||||
|
||||
if (doorsToControl.Count == 0) {
|
||||
Echo("No doors found. Not creating new job.");
|
||||
} else {
|
||||
Echo("Creating new job.");
|
||||
if (cli.Switch("close")) jobs.Add(CloseDoors(doorsToControl));
|
||||
else jobs.Add(OpenDoors(doorsToControl));
|
||||
Runtime.UpdateFrequency = UpdateFrequency.Update1;
|
||||
}
|
||||
}
|
||||
|
||||
// Process running jobs
|
||||
for (int i=0; i < jobs.Count; i++) {
|
||||
if (!jobs[i].MoveNext()) {
|
||||
jobs[i].Dispose();
|
||||
jobs.Remove(jobs[i]);
|
||||
i--;
|
||||
Echo("Operation Complete.");
|
||||
}
|
||||
}
|
||||
|
||||
if (jobs.Count == 0) {
|
||||
Runtime.UpdateFrequency = UpdateFrequency.None;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator<bool> OpenDoors(List<Door> doorsToControl) {
|
||||
Echo("Opening doors.");
|
||||
foreach (Door door in doorsToControl) {
|
||||
door.OpenDoor();
|
||||
}
|
||||
return ActuateDoors(doorsToControl);
|
||||
}
|
||||
|
||||
private IEnumerator<bool> CloseDoors(List<Door> doorsToControl) {
|
||||
Echo("Closing doors.");
|
||||
foreach (Door door in doorsToControl) {
|
||||
door.CloseDoor();
|
||||
}
|
||||
return ActuateDoors(doorsToControl);
|
||||
}
|
||||
|
||||
private IEnumerator<bool> ActuateDoors(List<Door> doorsToControl) {
|
||||
while (true) {
|
||||
Echo("Actuating doors.");
|
||||
bool done = true; // assume we've finished, then falsify it below
|
||||
foreach (Door door in doorsToControl) {
|
||||
if (!door.Actuate()) {
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
if (done) yield break;
|
||||
yield return true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user