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;