Add (and use) a Sequencer library for orchestrating the mechanical door; this will eventually have wide reuse applicability.
This commit is contained in:
parent
74331a95ba
commit
37511ac473
|
@ -1,62 +0,0 @@
|
||||||
using Sandbox.ModAPI.Ingame;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace IngameScript
|
|
||||||
{
|
|
||||||
public class Door
|
|
||||||
{
|
|
||||||
private PrefixedConsole _console;
|
|
||||||
private List<DoorHinge> _hinges;
|
|
||||||
|
|
||||||
public bool Locked
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
foreach (DoorHinge hinge in _hinges)
|
|
||||||
{
|
|
||||||
if (!hinge.Locked) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Door(Console console, string name)
|
|
||||||
{
|
|
||||||
_console = new PrefixedConsole(console, name);
|
|
||||||
_hinges = new List<DoorHinge>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a hinge to the door
|
|
||||||
public void AddHinge(IMyMotorStator hinge)
|
|
||||||
{
|
|
||||||
_hinges.Add(new DoorHinge(_console, 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
using Sandbox.ModAPI.Ingame;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace IngameScript
|
|
||||||
{
|
|
||||||
public class DoorHinge
|
|
||||||
{
|
|
||||||
public bool Locked { get { return _hinge.RotorLock; } }
|
|
||||||
|
|
||||||
private PrefixedConsole _console;
|
|
||||||
private IMyMotorStator _hinge;
|
|
||||||
private float _targetAngle;
|
|
||||||
private float _lastAngle;
|
|
||||||
private float _openAngle = 90F;
|
|
||||||
private float _closedAngle = 0F;
|
|
||||||
private float _velocity = 5F;
|
|
||||||
|
|
||||||
public DoorHinge(PrefixedConsole console, IMyMotorStator hinge)
|
|
||||||
{
|
|
||||||
_hinge = hinge;
|
|
||||||
_console = console;
|
|
||||||
|
|
||||||
ConfigParser config = new ConfigParser(_hinge);
|
|
||||||
_openAngle = config.GetValue("OpenAngle", 90F);
|
|
||||||
_closedAngle = config.GetValue("ClosedAngle", 0F);
|
|
||||||
_velocity = config.GetValue("Velocity", 5F);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private float degToRad(float degrees)
|
|
||||||
{
|
|
||||||
return degrees * ((float)Math.PI / 180F);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -25,4 +25,6 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="..\Mixins\Console\Console.projitems" Label="shared" />
|
<Import Project="..\Mixins\Console\Console.projitems" Label="shared" />
|
||||||
<Import Project="..\Mixins\ConfigParser\ConfigParser.projitems" Label="shared" />
|
<Import Project="..\Mixins\ConfigParser\ConfigParser.projitems" Label="shared" />
|
||||||
|
<Import Project="..\Mixins\Sequencer\Sequencer.projitems" Label="shared" />
|
||||||
|
<Import Project="..\Mixins\Utils\Utils.projitems" Label="shared" />
|
||||||
</Project>
|
</Project>
|
|
@ -1,4 +1,5 @@
|
||||||
using Sandbox.ModAPI.Ingame;
|
using Sandbox.ModAPI.Ingame;
|
||||||
|
using SpaceEngineers.Game.ModAPI.Ingame;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using VRage.Game.ModAPI.Ingame.Utilities;
|
using VRage.Game.ModAPI.Ingame.Utilities;
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ namespace IngameScript
|
||||||
private MyCommandLine _cli;
|
private MyCommandLine _cli;
|
||||||
private Console _console;
|
private Console _console;
|
||||||
private List<IEnumerator<bool>> _jobs;
|
private List<IEnumerator<bool>> _jobs;
|
||||||
private Dictionary<string, Door> _doors;
|
private Dictionary<string, Sequencer> _doors;
|
||||||
private int _tickCount;
|
private int _tickCount;
|
||||||
|
|
||||||
public Program()
|
public Program()
|
||||||
|
@ -19,21 +20,25 @@ namespace IngameScript
|
||||||
_console = new Console(this);
|
_console = new Console(this);
|
||||||
_jobs = new List<IEnumerator<bool>>();
|
_jobs = new List<IEnumerator<bool>>();
|
||||||
|
|
||||||
_doors = new Dictionary<string, Door>();
|
_doors = new Dictionary<string, Sequencer>();
|
||||||
|
|
||||||
List<IMyMotorStator> allHinges = new List<IMyMotorStator>();
|
List<IMyTerminalBlock> doorParts = Utils.GetBlocksNameContains(GridTerminalSystem, "!Door");
|
||||||
GridTerminalSystem.GetBlocksOfType(allHinges);
|
foreach (IMyTerminalBlock block in doorParts)
|
||||||
foreach (IMyMotorStator hinge in allHinges)
|
|
||||||
{
|
{
|
||||||
if (hinge.CustomName.StartsWith("Door"))
|
string doorName = Utils.ExtractTag(block, "!Door");
|
||||||
{
|
|
||||||
string doorName = hinge.CustomName.Split(' ')[0];
|
// Create the door if this is a new tag
|
||||||
if (!_doors.ContainsKey(doorName))
|
if (!_doors.ContainsKey(doorName))
|
||||||
{
|
{
|
||||||
_doors[doorName] = new Door(_console, doorName);
|
_doors[doorName] = new Sequencer(doorName, new PrefixedConsole(_console, doorName));
|
||||||
}
|
|
||||||
_doors[doorName].AddHinge(hinge);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the part; the Door object handles typing and sequencing.
|
||||||
|
int defaultStep = 1;
|
||||||
|
if (block is IMyShipMergeBlock) defaultStep = 0;
|
||||||
|
ISequenceable wrapped = SequenceableFactory.MakeSequenceable(block, defaultStep);
|
||||||
|
if (wrapped == null) { _console.Print($"Tried to add incompatible block '{block.CustomName}'"); continue; }
|
||||||
|
_doors[doorName].AddBlock(wrapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
_console.Print($"Found {_doors.Keys.Count} doors.");
|
_console.Print($"Found {_doors.Keys.Count} doors.");
|
||||||
|
@ -47,17 +52,14 @@ namespace IngameScript
|
||||||
{
|
{
|
||||||
// Create a new job
|
// Create a new job
|
||||||
_cli.TryParse(argument);
|
_cli.TryParse(argument);
|
||||||
List<Door> doorsToControl = new List<Door>();
|
List<Sequencer> doorsToControl = new List<Sequencer>();
|
||||||
|
|
||||||
if (_cli.ArgumentCount == 0)
|
if (_cli.ArgumentCount == 0)
|
||||||
{
|
{
|
||||||
_console.Print("No arguments passed. Controlling all doors.");
|
_console.Print("No arguments passed. Controlling all doors.");
|
||||||
foreach (Door door in _doors.Values)
|
foreach (Sequencer door in _doors.Values)
|
||||||
{
|
{
|
||||||
if (!door.Locked)
|
if (door.Running) continue;
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
doorsToControl.Add(door);
|
doorsToControl.Add(door);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,12 +69,12 @@ namespace IngameScript
|
||||||
string key = "Door" + _cli.Argument(i);
|
string key = "Door" + _cli.Argument(i);
|
||||||
if (!_doors.ContainsKey(key))
|
if (!_doors.ContainsKey(key))
|
||||||
{
|
{
|
||||||
_console.Print($"Door with identifier {key} not found. Skipping.");
|
_console.Print($"Door '{key}' not found. Skipping.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!_doors[key].Locked)
|
if (_doors[key].Running)
|
||||||
{
|
{
|
||||||
_console.Print($"Door {key} already moving. Skipping.");
|
_console.Print($"Door '{key}' already moving. Skipping.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
doorsToControl.Add(_doors[key]);
|
doorsToControl.Add(_doors[key]);
|
||||||
|
@ -84,10 +86,13 @@ namespace IngameScript
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_console.Print("Creating new job.");
|
_console.Print("Creating new job(s).");
|
||||||
if (_cli.Switch("close")) _jobs.Add(closeDoors(doorsToControl));
|
bool close = _cli.Switch("close");
|
||||||
else _jobs.Add(openDoors(doorsToControl));
|
foreach (Sequencer door in doorsToControl)
|
||||||
Runtime.UpdateFrequency = UpdateFrequency.Update1;
|
{
|
||||||
|
_jobs.Add(door.RunSequence(close));
|
||||||
|
}
|
||||||
|
Runtime.UpdateFrequency |= UpdateFrequency.Update1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,43 +113,5 @@ namespace IngameScript
|
||||||
Runtime.UpdateFrequency = UpdateFrequency.None;
|
Runtime.UpdateFrequency = UpdateFrequency.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerator<bool> openDoors(List<Door> doorsToControl)
|
|
||||||
{
|
|
||||||
_console.Print("Opening doors.");
|
|
||||||
foreach (Door door in doorsToControl)
|
|
||||||
{
|
|
||||||
door.OpenDoor();
|
|
||||||
}
|
|
||||||
return actuateDoors(doorsToControl);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerator<bool> closeDoors(List<Door> doorsToControl)
|
|
||||||
{
|
|
||||||
_console.Print("Closing doors.");
|
|
||||||
foreach (Door door in doorsToControl)
|
|
||||||
{
|
|
||||||
door.CloseDoor();
|
|
||||||
}
|
|
||||||
return actuateDoors(doorsToControl);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerator<bool> actuateDoors(List<Door> doorsToControl)
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
_console.Print("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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
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>
|
Loading…
Reference in New Issue
Block a user