Make further properties multi-client and thread-safe
Move MovingPrimary, MovingSecondary, EarliestNonSlewingTime to SharedResources, make all new properties thread-safe (atomic) operations.
This commit is contained in:
@@ -1004,20 +1004,28 @@ namespace Meade.net.Telescope.UnitTests
|
||||
_sharedResourcesWrapperMock.Verify(x => x.SendChar("P", false), Times.AtLeastOnce);
|
||||
}
|
||||
|
||||
[TestCase("High", false, true)]
|
||||
[TestCase("High", true, true)]
|
||||
[TestCase("Low", false, false)]
|
||||
[TestCase("Low", true, false)]
|
||||
public void Precision_Set_WhenSecondConnectionMade_ThenTelescopePrecisionNotChanged(string desiredPresision, bool telescopePrecision, bool finalPrecision)
|
||||
[TestCase("High")]
|
||||
[TestCase("Low")]
|
||||
public void Precision_Set_WhenSecondConnectionMade_ThenTelescopePrecisionNotChanged(string desiredPresision)
|
||||
{
|
||||
var isLongFormat = desiredPresision == "High"
|
||||
|| (desiredPresision == "Low"
|
||||
? false
|
||||
: throw new ArgumentOutOfRangeException(nameof(desiredPresision), desiredPresision, "Should be High or Low"));
|
||||
_sharedResourcesWrapperMock.SetupProperty(x => x.IsLongFormat, isLongFormat);
|
||||
_sharedResourcesWrapperMock.Setup(x => x.SendString("GR", false)).Returns(() => _testProperties.telescopeRaResult);
|
||||
_utilMock.Setup(x => x.HMSToHours(_testProperties.telescopeRaResult)).Returns(() => _testProperties.rightAscension);
|
||||
|
||||
_profileProperties.Precision = desiredPresision;
|
||||
|
||||
_connectionInfo.SameDevice = 2;
|
||||
//_connectionInfo.Connections = 2;
|
||||
|
||||
|
||||
_telescope.Connected = true;
|
||||
|
||||
_sharedResourcesWrapperMock.Verify(x => x.SendChar("P", false), Times.Never);
|
||||
_sharedResourcesWrapperMock.Verify(x => x.IsLongFormat, Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -1687,6 +1695,9 @@ namespace Meade.net.Telescope.UnitTests
|
||||
[TestCase(GuideDirections.guideSouth, TelescopeAxes.axisSecondary)]
|
||||
public void PulseGuide_WhenMovingAxisAndPulseGuideAttempted_ThenThrowsExpectedException(GuideDirections direction, TelescopeAxes axes)
|
||||
{
|
||||
_sharedResourcesWrapperMock.SetupProperty(x => x.MovingPrimary);
|
||||
_sharedResourcesWrapperMock.SetupProperty(x => x.MovingSecondary);
|
||||
_sharedResourcesWrapperMock.SetupProperty(x => x.EarliestNonSlewingTime, DateTime.MinValue);
|
||||
_sharedResourcesWrapperMock.Setup(x => x.SendString("D", false)).Returns("");
|
||||
|
||||
var duration = 0;
|
||||
@@ -1697,6 +1708,8 @@ namespace Meade.net.Telescope.UnitTests
|
||||
var exception = Assert.Throws<InvalidOperationException>(() => _telescope.PulseGuide(direction, duration));
|
||||
|
||||
Assert.That(exception.Message, Is.EqualTo("Unable to PulseGuide while moving same axis."));
|
||||
Assert.That(_sharedResourcesWrapperMock.Object.MovingPrimary, Is.EqualTo(axes == TelescopeAxes.axisPrimary));
|
||||
Assert.That(_sharedResourcesWrapperMock.Object.MovingSecondary, Is.EqualTo(axes == TelescopeAxes.axisSecondary));
|
||||
}
|
||||
|
||||
[TestCase(GuideDirections.guideEast)]
|
||||
@@ -2909,6 +2922,7 @@ namespace Meade.net.Telescope.UnitTests
|
||||
[TestCase(15, 10, "2021-10-03T20:36:00", "2021-10-03T20:36:25", false)]
|
||||
public void Slewing_WhenTelescopeIsSlewing_ThenReturnsExpectedValueForSettleTime(short settleTime, short profileSettleTime, string startSlewing, string endSlewing, bool isSlewing)
|
||||
{
|
||||
_sharedResourcesWrapperMock.SetupProperty(x => x.EarliestNonSlewingTime, DateTime.MinValue);
|
||||
_profileProperties.SettleTime = profileSettleTime;
|
||||
|
||||
var timescalled = 0;
|
||||
@@ -2979,6 +2993,10 @@ namespace Meade.net.Telescope.UnitTests
|
||||
[TestCase(-1, TelescopeAxes.axisSecondary)]
|
||||
public void Slewing_WhenTelescopeIsMoving_ThenDoesNotSendCommandAndReturnsTrue(int rate, TelescopeAxes axis)
|
||||
{
|
||||
_sharedResourcesWrapperMock.SetupProperty(x => x.MovingPrimary);
|
||||
_sharedResourcesWrapperMock.SetupProperty(x => x.MovingSecondary);
|
||||
_sharedResourcesWrapperMock.SetupProperty(x => x.EarliestNonSlewingTime, DateTime.MinValue);
|
||||
|
||||
ConnectTelescope();
|
||||
|
||||
_telescope.MoveAxis(axis, rate);
|
||||
@@ -2986,6 +3004,9 @@ namespace Meade.net.Telescope.UnitTests
|
||||
var result = _telescope.Slewing;
|
||||
|
||||
Assert.That(result, Is.True);
|
||||
Assert.That(_sharedResourcesWrapperMock.Object.MovingPrimary, Is.EqualTo(axis == TelescopeAxes.axisPrimary));
|
||||
Assert.That(_sharedResourcesWrapperMock.Object.MovingSecondary, Is.EqualTo(axis == TelescopeAxes.axisSecondary));
|
||||
|
||||
_sharedResourcesWrapperMock.Verify(x => x.SendString("D", false), Times.Never);
|
||||
}
|
||||
|
||||
@@ -3005,6 +3026,11 @@ namespace Meade.net.Telescope.UnitTests
|
||||
[TestCase(-1, TelescopeAxes.axisSecondary, 10, 20, true, true)]
|
||||
public void Slewing_WhenTelescopeStops_ThenWaitsForSettleTime(int rate, TelescopeAxes axis, short profileSettleTime, short driverSettleTime, bool expectedResultInWaitingPeriod, bool afterProfileSettleTimeUp)
|
||||
{
|
||||
_sharedResourcesWrapperMock.SetupProperty(x => x.MovingPrimary);
|
||||
_sharedResourcesWrapperMock.SetupProperty(x => x.MovingSecondary);
|
||||
_sharedResourcesWrapperMock.SetupProperty(x => x.SlewSettleTime);
|
||||
_sharedResourcesWrapperMock.SetupProperty(x => x.EarliestNonSlewingTime, DateTime.MinValue);
|
||||
|
||||
_profileProperties.SettleTime = profileSettleTime;
|
||||
|
||||
DateTime currentTime = MakeTime("2021-01-23T22:02:10");
|
||||
@@ -3022,17 +3048,17 @@ namespace Meade.net.Telescope.UnitTests
|
||||
|
||||
_telescope.MoveAxis(axis, 0);
|
||||
|
||||
currentTime = currentTime + TimeSpan.FromSeconds(profileSettleTime / 2);
|
||||
currentTime += TimeSpan.FromSeconds(profileSettleTime / 2);
|
||||
|
||||
result = _telescope.Slewing;
|
||||
Assert.That(result, Is.EqualTo(expectedResultInWaitingPeriod));
|
||||
|
||||
currentTime = currentTime + TimeSpan.FromSeconds(profileSettleTime / 2);
|
||||
currentTime += TimeSpan.FromSeconds(profileSettleTime / 2);
|
||||
|
||||
result = _telescope.Slewing;
|
||||
Assert.That(result, Is.EqualTo(afterProfileSettleTimeUp));
|
||||
|
||||
currentTime = currentTime + TimeSpan.FromSeconds(driverSettleTime);
|
||||
currentTime += TimeSpan.FromSeconds(driverSettleTime);
|
||||
|
||||
result = _telescope.Slewing;
|
||||
Assert.That(result, Is.False);
|
||||
|
||||
@@ -938,8 +938,8 @@ namespace ASCOM.Meade.net
|
||||
//:Q# Halt all current slewing
|
||||
//Returns:Nothing
|
||||
|
||||
_movingPrimary = false;
|
||||
_movingSecondary = false;
|
||||
SharedResourcesWrapper.MovingPrimary = false;
|
||||
SharedResourcesWrapper.MovingSecondary = false;
|
||||
SetSlewingMinEndTime();
|
||||
}
|
||||
|
||||
@@ -1522,9 +1522,6 @@ namespace ASCOM.Meade.net
|
||||
}
|
||||
}
|
||||
|
||||
private bool _movingPrimary;
|
||||
private bool _movingSecondary;
|
||||
|
||||
public void MoveAxis(TelescopeAxes axis, double rate)
|
||||
{
|
||||
LogMessage("MoveAxis", $"Axis={axis} rate={rate}");
|
||||
@@ -1573,7 +1570,7 @@ namespace ASCOM.Meade.net
|
||||
SetSlewingMinEndTime();
|
||||
}
|
||||
|
||||
_movingPrimary = false;
|
||||
SharedResourcesWrapper.MovingPrimary = false;
|
||||
SharedResourcesWrapper.SendBlind("Qe");
|
||||
//:Qe# Halt eastward Slews
|
||||
//Returns: Nothing
|
||||
@@ -1585,17 +1582,13 @@ namespace ASCOM.Meade.net
|
||||
SharedResourcesWrapper.SendBlind("Me");
|
||||
//:Me# Move Telescope East at current slew rate
|
||||
//Returns: Nothing
|
||||
_movingPrimary = true;
|
||||
// in principle we could calculate the current side of pier, but unknown is the safer option.
|
||||
SharedResourcesWrapper.SideOfPier = PierSide.pierUnknown;
|
||||
SharedResourcesWrapper.MovingPrimary = true;
|
||||
break;
|
||||
case ComparisonResult.Lower:
|
||||
SharedResourcesWrapper.SendBlind("Mw");
|
||||
//:Mw# Move Telescope West at current slew rate
|
||||
//Returns: Nothing
|
||||
_movingPrimary = true;
|
||||
// in principle we could calculate the current side of pier, but unknown is the safer option.
|
||||
SharedResourcesWrapper.SideOfPier = PierSide.pierUnknown;
|
||||
SharedResourcesWrapper.MovingPrimary = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1607,7 +1600,7 @@ namespace ASCOM.Meade.net
|
||||
{
|
||||
SetSlewingMinEndTime();
|
||||
}
|
||||
_movingSecondary = false;
|
||||
SharedResourcesWrapper.MovingSecondary = false;
|
||||
SharedResourcesWrapper.SendBlind("Qn");
|
||||
//:Qn# Halt northward Slews
|
||||
//Returns: Nothing
|
||||
@@ -1619,13 +1612,13 @@ namespace ASCOM.Meade.net
|
||||
SharedResourcesWrapper.SendBlind("Mn");
|
||||
//:Mn# Move Telescope North at current slew rate
|
||||
//Returns: Nothing
|
||||
_movingSecondary = true;
|
||||
SharedResourcesWrapper.MovingSecondary = true;
|
||||
break;
|
||||
case ComparisonResult.Lower:
|
||||
SharedResourcesWrapper.SendBlind("Ms");
|
||||
//:Ms# Move Telescope South at current slew rate
|
||||
//Returns: Nothing
|
||||
_movingSecondary = true;
|
||||
SharedResourcesWrapper.MovingSecondary = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1695,11 +1688,11 @@ namespace ASCOM.Meade.net
|
||||
_isGuiding = true;
|
||||
try
|
||||
{
|
||||
if (_movingPrimary &&
|
||||
if (SharedResourcesWrapper.MovingPrimary &&
|
||||
(direction == GuideDirections.guideEast || direction == GuideDirections.guideWest))
|
||||
throw new InvalidOperationException("Unable to PulseGuide while moving same axis.");
|
||||
|
||||
if (_movingSecondary &&
|
||||
if (SharedResourcesWrapper.MovingSecondary &&
|
||||
(direction == GuideDirections.guideNorth || direction == GuideDirections.guideSouth))
|
||||
throw new InvalidOperationException("Unable to PulseGuide while moving same axis.");
|
||||
|
||||
@@ -2279,11 +2272,9 @@ namespace ASCOM.Meade.net
|
||||
if (_isGuiding)
|
||||
return false;
|
||||
|
||||
return _movingPrimary || _movingSecondary;
|
||||
return SharedResourcesWrapper.MovingPrimary || SharedResourcesWrapper.MovingSecondary;
|
||||
}
|
||||
|
||||
private DateTime _earliestNonSlewingTime = DateTime.MinValue;
|
||||
|
||||
public bool Slewing
|
||||
{
|
||||
get
|
||||
@@ -2292,7 +2283,7 @@ namespace ASCOM.Meade.net
|
||||
|
||||
if (isSlewing)
|
||||
SetSlewingMinEndTime();
|
||||
else if (_clock.UtcNow < _earliestNonSlewingTime)
|
||||
else if (_clock.UtcNow < SharedResourcesWrapper.EarliestNonSlewingTime)
|
||||
isSlewing = true;
|
||||
|
||||
LogMessage("Slewing", $"Result = {isSlewing}");
|
||||
@@ -2302,7 +2293,7 @@ namespace ASCOM.Meade.net
|
||||
|
||||
private void SetSlewingMinEndTime()
|
||||
{
|
||||
_earliestNonSlewingTime = _clock.UtcNow + GetTotalSlewingSettleTime();
|
||||
SharedResourcesWrapper.EarliestNonSlewingTime = _clock.UtcNow + GetTotalSlewingSettleTime();
|
||||
}
|
||||
|
||||
private TimeSpan GetTotalSlewingSettleTime()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\NUnit3TestAdapter.3.13.0\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.13.0\build\net35\NUnit3TestAdapter.props')" />
|
||||
<Import Project="..\packages\NUnit.3.13.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.13.0\build\NUnit.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
@@ -98,6 +99,10 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="SharedResourcesUnitTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ThreadSafeBoolTests.cs" />
|
||||
<Compile Include="ThreadSafeDateTimeTests.cs" />
|
||||
<Compile Include="ThreadSafeEnumTests.cs" />
|
||||
<Compile Include="ThreadSafeNullableDoubleTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Meade.net\Meade.net.csproj">
|
||||
@@ -116,5 +121,6 @@
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\NUnit.3.13.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.13.0\build\NUnit.props'))" />
|
||||
<Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.13.0\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.13.0\build\net35\NUnit3TestAdapter.props'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,39 @@
|
||||
using ASCOM.Meade.net;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Meade.net.UnitTests
|
||||
{
|
||||
public class ThreadSafeBoolTests
|
||||
{
|
||||
[TestCase(false)]
|
||||
[TestCase(true)]
|
||||
public void WhenConvertedValueIsSame(bool value)
|
||||
{
|
||||
// given
|
||||
ThreadSafeBool sut = value;
|
||||
|
||||
// when
|
||||
bool actual = sut;
|
||||
|
||||
// then
|
||||
Assert.That(actual, Is.EqualTo(value));
|
||||
}
|
||||
|
||||
[TestCase(false, false)]
|
||||
[TestCase(false, true)]
|
||||
[TestCase(true, false)]
|
||||
[TestCase(true, true)]
|
||||
public void WhenSetValueIsChanged(bool value, bool setValue)
|
||||
{
|
||||
// given
|
||||
ThreadSafeBool sut = value;
|
||||
|
||||
// when
|
||||
sut.Set(setValue);
|
||||
bool afterset = sut;
|
||||
|
||||
// then
|
||||
Assert.That(afterset, Is.EqualTo(setValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using ASCOM.Meade.net;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Meade.net.UnitTests
|
||||
{
|
||||
public class ThreadSafeDateTimeTests
|
||||
{
|
||||
[TestCaseSource(nameof(DateTimeSource))]
|
||||
public void WhenConvertedValueIsSame(DateTime value)
|
||||
{
|
||||
// given
|
||||
ThreadSafeDateTime sut = value;
|
||||
|
||||
// when
|
||||
DateTime actual = sut;
|
||||
|
||||
// then
|
||||
Assert.That(actual, Is.EqualTo(value));
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(DateTimeSetSource))]
|
||||
public void WhenSetValueIsChanged(DateTime value, DateTime setValue)
|
||||
{
|
||||
// given
|
||||
ThreadSafeDateTime sut = value;
|
||||
|
||||
// when
|
||||
sut.Set(setValue);
|
||||
DateTime afterset = sut;
|
||||
|
||||
// then
|
||||
Assert.That(afterset, Is.EqualTo(setValue));
|
||||
}
|
||||
|
||||
static readonly DateTime Example1 = DateTimeOffset.Parse("2012-05-09T02:10:31.296761Z", CultureInfo.InvariantCulture).UtcDateTime;
|
||||
static readonly DateTime Example2 = DateTimeOffset.Parse("2051-03-09T23:15:11.556081Z", CultureInfo.InvariantCulture).UtcDateTime;
|
||||
|
||||
static IEnumerable<DateTime> DateTimeSource => new[]
|
||||
{
|
||||
DateTime.MinValue,
|
||||
Example1,
|
||||
Example2
|
||||
};
|
||||
|
||||
static IEnumerable<TestCaseData> DateTimeSetSource => new[]
|
||||
{
|
||||
new TestCaseData(DateTime.MinValue, Example1),
|
||||
new TestCaseData(DateTime.MinValue, Example2),
|
||||
new TestCaseData(DateTime.MinValue, DateTime.MinValue),
|
||||
new TestCaseData(Example1, Example1),
|
||||
new TestCaseData(Example1, Example2),
|
||||
new TestCaseData(Example1, DateTime.MinValue),
|
||||
new TestCaseData(Example2, Example1),
|
||||
new TestCaseData(Example2, Example2),
|
||||
new TestCaseData(Example2, DateTime.MinValue)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using ASCOM.DeviceInterface;
|
||||
using ASCOM.Meade.net;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Meade.net.UnitTests
|
||||
{
|
||||
public class ThreadSafeEnumTests
|
||||
{
|
||||
[TestCase(PierSide.pierUnknown)]
|
||||
[TestCase(PierSide.pierEast)]
|
||||
[TestCase(PierSide.pierWest)]
|
||||
public void WhenConvertedValueIsSame(PierSide value)
|
||||
{
|
||||
// given
|
||||
ThreadSafeEnum<PierSide> sut = value;
|
||||
|
||||
// when
|
||||
PierSide actual = sut;
|
||||
|
||||
// then
|
||||
Assert.That(actual, Is.EqualTo(value));
|
||||
}
|
||||
|
||||
[TestCase(PierSide.pierUnknown, PierSide.pierUnknown)]
|
||||
[TestCase(PierSide.pierUnknown, PierSide.pierUnknown)]
|
||||
[TestCase(PierSide.pierUnknown, PierSide.pierUnknown)]
|
||||
[TestCase(PierSide.pierEast, PierSide.pierUnknown)]
|
||||
[TestCase(PierSide.pierEast, PierSide.pierWest)]
|
||||
[TestCase(PierSide.pierEast, PierSide.pierEast)]
|
||||
[TestCase(PierSide.pierWest, PierSide.pierUnknown)]
|
||||
[TestCase(PierSide.pierWest, PierSide.pierWest)]
|
||||
[TestCase(PierSide.pierWest, PierSide.pierEast)]
|
||||
public void WhenSetValueIsChanged(PierSide value, PierSide setValue)
|
||||
{
|
||||
// given
|
||||
ThreadSafeEnum<PierSide> sut = value;
|
||||
|
||||
// when
|
||||
sut.Set(setValue);
|
||||
PierSide afterset = sut;
|
||||
|
||||
// then
|
||||
Assert.That(afterset, Is.EqualTo(setValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using ASCOM.Meade.net;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Meade.net.UnitTests
|
||||
{
|
||||
public class ThreadSafeNullableDoubleTests
|
||||
{
|
||||
[TestCase(0.1d)]
|
||||
[TestCase(-12.34d)]
|
||||
[TestCase(0d)]
|
||||
[TestCase(null)]
|
||||
public void WhenConvertedValueIsSame(double? value)
|
||||
{
|
||||
// given
|
||||
ThreadSafeNullableDouble sut = value;
|
||||
|
||||
// when
|
||||
double? actual = sut;
|
||||
|
||||
// then
|
||||
Assert.That(actual, Is.EqualTo(value));
|
||||
}
|
||||
|
||||
[TestCase(0.1d, 0.2d)]
|
||||
[TestCase(-12.34d, 5d)]
|
||||
[TestCase(0d, 1d)]
|
||||
[TestCase(null, 2d)]
|
||||
[TestCase(0.1d, null)]
|
||||
[TestCase(-12.34d, null)]
|
||||
[TestCase(0d, null)]
|
||||
[TestCase(null, null)]
|
||||
public void WhenSetValueIsChanged(double? value, double? setValue)
|
||||
{
|
||||
// given
|
||||
ThreadSafeNullableDouble sut = value;
|
||||
|
||||
// when
|
||||
sut.Set(setValue);
|
||||
double? afterset = sut;
|
||||
|
||||
// then
|
||||
Assert.That(afterset, Is.EqualTo(setValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@
|
||||
<package id="JetBrains.Annotations" version="2020.3.0" targetFramework="net472" />
|
||||
<package id="Moq" version="4.15.2" targetFramework="net472" />
|
||||
<package id="NUnit" version="3.13.0" targetFramework="net472" />
|
||||
<package id="NUnit.ConsoleRunner" version="3.12.0" targetFramework="net472" />
|
||||
<package id="NUnit3TestAdapter" version="3.13.0" targetFramework="net472" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="5.0.0" targetFramework="net472" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
|
||||
</packages>
|
||||
@@ -146,6 +146,10 @@
|
||||
<Compile Include="ProfileProperties.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TelescopeList.cs" />
|
||||
<Compile Include="ThreadSafeBool.cs" />
|
||||
<Compile Include="ThreadSafeDateTime.cs" />
|
||||
<Compile Include="ThreadSafeEnum.cs" />
|
||||
<Compile Include="ThreadSafeNullableDouble.cs" />
|
||||
<Compile Include="Win32Utilities.cs" />
|
||||
<Compile Include="Wrapper\IProfileWrapper.cs" />
|
||||
<Compile Include="Wrapper\SharedResourcesWrapper.cs" />
|
||||
|
||||
@@ -19,6 +19,7 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.AccessControl;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using ASCOM.DeviceInterface;
|
||||
using ASCOM.Meade.net.Wrapper;
|
||||
@@ -245,7 +246,7 @@ namespace ASCOM.Meade.net
|
||||
private const string HandShakeDefault = "None";
|
||||
private const string ParityDefault = "None";
|
||||
private const string SendDateTimeDefault = "false";
|
||||
private static string ParkedBehaviourDefault = "No Coordinates";
|
||||
private const string ParkedBehaviourDefault = "No Coordinates";
|
||||
private const string ParkedAltDefault = "0";
|
||||
private const string ParkedAzimuthDefault = "180";
|
||||
|
||||
@@ -501,22 +502,78 @@ namespace ASCOM.Meade.net
|
||||
ParkedPosition = parkedPosition;
|
||||
}
|
||||
|
||||
public static bool IsParked { get; private set; }
|
||||
private static readonly ThreadSafeBool _isParked = false;
|
||||
public static bool IsParked
|
||||
{
|
||||
get => _isParked;
|
||||
private set => _isParked.Set(value);
|
||||
}
|
||||
|
||||
public static ParkedPosition ParkedPosition { get; private set; }
|
||||
private static ParkedPosition _parkedPosition;
|
||||
public static ParkedPosition ParkedPosition
|
||||
{
|
||||
get => _parkedPosition;
|
||||
private set => Interlocked.Exchange(ref _parkedPosition, value);
|
||||
}
|
||||
|
||||
private static readonly ThreadSafeEnum<PierSide> _sideOfPier = PierSide.pierUnknown;
|
||||
/// <summary>
|
||||
/// Start with <see cref="PierSide.pierUnknown"/>.
|
||||
/// As we do not know the physical declination axis position, we have to keep track manually.
|
||||
/// </summary>
|
||||
public static PierSide SideOfPier { get; internal set; } = PierSide.pierUnknown;
|
||||
public static PierSide SideOfPier
|
||||
{
|
||||
get => _sideOfPier;
|
||||
internal set => _sideOfPier.Set(value);
|
||||
}
|
||||
|
||||
public static double? TargetRightAscension { get; internal set; }
|
||||
private static readonly ThreadSafeNullableDouble _targetRightAscension = null as double?;
|
||||
public static double? TargetRightAscension
|
||||
{
|
||||
get => _targetRightAscension;
|
||||
internal set => _targetRightAscension.Set(value);
|
||||
}
|
||||
|
||||
public static double? TargetDeclination { get; internal set; }
|
||||
private static readonly ThreadSafeNullableDouble _targetDeclination = null as double?;
|
||||
public static double? TargetDeclination
|
||||
{
|
||||
get => _targetDeclination;
|
||||
internal set => _targetDeclination.Set(value);
|
||||
}
|
||||
|
||||
public static short SlewSettleTime { get; internal set; }
|
||||
private static int _slewSettleTime;
|
||||
public static short SlewSettleTime
|
||||
{
|
||||
get => Convert.ToInt16(_slewSettleTime);
|
||||
internal set => Interlocked.Exchange(ref _slewSettleTime, value);
|
||||
}
|
||||
|
||||
public static bool IsLongFormat { get; internal set; }
|
||||
private static readonly ThreadSafeBool _isLongFormat = false;
|
||||
public static bool IsLongFormat
|
||||
{
|
||||
get => _isLongFormat;
|
||||
internal set => _isLongFormat.Set(value);
|
||||
}
|
||||
|
||||
private static readonly ThreadSafeBool _movingPrimary = false;
|
||||
public static bool MovingPrimary
|
||||
{
|
||||
get => _movingPrimary;
|
||||
internal set => _movingPrimary.Set(value);
|
||||
}
|
||||
|
||||
private static readonly ThreadSafeBool _movingSecondary = false;
|
||||
public static bool MovingSecondary
|
||||
{
|
||||
get => _movingSecondary;
|
||||
internal set => _movingSecondary.Set(value);
|
||||
}
|
||||
|
||||
private static readonly ThreadSafeDateTime _earliestNonSlewingTime = DateTime.MinValue;
|
||||
public static DateTime EarliestNonSlewingTime
|
||||
{
|
||||
get => _earliestNonSlewingTime;
|
||||
internal set => _earliestNonSlewingTime.Set(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Threading;
|
||||
|
||||
namespace ASCOM.Meade.net
|
||||
{
|
||||
public class ThreadSafeBool
|
||||
{
|
||||
private object _value;
|
||||
|
||||
public ThreadSafeBool(in bool value) => _value = value;
|
||||
|
||||
public void Set(in bool value) => Interlocked.Exchange(ref _value, value);
|
||||
|
||||
public static implicit operator ThreadSafeBool(in bool value) => new ThreadSafeBool(value);
|
||||
|
||||
public static implicit operator bool(ThreadSafeBool @this) => (bool)@this._value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace ASCOM.Meade.net
|
||||
{
|
||||
public class ThreadSafeDateTime
|
||||
{
|
||||
private long _value;
|
||||
|
||||
public ThreadSafeDateTime(in DateTime value) => _value = DateTimeToLong(value);
|
||||
|
||||
public void Set(in DateTime value) => Interlocked.Exchange(ref _value, DateTimeToLong(value));
|
||||
|
||||
private static long DateTimeToLong(in DateTime value) => value.ToUniversalTime().Ticks;
|
||||
|
||||
public static implicit operator ThreadSafeDateTime(in DateTime value) => new ThreadSafeDateTime(value);
|
||||
|
||||
public static implicit operator DateTime(ThreadSafeDateTime @this) => new DateTime(Interlocked.Read(ref @this._value), DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace ASCOM.Meade.net
|
||||
{
|
||||
public class ThreadSafeEnum<T>
|
||||
where T: struct, Enum
|
||||
{
|
||||
private long _value;
|
||||
|
||||
public ThreadSafeEnum(T value) => _value = EnumToLong(value);
|
||||
|
||||
public void Set(T value) => Interlocked.Exchange(ref _value, EnumToLong(value));
|
||||
|
||||
private static long EnumToLong(T value) => Convert.ToInt64(value);
|
||||
|
||||
public static implicit operator ThreadSafeEnum<T>(T value) => new ThreadSafeEnum<T>(value);
|
||||
|
||||
public static implicit operator T(ThreadSafeEnum<T> @this) => (T) Enum.ToObject(typeof(T), Interlocked.Read(ref @this._value));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace ASCOM.Meade.net
|
||||
{
|
||||
public class ThreadSafeNullableDouble
|
||||
{
|
||||
private long _value;
|
||||
|
||||
public ThreadSafeNullableDouble(in double? value) => _value = NullableDoubleToLong(value);
|
||||
|
||||
public void Set(in double? value) => Interlocked.Exchange(ref _value, NullableDoubleToLong(value));
|
||||
|
||||
private static long NullableDoubleToLong(in double? value) => BitConverter.DoubleToInt64Bits(value ?? double.NaN);
|
||||
|
||||
public static implicit operator ThreadSafeNullableDouble(in double? value) => new ThreadSafeNullableDouble(value);
|
||||
|
||||
public static implicit operator double?(ThreadSafeNullableDouble @this)
|
||||
{
|
||||
var doubleValue = BitConverter.Int64BitsToDouble(Interlocked.Read(ref @this._value));
|
||||
return double.IsNaN(doubleValue) ? null as double? : doubleValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,12 @@ namespace ASCOM.Meade.net.Wrapper
|
||||
short SlewSettleTime { get; set; }
|
||||
|
||||
bool IsLongFormat { get; set; }
|
||||
|
||||
bool MovingPrimary { get; set; }
|
||||
|
||||
bool MovingSecondary { get; set; }
|
||||
|
||||
DateTime EarliestNonSlewingTime { get; set; }
|
||||
}
|
||||
|
||||
public class SharedResourcesWrapper : ISharedResourcesWrapper
|
||||
@@ -151,5 +157,23 @@ namespace ASCOM.Meade.net.Wrapper
|
||||
get => SharedResources.IsLongFormat;
|
||||
set => SharedResources.IsLongFormat = value;
|
||||
}
|
||||
|
||||
public bool MovingPrimary
|
||||
{
|
||||
get => SharedResources.MovingPrimary;
|
||||
set => SharedResources.MovingPrimary = value;
|
||||
}
|
||||
|
||||
public bool MovingSecondary
|
||||
{
|
||||
get => SharedResources.MovingSecondary;
|
||||
set => SharedResources.MovingSecondary = value;
|
||||
}
|
||||
|
||||
public DateTime EarliestNonSlewingTime
|
||||
{
|
||||
get => SharedResources.EarliestNonSlewingTime;
|
||||
set => SharedResources.EarliestNonSlewingTime = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user