diff --git a/CHANGELOG.md b/CHANGELOG.md
index da1e65f..5adbe94 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,8 +5,24 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
+
+## [8.3.0] - 2019-01-25
+### Added
+ - Added SimplSharpProMono to eRuntimeEnvironment enum
+ - Added path support for SimplSharpProMono environment
+ - Added GetApplicationRootDirectory for all platforms
+
+### Changed
+ - Small fixes for better VC4 support
+
+## [8.2.0] - 2019-01-10
+### Added
+ - Added TryGetPortForScheme method to UriExtensions
+ - Added range attribute for clarifying numeric fields, properties and parameters
+
### Changed
- IcdHashSet preserves comparer when an operation creates a new IcdHashSet
+ - Fixed bug where XML fragments on Net Standard were being prepended with a document header
## [8.1.0] - 2019-01-02
### Added
diff --git a/ICD.Common.Utils/EventArguments/BoolEventArgs.cs b/ICD.Common.Utils/EventArguments/BoolEventArgs.cs
index 56d6c66..c73580c 100644
--- a/ICD.Common.Utils/EventArguments/BoolEventArgs.cs
+++ b/ICD.Common.Utils/EventArguments/BoolEventArgs.cs
@@ -6,7 +6,17 @@
/// Constructor.
///
///
- public BoolEventArgs(bool data) : base(data)
+ public BoolEventArgs(bool data)
+ : base(data)
+ {
+ }
+
+ ///
+ /// Constructor.
+ ///
+ ///
+ public BoolEventArgs(BoolEventArgs eventArgs)
+ : this(eventArgs.Data)
{
}
}
diff --git a/ICD.Common.Utils/EventArguments/StringEventArgs.cs b/ICD.Common.Utils/EventArguments/StringEventArgs.cs
index 56acfa8..db25463 100644
--- a/ICD.Common.Utils/EventArguments/StringEventArgs.cs
+++ b/ICD.Common.Utils/EventArguments/StringEventArgs.cs
@@ -9,5 +9,14 @@
public StringEventArgs(string data) : base(data)
{
}
+
+ ///
+ /// Constructor.
+ ///
+ ///
+ public StringEventArgs(StringEventArgs eventArgs)
+ : base(eventArgs.Data)
+ {
+ }
}
}
diff --git a/ICD.Common.Utils/Extensions/StringExtensions.cs b/ICD.Common.Utils/Extensions/StringExtensions.cs
index d1828e3..e1be90e 100644
--- a/ICD.Common.Utils/Extensions/StringExtensions.cs
+++ b/ICD.Common.Utils/Extensions/StringExtensions.cs
@@ -221,5 +221,29 @@ namespace ICD.Common.Utils.Extensions
return extends.Contains(character.ToString());
}
+
+ ///
+ /// Generates a hashcode that is consistent between program executions.
+ ///
+ ///
+ ///
+ public static int GetStableHashCode(this string extends)
+ {
+ unchecked
+ {
+ int hash1 = 5381;
+ int hash2 = hash1;
+
+ for (int i = 0; i < extends.Length && extends[i] != '\0'; i += 2)
+ {
+ hash1 = ((hash1 << 5) + hash1) ^ extends[i];
+ if (i == extends.Length - 1 || extends[i + 1] == '\0')
+ break;
+ hash2 = ((hash2 << 5) + hash2) ^ extends[i + 1];
+ }
+
+ return hash1 + (hash2 * 1566083941);
+ }
+ }
}
}
diff --git a/ICD.Common.Utils/GuidUtils.cs b/ICD.Common.Utils/GuidUtils.cs
new file mode 100644
index 0000000..d68feb6
--- /dev/null
+++ b/ICD.Common.Utils/GuidUtils.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace ICD.Common.Utils
+{
+ public static class GuidUtils
+ {
+ public static Guid GenerateSeeded(int seed)
+ {
+ Random seeded = new Random(seed);
+ byte[] bytes = new byte[16];
+
+ seeded.NextBytes(bytes);
+
+ return new Guid(bytes);
+ }
+ }
+}
diff --git a/ICD.Common.Utils/ICD.Common.Utils_SimplSharp.csproj b/ICD.Common.Utils/ICD.Common.Utils_SimplSharp.csproj
index 103d153..297b013 100644
--- a/ICD.Common.Utils/ICD.Common.Utils_SimplSharp.csproj
+++ b/ICD.Common.Utils/ICD.Common.Utils_SimplSharp.csproj
@@ -112,6 +112,7 @@
+
diff --git a/ICD.Common.Utils/IO/IcdDirectory.cs b/ICD.Common.Utils/IO/IcdDirectory.cs
index 3ac77ad..27b3c31 100644
--- a/ICD.Common.Utils/IO/IcdDirectory.cs
+++ b/ICD.Common.Utils/IO/IcdDirectory.cs
@@ -2,6 +2,7 @@
#if SIMPLSHARP
using Crestron.SimplSharp.CrestronIO;
#else
+using ICD.Common.Utils.Extensions;
using System.IO;
using Microsoft.DotNet.PlatformAbstractions;
#endif
@@ -19,6 +20,19 @@ namespace ICD.Common.Utils.IO
#endif
}
+ ///
+ /// This gets the application root directory for Crestron systems
+ ///
+ ///
+ public static string GetApplicationRootDirectory()
+ {
+#if SIMPLSHARP
+ return Directory.GetApplicationRootDirectory();
+#else
+ return Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetPath());
+#endif
+ }
+
public static bool Exists(string path)
{
if (path == null)
diff --git a/ICD.Common.Utils/IcdConsole.cs b/ICD.Common.Utils/IcdConsole.cs
index 5ca1894..fe00a64 100644
--- a/ICD.Common.Utils/IcdConsole.cs
+++ b/ICD.Common.Utils/IcdConsole.cs
@@ -123,6 +123,10 @@ namespace ICD.Common.Utils
public static bool SendControlSystemCommand(string command, ref string result)
{
#if SIMPLSHARP
+ // No console on VC4
+ if (IcdEnvironment.RuntimeEnvironment == IcdEnvironment.eRuntimeEnvironment.SimplSharpProMono)
+ return false;
+
return CrestronConsole.SendControlSystemCommand(command, ref result);
#else
return false;
diff --git a/ICD.Common.Utils/IcdEnvironment.SimplSharp.cs b/ICD.Common.Utils/IcdEnvironment.SimplSharp.cs
index ce5f344..ce42e79 100644
--- a/ICD.Common.Utils/IcdEnvironment.SimplSharp.cs
+++ b/ICD.Common.Utils/IcdEnvironment.SimplSharp.cs
@@ -12,7 +12,12 @@ namespace ICD.Common.Utils
public static eRuntimeEnvironment RuntimeEnvironment
{
- get { return GetRuntimeEnvironment(CrestronEnvironment.RuntimeEnvironment); }
+ get
+ {
+ return CrestronEnvironment.DevicePlatform == eDevicePlatform.Server
+ ? eRuntimeEnvironment.SimplSharpProMono
+ : GetRuntimeEnvironment(CrestronEnvironment.RuntimeEnvironment);
+ }
}
///
diff --git a/ICD.Common.Utils/IcdEnvironment.cs b/ICD.Common.Utils/IcdEnvironment.cs
index f947cab..f0d6a36 100644
--- a/ICD.Common.Utils/IcdEnvironment.cs
+++ b/ICD.Common.Utils/IcdEnvironment.cs
@@ -11,6 +11,7 @@ namespace ICD.Common.Utils
{
SimplSharp,
SimplSharpPro,
+ SimplSharpProMono,
Standard
}
diff --git a/ICD.Common.Utils/PathUtils.cs b/ICD.Common.Utils/PathUtils.cs
index 491fbae..64e21a6 100644
--- a/ICD.Common.Utils/PathUtils.cs
+++ b/ICD.Common.Utils/PathUtils.cs
@@ -17,7 +17,15 @@ namespace ICD.Common.Utils
/// Gets the path to the root directory of the processor.
///
[PublicAPI]
- public static string RootPath { get { return IcdDirectory.GetDirectoryRoot("\\"); } }
+ public static string RootPath {
+ get
+ {
+ if (IcdEnvironment.RuntimeEnvironment == IcdEnvironment.eRuntimeEnvironment.SimplSharpProMono)
+ return IcdDirectory.GetApplicationRootDirectory();
+
+ return IcdDirectory.GetDirectoryRoot(IcdPath.DirectorySeparatorChar.ToString());
+ }
+ }
///
/// Gets the path to the program directory
@@ -35,7 +43,7 @@ namespace ICD.Common.Utils
get
{
#if SIMPLSHARP
- return Join(RootPath, "USER");
+ return Join(RootPath, "User");
#elif LINUX
return Join(RootPath, "opt", "ICD.Connect");
#else
@@ -53,6 +61,9 @@ namespace ICD.Common.Utils
{
get
{
+ if (IcdEnvironment.RuntimeEnvironment == IcdEnvironment.eRuntimeEnvironment.SimplSharpProMono)
+ return Join(RootConfigPath, "ProgramConfig");
+
string directoryName = string.Format("Program{0:D2}Config", ProgramUtils.ProgramNumber);
return Join(RootConfigPath, directoryName);
}
diff --git a/ICD.Common.Utils/ProgramUtils.cs b/ICD.Common.Utils/ProgramUtils.cs
index d291371..91fbdbf 100644
--- a/ICD.Common.Utils/ProgramUtils.cs
+++ b/ICD.Common.Utils/ProgramUtils.cs
@@ -33,6 +33,10 @@ namespace ICD.Common.Utils
name = name.Substring(0, proLength).PadRight(26);
break;
+ case IcdEnvironment.eRuntimeEnvironment.SimplSharpProMono:
+ // No console
+ return;
+
case IcdEnvironment.eRuntimeEnvironment.Standard:
name += ' ';
break;
diff --git a/ICD.Common.Utils/Properties/AssemblyInfo.cs b/ICD.Common.Utils/Properties/AssemblyInfo.cs
index 4497a46..6df4043 100644
--- a/ICD.Common.Utils/Properties/AssemblyInfo.cs
+++ b/ICD.Common.Utils/Properties/AssemblyInfo.cs
@@ -4,4 +4,4 @@ using System.Reflection;
[assembly: AssemblyCompany("ICD Systems")]
[assembly: AssemblyProduct("ICD.Common.Utils")]
[assembly: AssemblyCopyright("Copyright © ICD Systems 2018")]
-[assembly: AssemblyVersion("8.1.0.0")]
+[assembly: AssemblyVersion("8.3.0.0")]
diff --git a/ICD.Common.Utils/ReflectionUtils.cs b/ICD.Common.Utils/ReflectionUtils.cs
index a5b1ff6..e2a2ddf 100644
--- a/ICD.Common.Utils/ReflectionUtils.cs
+++ b/ICD.Common.Utils/ReflectionUtils.cs
@@ -4,8 +4,6 @@ using System.Linq;
using ICD.Common.Properties;
using ICD.Common.Utils.Extensions;
using ICD.Common.Utils.IO;
-using ICD.Common.Utils.Services;
-using ICD.Common.Utils.Services.Logging;
#if SIMPLSHARP
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.Reflection;
@@ -170,6 +168,7 @@ namespace ICD.Common.Utils
///
///
///
+ [NotNull]
public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method)
{
return
@@ -185,6 +184,7 @@ namespace ICD.Common.Utils
/// Creates an instance of the given type, calling the default constructor.
///
///
+ [NotNull]
public static T CreateInstance(Type type)
{
if (type == null)
@@ -198,6 +198,7 @@ namespace ICD.Common.Utils
///
///
///
+ [NotNull]
public static T CreateInstance(params object[] parameters)
{
if (parameters == null)
@@ -210,6 +211,7 @@ namespace ICD.Common.Utils
/// Creates an instance of the given type, calling the default constructor.
///
///
+ [NotNull]
public static object CreateInstance(Type type, params object[] parameters)
{
if (type == null)
@@ -218,28 +220,7 @@ namespace ICD.Common.Utils
if (parameters == null)
throw new ArgumentNullException("parameters");
- ConstructorInfo constructor = null;
-
- try
- {
- constructor = GetConstructor(type, parameters);
- }
- catch (ArgumentException e)
- {
- var logger = ServiceProvider.GetService();
-
- logger.AddEntry(eSeverity.Error, "Could not find constructor while attempting to create instance.");
- logger.AddEntry(eSeverity.Error, "Attempted to create an instance of type {0}", type.ToString());
- logger.AddEntry(eSeverity.Error, "With the following parameters:");
- foreach (var param in parameters)
- {
- logger.AddEntry(eSeverity.Error, "Type:{0}, Value:{1}", param.GetType().ToString(), param.ToString());
- }
- logger.AddEntry(eSeverity.Error, "No valid constructor exists for this set of parameters.");
- }
-
- if (constructor == null)
- return null;
+ ConstructorInfo constructor = GetConstructor(type, parameters);
try
{
@@ -289,6 +270,7 @@ namespace ICD.Common.Utils
///
///
///
+ [NotNull]
public static Assembly LoadAssemblyFromPath(string path)
{
if (path == null)
@@ -377,6 +359,7 @@ namespace ICD.Common.Utils
/// The instance with the callback MethodInfo. Null for static types.
/// The MethodInfo for the callback method.
///
+ [NotNull]
public static Delegate SubscribeEvent(object instance, EventInfo eventInfo, object handler, MethodInfo callback)
{
if (eventInfo == null)
diff --git a/ICD.Common.Utils/Timers/SafeTimer.cs b/ICD.Common.Utils/Timers/SafeTimer.cs
index 526c80e..1047f7d 100644
--- a/ICD.Common.Utils/Timers/SafeTimer.cs
+++ b/ICD.Common.Utils/Timers/SafeTimer.cs
@@ -20,7 +20,7 @@ namespace ICD.Common.Utils.Timers
private readonly Timer m_Timer;
private int m_RepeatPeriod;
#endif
- private readonly Action m_Callback;
+ private Action m_Callback;
///
/// Returns true if this instance has been disposed.
@@ -88,6 +88,8 @@ namespace ICD.Common.Utils.Timers
Stop();
m_Timer.Dispose();
+ m_Callback = null;
+
IsDisposed = true;
}
diff --git a/ICD.Common.Utils/Xml/AbstractGenericXmlConverter.cs b/ICD.Common.Utils/Xml/AbstractGenericXmlConverter.cs
index e8fafcf..1673858 100644
--- a/ICD.Common.Utils/Xml/AbstractGenericXmlConverter.cs
+++ b/ICD.Common.Utils/Xml/AbstractGenericXmlConverter.cs
@@ -48,7 +48,9 @@ namespace ICD.Common.Utils.Xml
if (writer == null)
throw new ArgumentNullException("writer");
+// ReSharper disable CompareNonConstrainedGenericWithNull
if (value == null)
+// ReSharper restore CompareNonConstrainedGenericWithNull
{
writer.WriteElementString(elementName, null);
return;