This shows you the differences between two versions of the page.
Previous revisionNext revision | |||
— | fuss:csharp [2019/08/22 07:32] – [Recursive] office | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== | ||
+ | |||
+ | Some functions are implemented as part of the Wizardry and Steamworks portable library class (PCL) and the full library can be retrieved from SVN by checking out the following repository: | ||
+ | |||
+ | * [[http:// | ||
+ | |||
+ | The PCL targets: | ||
+ | |||
+ | * .NET Framework 4.5.1 | ||
+ | * Microsoft Windows 8.1 | ||
+ | * Windows Phone 8.1 | ||
+ | |||
+ | ====== Linq Number of Times ====== | ||
+ | |||
+ | Use the following one-liner to display a line of dashes that goes goes from one end of the terminal to the other: | ||
+ | <code C#> | ||
+ | new List< | ||
+ | </ | ||
+ | which creates an empty list of integers of size '' | ||
+ | |||
+ | ====== Assemblies in Different Directory ====== | ||
+ | |||
+ | Assemblies can be loaded from a different directory by creating an '' | ||
+ | |||
+ | <code xml> | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | This will make the application to look for the assemblies in the '' | ||
+ | |||
+ | ====== Get Memory Currently In-Use by Process ====== | ||
+ | |||
+ | '' | ||
+ | |||
+ | <code c#> | ||
+ | System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess(); | ||
+ | int freeBytes = proc.PrivateMemorySize64; | ||
+ | </ | ||
+ | |||
+ | ====== Select Even Element of Array ====== | ||
+ | |||
+ | Given the array: | ||
+ | < | ||
+ | [ 0, 1, 2, 3, 4, 5, ... ] | ||
+ | </ | ||
+ | |||
+ | the following LINQ expression: | ||
+ | <code c#> | ||
+ | var a = data.Where((value, | ||
+ | </ | ||
+ | |||
+ | will set a to the array: | ||
+ | < | ||
+ | [ 0, 2, 4, ... ] | ||
+ | </ | ||
+ | |||
+ | ====== Serializing a Structure ====== | ||
+ | |||
+ | Suppose that we have a C# structure that defines a person along with multiple properties for that person and that we want to create a method that will serialize this structure to the [[.: | ||
+ | |||
+ | <code csharp> | ||
+ | public struct Person { | ||
+ | ... | ||
+ | public Person(string name, string address, ...) { | ||
+ | this.name = name; | ||
+ | this.address = address; | ||
+ | } | ||
+ | ... | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// Serializes a structure to a Wizardry and Steamworks key-value data string. | ||
+ | /// </ | ||
+ | private string ToKeyValueData() { | ||
+ | var sb = new StringBuilder(); | ||
+ | object p = new Person(); | ||
+ | foreach(var k in p.GetType().GetProperties()) { | ||
+ | var v = GetType().GetProperty(k.Name).GetValue(this, | ||
+ | if(string.IsNullOrEmpty(v)) continue; | ||
+ | sb.Append(string.Format(" | ||
+ | sb.Append(delimiter); | ||
+ | } | ||
+ | if(sb.Length != 0) sb.Length--; | ||
+ | return sb.ToString(); | ||
+ | } | ||
+ | ... | ||
+ | public string name { get; internal set; } | ||
+ | public string address { get; internal set; } | ||
+ | ... | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | That is done by enumerating the properties of the '' | ||
+ | |||
+ | ====== Temporary Structure ====== | ||
+ | |||
+ | There are cases where you want a wrapper that can hold objects in order to avoid declaring temporary variables (from the series, "can I partially allocate an object?" | ||
+ | |||
+ | <code csharp> | ||
+ | int time = 0; | ||
+ | int greeting = ""; | ||
+ | foreach(var o in ...) { | ||
+ | switch(o) { | ||
+ | case ...: | ||
+ | time = 10; | ||
+ | break; | ||
+ | case ...: | ||
+ | greeting = "Good Day!"; | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | In such cases, a generic object array is more suitable: | ||
+ | <code csharp> | ||
+ | object[2] data = new object[2]; | ||
+ | foreach(var o in ...) { | ||
+ | switch(o) { | ||
+ | case ...: | ||
+ | data[0] = 10; | ||
+ | break; | ||
+ | case ...: | ||
+ | data[1] = "Good Day!"; | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | if(data.Any(o => o == null)) { | ||
+ | // data contains at least one null element | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | This works great as a temporary structure, in order to avoid creating a new class or struct which would live much longer than the inlined generic object. | ||
+ | |||
+ | ====== Get Variable Names ====== | ||
+ | |||
+ | <code csharp> | ||
+ | using System.Linq.Expressions; | ||
+ | ... | ||
+ | string ON; | ||
+ | ... | ||
+ | private static string GetName< | ||
+ | return ((MemberExpression) e.Body).Member.Name; | ||
+ | } | ||
+ | ... | ||
+ | Console.WriteLine(GetName(() => ON)); | ||
+ | </ | ||
+ | |||
+ | ====== Monitoring File Activity ====== | ||
+ | |||
+ | When you have to monitor files for changes or access times, '' | ||
+ | |||
+ | For example, the following filesystem watcher scans the current directory for: | ||
+ | * last access changes. | ||
+ | * last written changes. | ||
+ | * filename changes. | ||
+ | * directory name changes. | ||
+ | |||
+ | installs a filter for '' | ||
+ | |||
+ | <code csharp> | ||
+ | FileSystemWatcher watcher = new FileSystemWatcher(); | ||
+ | watcher.Path = Directory.GetCurrentDirectory(); | ||
+ | watcher.NotifyFilter = NotifyFilters.LastAccess | | ||
+ | | ||
+ | | ||
+ | | ||
+ | watcher.Filter = " | ||
+ | watched.Changed += HandleDirectoryChange; | ||
+ | ... | ||
+ | private static void HandleDirectoryChange(object sender, FileSystemEventArgs e) | ||
+ | { | ||
+ | Console.WriteLine(e.Name); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Note that '' | ||
+ | |||
+ | <code csharp> | ||
+ | watcher.Path = Directory.GetCurrentDirectory(); | ||
+ | watcher.Filter = " | ||
+ | </ | ||
+ | |||
+ | ====== Try to Parse a Nullable Structure ====== | ||
+ | |||
+ | '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | public static bool TryParseNullable< | ||
+ | { | ||
+ | if (string.IsNullOrEmpty(input)) | ||
+ | { | ||
+ | variable = null; | ||
+ | return false; | ||
+ | } | ||
+ | T? localVariable; | ||
+ | try | ||
+ | { | ||
+ | IConvertible convertibleString = input; | ||
+ | localVariable = (T)convertibleString.ToType(typeof(T), | ||
+ | } | ||
+ | catch (Exception) | ||
+ | { | ||
+ | variable = null; | ||
+ | return false; | ||
+ | } | ||
+ | variable = localVariable; | ||
+ | return true; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Get Names and Values of Enumeration Members ====== | ||
+ | |||
+ | Can be done by using reflection: | ||
+ | |||
+ | <code csharp> | ||
+ | foreach (FieldInfo fi in typeof(Molecules).GetFields(BindingFlags.Public | BindingFlags.Static)) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Group a Sequence by Pairs ====== | ||
+ | |||
+ | Suppose you have a set of elements: | ||
+ | < | ||
+ | 10, 20, 30, 40, 50 | ||
+ | </ | ||
+ | |||
+ | and that you want to create sub-sets from successive elements as pairs. Following the example, you want to create the pairs: $(10, 20)$, $(30, 40)$, $(50, 60)$ out of the initial set preferably as key-value pairs. | ||
+ | |||
+ | In that case, there are several solutions, but if you want to use only one LINQ line, then the following expression will return the desired key-value pairs: | ||
+ | <code csharp> | ||
+ | list.Select((o, | ||
+ | .GroupBy(q => q.p/2, q => q.o) | ||
+ | .Select(o => o.ToList()) | ||
+ | .TakeWhile(o => o.Count % 2 == 0) | ||
+ | .ToDictionary(o => o.First(), p => p.Last()) | ||
+ | </ | ||
+ | |||
+ | It does that by: | ||
+ | |||
+ | - grouping odd and even elements together, | ||
+ | - selecting the entire list of groups, | ||
+ | - selecting only matching key-value pairs, | ||
+ | - creating a key value pair from the first element and the last element in the pair-set. | ||
+ | |||
+ | ====== Serialising Comma-Separated Values to a Dictionary using Regular Expressions ====== | ||
+ | |||
+ | Given a comma-separated string ('' | ||
+ | < | ||
+ | Color, Red, Life, Good, Day, Sunday | ||
+ | </ | ||
+ | |||
+ | where the even strings ('' | ||
+ | |||
+ | <code csharp> | ||
+ | using System.Text.RegularExpressions; | ||
+ | //... | ||
+ | Dictionary< | ||
+ | Regex.Matches(command.Attachments, | ||
+ | .Cast< | ||
+ | .ToDictionary(m => m.Groups[" | ||
+ | </ | ||
+ | |||
+ | Note that the regex is sufficiently resistant to abuse, for example, it will work fine if the spaces around the strings are garbled: | ||
+ | < | ||
+ | Color , Red, | ||
+ | </ | ||
+ | |||
+ | Another, better variant is to use a splitting regular expression and then collect the even and odd keys with a bit of LINQ: | ||
+ | <code csharp> | ||
+ | using System.Text.RegularExpressions; | ||
+ | //... | ||
+ | public static Regex CSVRegEx = new Regex(@" | ||
+ | RegexOptions.Compiled); | ||
+ | //... | ||
+ | foreach (KeyValuePair< | ||
+ | .GroupBy(x => x.index/2, x => x.value) | ||
+ | .Select(x => x.ToList()) | ||
+ | .TakeWhile(o => o.Count % 2 == 0) | ||
+ | .ToDictionary(o => o.First(), p => p.Last())) | ||
+ | { | ||
+ | Console.WriteLine(a); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | For more details, see [[fuss/ | ||
+ | ====== Convert HashTable to Dictionary ====== | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// | ||
+ | /// </ | ||
+ | /// < | ||
+ | /// < | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | public static Dictionary< | ||
+ | { | ||
+ | return table.Cast< | ||
+ | .ToDictionary(kvp => (K)kvp.Key, kvp => (V)kvp.Value); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Calculate Memory Size of Object ====== | ||
+ | |||
+ | <code csharp> | ||
+ | /// < | ||
+ | /// Calculates the length in bytes of an object | ||
+ | /// and returns the size | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private int GetObjectSize(object TestObject) | ||
+ | { | ||
+ | BinaryFormatter bf = new BinaryFormatter(); | ||
+ | MemoryStream ms = new MemoryStream(); | ||
+ | byte[] Array; | ||
+ | bf.Serialize(ms, | ||
+ | Array = ms.ToArray(); | ||
+ | return Array.Length; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Convert a UNIX Timestamp to DateTime ====== | ||
+ | |||
+ | Using the '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// Returns a DateTime object from a given UNIX timestamp. | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static DateTime wasUNIXTimeStampToDateTime(double timeStamp) { | ||
+ | return new DateTime(1970, | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | an example call is: | ||
+ | |||
+ | <code csharp> | ||
+ | DateTime date = wasUNIXTimeStampToDateTime(1406583923); | ||
+ | </ | ||
+ | |||
+ | ====== Convert DateTime to UNIX Timestamp ====== | ||
+ | |||
+ | Given a '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// Returns the UNIX time from a DateTime object. | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static double wasDateTimeToUnixTimeStamp(DateTime date) { | ||
+ | return date.Subtract(new DateTime(1970, | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Get an Enumeration Value from Description ====== | ||
+ | |||
+ | Suppose you have an enumeration, | ||
+ | <code csharp> | ||
+ | [Flags] | ||
+ | private enum Days : uint | ||
+ | { | ||
+ | [Description(" | ||
+ | ONE = 1, | ||
+ | [Description(" | ||
+ | TWO = 2 | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | and you want to get the value (the '' | ||
+ | |||
+ | In that case, using '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// Get enumeration value from its description. | ||
+ | /// </ | ||
+ | /// < | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static T wasGetEnumValueFromDescription< | ||
+ | { | ||
+ | var field = typeof (T).GetFields() | ||
+ | .SelectMany(f => f.GetCustomAttributes( | ||
+ | typeof (DescriptionAttribute), | ||
+ | f, a) => new {Field = f, Att = a}).SingleOrDefault(a => ((DescriptionAttribute) a.Att) | ||
+ | .Description == description); | ||
+ | return field != null ? (T) field.Field.GetRawConstantValue() : default(T); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | you would make a call such as: | ||
+ | |||
+ | <code csharp> | ||
+ | uint day = (uint) wasGetEnumValueFromDescription(new Days(), " | ||
+ | </ | ||
+ | |||
+ | such that the '' | ||
+ | ====== Get Description from Enumeration Value ====== | ||
+ | |||
+ | Suppose you have an enumeration, | ||
+ | <code csharp> | ||
+ | [Flags] | ||
+ | private enum Days : uint | ||
+ | { | ||
+ | [Description(" | ||
+ | ONE = 1, | ||
+ | [Description(" | ||
+ | TWO = 2 | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | and you want to get the description ('' | ||
+ | |||
+ | Using '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// Get the description from an enumeration value. | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static string wasGetDescriptionFromEnumValue(Enum value) | ||
+ | { | ||
+ | DescriptionAttribute attribute = value.GetType() | ||
+ | .GetField(value.ToString()) | ||
+ | .GetCustomAttributes(typeof (DescriptionAttribute), | ||
+ | .SingleOrDefault() as DescriptionAttribute; | ||
+ | return attribute != null ? attribute.Description : string.Empty; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | you would make a call such as: | ||
+ | |||
+ | <code csharp> | ||
+ | string day = wasGetDescriptionFromEnumValue((Days)1); | ||
+ | </ | ||
+ | |||
+ | such that the string '' | ||
+ | |||
+ | ====== Get the Description of a Structure Member ====== | ||
+ | |||
+ | Suppose that you have a structure: | ||
+ | <code csharp> | ||
+ | private struct Person | ||
+ | { | ||
+ | [Description(" | ||
+ | public string Name; | ||
+ | [Description(" | ||
+ | public int Age; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | and that you have instantiated the structure as: | ||
+ | <code csharp> | ||
+ | Person person = new Person { | ||
+ | Name = "Mr. Sparky", | ||
+ | Age = 34 | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | and you want to get the description of the '' | ||
+ | |||
+ | In that case, using '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// Get the description of structure member. | ||
+ | /// </ | ||
+ | /// < | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | public static string wasGetStructureMemberDescription< | ||
+ | { | ||
+ | var field = typeof(T).GetFields() | ||
+ | .SelectMany(f => f.GetCustomAttributes(typeof(DescriptionAttribute), | ||
+ | (f, a) => new { Field = f, Att = a }).SingleOrDefault(f => f.Field.GetValue(structure).Equals(item)); | ||
+ | return field != null ? ((DescriptionAttribute)field.Att).Description : string.Empty; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | you would make a call such as: | ||
+ | <code csharp> | ||
+ | string ageDescription = wasGetStructureMemberDescription(person, | ||
+ | </ | ||
+ | |||
+ | which will leave '' | ||
+ | ====== Get All Descriptions of an Enumeration ====== | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static IEnumerable< | ||
+ | { | ||
+ | return from fi in enumeration.GetType().GetFields(BindingFlags.Static | BindingFlags.Public) | ||
+ | select ((Enum) fi.GetValue(enumeration)).GetAttribute< | ||
+ | into attribute | ||
+ | where attribute != null && !string.IsNullOrEmpty(attribute.Description) | ||
+ | select attribute.Description; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Bitwise Flag Enumerations ====== | ||
+ | |||
+ | The following are functions that manipulate flag-type enumerations, | ||
+ | <code csharp> | ||
+ | [Flags] | ||
+ | private enum Days : uint | ||
+ | { | ||
+ | Monday = 1, | ||
+ | Tuesday = 2, | ||
+ | Wednesday = 4, | ||
+ | Thursday = 8, | ||
+ | Friday = 16, | ||
+ | Saturday = 32, | ||
+ | Sunday = 64 | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | and are useful before the .NET release 4.0 which has built-in functions that can manipulate flags. | ||
+ | |||
+ | ===== Set Flags ===== | ||
+ | |||
+ | Sets a flag (or a flag mask) in a flag enumeration. | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Original by Dan Tao. | ||
+ | /// < | ||
+ | /// Sets flag in flags. | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | private static void SetFlags< | ||
+ | { | ||
+ | flags = (T) (object) ((uint) (object) flags | (uint) (object) flag); | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | For example, using the '' | ||
+ | |||
+ | <code csharp> | ||
+ | Days d = new Days(); | ||
+ | SetFlags(ref d, Days.Monday | Days.Friday | Days.Sunday); | ||
+ | </ | ||
+ | |||
+ | ===== Unset Flags ===== | ||
+ | |||
+ | Unsets a flag (or flag mask) in a flag enumeration. | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Original by Dan Tao. | ||
+ | /// < | ||
+ | /// | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | private static void UnsetFlags< | ||
+ | { | ||
+ | flags = (T) (object) ((uint) (object) flags & (~(uint) (object) flag)); | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | For example, using the '' | ||
+ | |||
+ | <code csharp> | ||
+ | Days d = new Days(); | ||
+ | UnsetFlags(ref d, Days.Friday); | ||
+ | </ | ||
+ | |||
+ | or, for multiple flags: | ||
+ | <code csharp> | ||
+ | Days d = new Days(); | ||
+ | UnsetFlags(ref d, Days.Friday | Days.Sunday); | ||
+ | </ | ||
+ | |||
+ | ===== Determine if a Flag or Flag Mask is Set ===== | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static bool IsSetFlags< | ||
+ | { | ||
+ | return | ||
+ | Enum.GetValues(typeof (T)) | ||
+ | .Cast< | ||
+ | .Where(f => (f & (uint) (object) flag) == f) | ||
+ | .All(set => ((uint) (object) flags & set) != 0); | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | For example, using the '' | ||
+ | |||
+ | <code csharp> | ||
+ | Days d = new Days(); | ||
+ | SetFlags(ref d, Days.Monday | Days.Friday | Days.Sunday); | ||
+ | IsSetFlags(ref d, Days.Monday | Days.Friday); | ||
+ | </ | ||
+ | |||
+ | the return value of '' | ||
+ | |||
+ | ===== Get the Values of Set Flags ===== | ||
+ | |||
+ | Gets the values of set flags in an enumeration. | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// Gets the flag values in flags. | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static IEnumerable< | ||
+ | { | ||
+ | return Enum.GetValues(typeof(T)).Cast< | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | For example, using the '' | ||
+ | |||
+ | <code csharp> | ||
+ | Days d = new Days(); | ||
+ | SetFlags(ref d, Days.Monday | Days.Friday | Days.Sunday); | ||
+ | List< | ||
+ | foreach (uint value in set) { | ||
+ | Console.WriteLine(value.ToString()); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | will print out: | ||
+ | < | ||
+ | 1 | ||
+ | 16 | ||
+ | 64 | ||
+ | </ | ||
+ | |||
+ | ===== Get the Names of Set Flags ===== | ||
+ | |||
+ | Gets the names of set flags. | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// Gets the names of the flags set in flags. | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static IEnumerable< | ||
+ | { | ||
+ | return | ||
+ | Enum.GetValues(typeof (T)) | ||
+ | .Cast< | ||
+ | .Where(f => (f & (uint)(object)flags) == f) | ||
+ | .Select(f => ((T) (object) f).ToString()); | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | For example, using the '' | ||
+ | |||
+ | <code csharp> | ||
+ | Days d = new Days(); | ||
+ | SetFlags(ref d, Days.Monday | Days.Friday | Days.Sunday); | ||
+ | List< | ||
+ | foreach (string name in set) { | ||
+ | Console.WriteLine(name); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | will print out: | ||
+ | < | ||
+ | Monday | ||
+ | Friday | ||
+ | Sunday | ||
+ | </ | ||
+ | |||
+ | ====== Graceful Shutdown of Console Applications ====== | ||
+ | |||
+ | Capturing the closing event of a console under Windows can be done by importing the '' | ||
+ | |||
+ | <code csharp> | ||
+ | // For Unix signals. | ||
+ | using Mono.Unix; | ||
+ | using Mono.Unix.Native; | ||
+ | // For Windows events. | ||
+ | using System.Runtime.InteropServices; | ||
+ | |||
+ | //... | ||
+ | |||
+ | /// < | ||
+ | /// | ||
+ | /// </ | ||
+ | [DllImport(" | ||
+ | private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add); | ||
+ | |||
+ | // A delegate for SetConsoleCtrlHandler. | ||
+ | private delegate bool EventHandler(CtrlType ctrlType); | ||
+ | |||
+ | // Set to static in order to avoid garbage collection. | ||
+ | private static EventHandler ConsoleEventHandler; | ||
+ | |||
+ | // An enumerated type for the control messages | ||
+ | // sent to the handler routine. | ||
+ | private enum CtrlType | ||
+ | { | ||
+ | CTRL_C_EVENT = 0, | ||
+ | CTRL_BREAK_EVENT, | ||
+ | CTRL_CLOSE_EVENT, | ||
+ | CTRL_LOGOFF_EVENT = 5, | ||
+ | CTRL_SHUTDOWN_EVENT | ||
+ | } | ||
+ | |||
+ | private static bool ConsoleCtrlCheck(CtrlType ctrlType) | ||
+ | { | ||
+ | KeyValuePair< | ||
+ | if (semaphore.Value != null) | ||
+ | { | ||
+ | semaphore.Value.Set(); | ||
+ | } | ||
+ | |||
+ | // Wait for threads to finish. | ||
+ | Thread.Sleep(60000); | ||
+ | return true; | ||
+ | } | ||
+ | |||
+ | // Main entry point. | ||
+ | public static void Main() | ||
+ | { | ||
+ | // Branch on platform and set-up termination handlers. | ||
+ | switch (Environment.OSVersion.Platform) | ||
+ | { | ||
+ | // SetConsoleCtrlHandler supported on Windows 2000 or later. | ||
+ | case PlatformID.Win32NT: | ||
+ | // Setup console handler. | ||
+ | ConsoleEventHandler += ConsoleCtrlCheck; | ||
+ | SetConsoleCtrlHandler(ConsoleEventHandler, | ||
+ | break; | ||
+ | // For Unix signals, catch SIGTERM (daemon). | ||
+ | case PlatformID.Unix: | ||
+ | UnixSignal[] signals = | ||
+ | { | ||
+ | new UnixSignal(Signum.SIGTERM) | ||
+ | }; | ||
+ | new Thread(() => | ||
+ | { | ||
+ | UnixSignal.WaitAny(signals, | ||
+ | |||
+ | KeyValuePair< | ||
+ | ConnectionSemaphores.FirstOrDefault(s => s.Key.Equals(' | ||
+ | if (semaphore.Value != null) | ||
+ | { | ||
+ | semaphore.Value.Set(); | ||
+ | } | ||
+ | }).Start(); | ||
+ | break; | ||
+ | } | ||
+ | | ||
+ | // Rest of the program | ||
+ | // ... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | This method will branch on '' | ||
+ | |||
+ | ====== Split String into Groups of Strings ====== | ||
+ | |||
+ | Using LINQ, this can be done by: | ||
+ | <code csharp> | ||
+ | int groups = 2; | ||
+ | |||
+ | IEnumerable< | ||
+ | .GroupBy(x => x.index/ | ||
+ | .Select(xg => string.Join("", | ||
+ | </ | ||
+ | |||
+ | where '' | ||
+ | |||
+ | For example, for a string such as: | ||
+ | < | ||
+ | good day! | ||
+ | </ | ||
+ | |||
+ | and '' | ||
+ | < | ||
+ | go | ||
+ | od | ||
+ | d | ||
+ | ay | ||
+ | ! | ||
+ | </ | ||
+ | |||
+ | ====== RFC3986 URI Escape and Unescape a Data String ====== | ||
+ | |||
+ | The '' | ||
+ | |||
+ | ===== Unescape ===== | ||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static string wasUriUnescapeDataString(string data) | ||
+ | { | ||
+ | return | ||
+ | Regex.Matches(data, | ||
+ | .Cast< | ||
+ | .Select(m => m.Value) | ||
+ | .Distinct() | ||
+ | .Aggregate(data, | ||
+ | (current, match) => | ||
+ | current.Replace(match, | ||
+ | ((char) int.Parse(match.Substring(1), | ||
+ | CultureInfo.InvariantCulture))); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Escape ===== | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static string wasUriEscapeDataString(string data) | ||
+ | { | ||
+ | StringBuilder result = new StringBuilder(); | ||
+ | foreach (char c in data.Select(o => o)) | ||
+ | { | ||
+ | if(char.IsLetter(c) || char.IsDigit(c)) { | ||
+ | result.Append(c); | ||
+ | continue; | ||
+ | } | ||
+ | result.AppendFormat(" | ||
+ | } | ||
+ | return result.ToString(); | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ====== Fibonacci Number Generator ====== | ||
+ | |||
+ | As a translation of the [[fuss/ | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// | ||
+ | /// | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static IEnumerable< | ||
+ | if (count <= 0) yield break; | ||
+ | yield return first; | ||
+ | foreach(ulong f in wasFibonacci(--count, | ||
+ | yield return f; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Determine if Number is a Power of Two ====== | ||
+ | |||
+ | The function '' | ||
+ | |||
+ | <code csharp> | ||
+ | private static bool IsPowerOfTwo(uint n) { | ||
+ | return (n & (n - 1)) == 0 && n != 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== XOR Swap Two Integers ====== | ||
+ | |||
+ | This is actually very elegant in C# using the '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// Swaps two integers passed by reference using XOR. | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | private static void wasXORSwap(ref int q, ref int p) | ||
+ | { | ||
+ | q ^= p; | ||
+ | p ^= q; | ||
+ | q ^= p; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Parallel Insertion of Matrix Values in Flat Array ====== | ||
+ | |||
+ | One interesting problem is the following: suppose that you have a certain terrain, from the bottom-left corner $A(x_{1}, y_{1})$ to the top-right corner $B(x_{2}, y_{2})$ and that the domain of values for $x$ and $y$ is discrete. You want to measure the height for each coordinate $C(x_{i}, y_{j})$ in the rectangle whose diagonal is $\overline{AB}$ and store it in a flat array of values. | ||
+ | |||
+ | This is perhaps visualised better as a grid (or a matrix): | ||
+ | < | ||
+ | x x B | ||
+ | x x x | ||
+ | A x x | ||
+ | </ | ||
+ | where each element has a certain height. | ||
+ | |||
+ | It is clear that this will turn out to be an $O^2$ algorithm because every single coordinate will have to be measured. However, if you benefit from threads, then depending on the number of threads that can be run in parallel, the $O^2$ complexity can be reduced considerably. In the visualisation above, we have to visit 9 different coordinates, | ||
+ | |||
+ | In order to write the algorithm, we are first going to compute the index of each element on the grid, in the order that we measure it by. From the visualisation, | ||
+ | < | ||
+ | 2 5 8 | ||
+ | 1 4 7 | ||
+ | 0 3 6 | ||
+ | </ | ||
+ | from $A$ at index $0$ to $B$ at index $8$. We express the index of the array in function of our current $x$ and $y$ coordinate: | ||
+ | |||
+ | \begin{eqnarray*} | ||
+ | \text{index} &=& x_{max} * x + y | ||
+ | \end{eqnarray*} | ||
+ | |||
+ | where: | ||
+ | |||
+ | * $x$ and $y$ represent the current location, | ||
+ | * $x_{max}$ represents the width of the grid. | ||
+ | |||
+ | |||
+ | Now we can write the algorithm: | ||
+ | |||
+ | <code csharp> | ||
+ | // calculate the sizes for x and y | ||
+ | int sx = x2 - x1 + 1; | ||
+ | int sy = y2 - y1 + 1; | ||
+ | // create an array of the total size (sx*sy) | ||
+ | float[] data = new float[sx*sy]; | ||
+ | // loop over the range of x, loop over the range of y | ||
+ | Parallel.ForEach(Enumerable.Range(x1, | ||
+ | { | ||
+ | // if the height can be determined at a given | ||
+ | // x and y, then set the height at the correct | ||
+ | // index in the flat array of values. | ||
+ | float height; | ||
+ | data[sx * x + y] = Client.Network.CurrentSim.TerrainHeightAtPoint(x, | ||
+ | ? height | ||
+ | : -1; | ||
+ | })); | ||
+ | </ | ||
+ | |||
+ | One of the nice remarks about this algorithm is that it does not use any form of locking - every single task works on one single index such that no locking is needed for insertion. Even if we were to use locks, we would have a problem, because we could not tell in what order the elements would be inserted. Using the formula however, we can make sure that each task can run independently of other tasks. | ||
+ | |||
+ | ====== Compressing a HTTP Web Request ====== | ||
+ | |||
+ | Using '' | ||
+ | |||
+ | <code csharp> | ||
+ | using System.IO.Compression; | ||
+ | |||
+ | // ... | ||
+ | |||
+ | using (Stream requestStream = request.GetRequestStream()) | ||
+ | { | ||
+ | using(var zipStream = new GZipStream(requestStream, | ||
+ | { | ||
+ | zipStream.Write(byteData, | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | which is different from requesting a compressed response, which is more common. | ||
+ | |||
+ | ====== Permute an Array ====== | ||
+ | |||
+ | '' | ||
+ | |||
+ | ===== Reverse ===== | ||
+ | |||
+ | Suppose you have an array with the elements: | ||
+ | < | ||
+ | a b c | ||
+ | </ | ||
+ | |||
+ | then a call such as '' | ||
+ | < | ||
+ | b c a | ||
+ | </ | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// | ||
+ | /// </ | ||
+ | /// < | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static T[] wasReversePermuteArrayElements< | ||
+ | { | ||
+ | if (times.Equals(0)) return input; | ||
+ | T[] slice = new T[input.Length]; | ||
+ | Array.Copy(input, | ||
+ | Array.Copy(input, | ||
+ | return wasReversePermuteAttayElements(slice, | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Forward ===== | ||
+ | |||
+ | Suppose you have an array with the elements: | ||
+ | < | ||
+ | a b c | ||
+ | </ | ||
+ | |||
+ | then a call such as '' | ||
+ | < | ||
+ | c a b | ||
+ | </ | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// | ||
+ | /// </ | ||
+ | /// < | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static T[] wasForwardPermuteArrayElements< | ||
+ | { | ||
+ | if (times.Equals(0)) return input; | ||
+ | T[] slice = new T[input.Length]; | ||
+ | Array.Copy(input, | ||
+ | Array.Copy(input, | ||
+ | return wasForwardPermuteArrayElements(slice, | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Swap Array Elements ====== | ||
+ | |||
+ | The '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// Swaps two elements in an array. | ||
+ | /// </ | ||
+ | /// < | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static T[] wasArraySwap< | ||
+ | { | ||
+ | T[] swap = input.Clone() as T[]; | ||
+ | int i = Array.IndexOf(input, | ||
+ | int j = Array.IndexOf(input, | ||
+ | Array.Copy(input, | ||
+ | Array.Copy(input, | ||
+ | return swap; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Concatenate Array Elements ====== | ||
+ | |||
+ | Given several arrays as input, the '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// | ||
+ | /// </ | ||
+ | /// < | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | public static T[] wasConcatenateArrays< | ||
+ | { | ||
+ | int resultLength = 0; | ||
+ | foreach (T[] o in arrays) | ||
+ | { | ||
+ | resultLength += o.Length; | ||
+ | } | ||
+ | T[] result = new T[resultLength]; | ||
+ | int offset = 0; | ||
+ | for (int x = 0; x < arrays.Length; | ||
+ | { | ||
+ | arrays[x].CopyTo(result, | ||
+ | offset += arrays[x].Length; | ||
+ | } | ||
+ | return result; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Delete Sub-Array ====== | ||
+ | |||
+ | Given an array, the '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// | ||
+ | /// </ | ||
+ | /// < | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | public static T[] wasDeleteSubArray< | ||
+ | { | ||
+ | if (stop.Equals(-1)) | ||
+ | stop = data.Length - 1; | ||
+ | T[] result = new T[data.Length - (stop - start) - 1]; | ||
+ | Array.Copy(data, | ||
+ | Array.Copy(data, | ||
+ | return result; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Get Sub-Array ====== | ||
+ | |||
+ | The '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// Gets a sub-array from an array. | ||
+ | /// </ | ||
+ | /// < | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | public static T[] wasGetSubArray< | ||
+ | { | ||
+ | if (stop.Equals(-1)) | ||
+ | stop = data.Length - 1; | ||
+ | T[] result = new T[stop - start + 1]; | ||
+ | Array.Copy(data, | ||
+ | return result; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Cryptographic Functions ====== | ||
+ | |||
+ | A list of cryptographic functions created by Wizardry and Steamworks: | ||
+ | |||
+ | {{indexmenu>: | ||
+ | |||
+ | that will help you encrypt and decrypt messages. | ||
+ | |||
+ | ====== Sequence Contains All Elements of Sequence ====== | ||
+ | |||
+ | Suppose we have two sets: | ||
+ | <code csharp> | ||
+ | var subset = new [] { 2 3 1 }; | ||
+ | var set = new [] { 2 3 8 4 2 }; | ||
+ | </ | ||
+ | and we want to determine if '' | ||
+ | |||
+ | In that case we can do: | ||
+ | <code csharp> | ||
+ | bool contained = !subset.Except(set).Any(); | ||
+ | </ | ||
+ | |||
+ | after which '' | ||
+ | |||
+ | ====== Unix Alarm ====== | ||
+ | |||
+ | The '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | public class wasAlarm | ||
+ | { | ||
+ | private Timer alarm; | ||
+ | |||
+ | public wasAlarm() | ||
+ | { | ||
+ | Signal = new ManualResetEvent(false); | ||
+ | } | ||
+ | |||
+ | public ManualResetEvent Signal { get; set; } | ||
+ | |||
+ | public void Alarm(int deadline) | ||
+ | { | ||
+ | if (alarm == null) | ||
+ | { | ||
+ | alarm = new Timer(deadline); | ||
+ | alarm.Elapsed += (o, p) => | ||
+ | { | ||
+ | Signal.Set(); | ||
+ | alarm.Dispose(); | ||
+ | }; | ||
+ | alarm.Start(); | ||
+ | return; | ||
+ | } | ||
+ | alarm.Interval = deadline; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Suppose that you have an event, that you do not know how many times it will be called before not being called again, in that case you would first create the alarm: | ||
+ | <code csharp> | ||
+ | wasAlarm trigger = new wasAlarm(); | ||
+ | </ | ||
+ | |||
+ | then, in the event handler, you would reschedule the alarm, with: | ||
+ | <code csharp> | ||
+ | trigger.Alarm(1000); | ||
+ | </ | ||
+ | |||
+ | Finally, you would wait on the alarm to trigger using, for example, '' | ||
+ | <code csharp> | ||
+ | trigger.Signal.WaitOne(timeout, | ||
+ | </ | ||
+ | |||
+ | This class is used throughout [[secondlife/ | ||
+ | |||
+ | ====== Adaptive Alarm ====== | ||
+ | |||
+ | '' | ||
+ | |||
+ | One of the short-comings of the UNIX alarm is that it does not explicitly consider past elapsed times. For example, suppose that you set and reset an alarm as some events happen. You would only reschedule the alarm with a fixed time, every time, regardless whether the previous event has been delivered much earlier than your alarm schedule. | ||
+ | |||
+ | '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// An alarm class similar to the UNIX alarm with the added benefit | ||
+ | /// of a decaying timer that tracks the time between rescheduling. | ||
+ | /// </ | ||
+ | /// < | ||
+ | /// (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 | ||
+ | /// </ | ||
+ | public class wasAdaptiveAlarm | ||
+ | { | ||
+ | [Flags] | ||
+ | public enum DECAY_TYPE | ||
+ | { | ||
+ | NONE = 0, | ||
+ | ARITHMETIC = 1, | ||
+ | GEOMETRIC = 2, | ||
+ | HARMONIC = 4 | ||
+ | } | ||
+ | |||
+ | private readonly DECAY_TYPE decay = DECAY_TYPE.NONE; | ||
+ | private readonly Stopwatch elapsed = new Stopwatch(); | ||
+ | private readonly HashSet< | ||
+ | private System.Timers.Timer alarm; | ||
+ | |||
+ | /// < | ||
+ | /// The default constructor using no decay. | ||
+ | /// </ | ||
+ | public wasAdaptiveAlarm() | ||
+ | { | ||
+ | Signal = new ManualResetEvent(false); | ||
+ | } | ||
+ | |||
+ | /// < | ||
+ | /// The constructor for the wasAdaptiveAlarm class taking as parameter a decay type. | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | public wasAdaptiveAlarm(DECAY_TYPE decay) | ||
+ | { | ||
+ | Signal = new ManualResetEvent(false); | ||
+ | this.decay = decay; | ||
+ | } | ||
+ | |||
+ | public ManualResetEvent Signal { get; set; } | ||
+ | |||
+ | public void Alarm(double deadline) | ||
+ | { | ||
+ | if (alarm == null) | ||
+ | { | ||
+ | alarm = new System.Timers.Timer(deadline); | ||
+ | alarm.Elapsed += (o, p) => | ||
+ | { | ||
+ | Signal.Set(); | ||
+ | times.Clear(); | ||
+ | alarm.Dispose(); | ||
+ | }; | ||
+ | elapsed.Start(); | ||
+ | alarm.Start(); | ||
+ | return; | ||
+ | } | ||
+ | elapsed.Stop(); | ||
+ | times.Add(elapsed.ElapsedMilliseconds); | ||
+ | elapsed.Reset(); | ||
+ | elapsed.Start(); | ||
+ | switch (decay) | ||
+ | { | ||
+ | case DECAY_TYPE.ARITHMETIC: | ||
+ | alarm.Interval = (deadline + times.Aggregate((a, | ||
+ | break; | ||
+ | case DECAY_TYPE.GEOMETRIC: | ||
+ | alarm.Interval = Math.Pow(deadline * times.Aggregate((a, | ||
+ | break; | ||
+ | case DECAY_TYPE.HARMONIC: | ||
+ | alarm.Interval = (1f + times.Count) / (1f / deadline + times.Aggregate((a, | ||
+ | break; | ||
+ | default: | ||
+ | alarm.Interval = deadline; | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | As a practical example, '' | ||
+ | ====== Combine Multiple Paths ====== | ||
+ | |||
+ | In .NET, '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | private static string wasPathCombine(params string[] paths) | ||
+ | { | ||
+ | if (paths.Length.Equals(0)) return string.Empty; | ||
+ | return paths.Length < 2 | ||
+ | ? paths[0] : Path.Combine(Path.Combine(paths[0], | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Convert a Decimal Number to a Given Base ====== | ||
+ | |||
+ | Inspired from [[http:// | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// | ||
+ | /// | ||
+ | /// </ | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | public static string wasIntegerToBase(long value, int radix) { | ||
+ | const string alphabet = @ " | ||
+ | |||
+ | if (radix < 2 || radix > alphabet.Length) | ||
+ | throw new ArgumentException(" | ||
+ | |||
+ | if (value == 0) return " | ||
+ | |||
+ | char[] final = new char[64]; | ||
+ | |||
+ | long n = Math.Abs(value); | ||
+ | int i = 64; | ||
+ | do { | ||
+ | int remainder = (int)(n % radix); | ||
+ | final[--i] = alphabet[remainder]; | ||
+ | n = n / radix; | ||
+ | } while (n != 0); | ||
+ | |||
+ | StringBuilder sb = new StringBuilder(); | ||
+ | if (value < 0) sb.Append(" | ||
+ | sb.Append(final, | ||
+ | |||
+ | return sb.ToString(); | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ====== Iterative Fibonacci Implementation ====== | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | using System; | ||
+ | |||
+ | namespace Fibonacci { | ||
+ | public class Fibonacci { | ||
+ | public static void Main(string[] args) { | ||
+ | int f0 = 0; | ||
+ | int f1 = 1; | ||
+ | |||
+ | int i = 0; | ||
+ | while(i < 10) { | ||
+ | int s = f0; | ||
+ | f0 = f1; | ||
+ | f1 = s + f1; | ||
+ | | ||
+ | Console.WriteLine(s); | ||
+ | | ||
+ | i = i + 1; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Binary Search ====== | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | public static int BinarySearch(int[] a, int i, int min, int max) { | ||
+ | if(max < min) return -1; | ||
+ | int mid = (min+max)/ | ||
+ | if(a[mid] > i) | ||
+ | return BinarySearch(a, | ||
+ | if(a[mid] < i) | ||
+ | return BinarySearch(a, | ||
+ | return i; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Quicksort ====== | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | public static List< | ||
+ | if (l.Count <= 1) { | ||
+ | return l; | ||
+ | } | ||
+ | |||
+ | int pivot = l[l.Count / 2]; | ||
+ | | ||
+ | List< | ||
+ | List< | ||
+ | |||
+ | foreach (int i in l) { | ||
+ | if (i < pivot) | ||
+ | { | ||
+ | less.Add(i); | ||
+ | } | ||
+ | if (i > pivot) | ||
+ | { | ||
+ | more.Add(i); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | List< | ||
+ | result.AddRange(Quicksort(less)); | ||
+ | result.Add(pivot); | ||
+ | result.AddRange(Quicksort(more)); | ||
+ | |||
+ | return result; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Get Field or Property from Nested Class by Fully Qualified Name ====== | ||
+ | |||
+ | The '' | ||
+ | |||
+ | <code csharp> | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | /// < | ||
+ | /// Get field or property from a class by supplying a path. | ||
+ | /// </ | ||
+ | /// < | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// <param name=" | ||
+ | /// < | ||
+ | /// the last object in the fully qualified path or null in case the field or property could not be found | ||
+ | /// </ | ||
+ | public static object GetFP< | ||
+ | BindingFlags flags = BindingFlags.Instance | BindingFlags.Public) where T : class | ||
+ | { | ||
+ | if (string.IsNullOrEmpty(path)) return null; | ||
+ | if (o == null) return null; | ||
+ | |||
+ | var components = path.Split(' | ||
+ | |||
+ | var memberTypes = o.GetType().GetMember(components[0], | ||
+ | |||
+ | if (memberTypes.Length != 1) return null; | ||
+ | |||
+ | switch (memberTypes[0].MemberType) | ||
+ | { | ||
+ | case MemberTypes.Field: | ||
+ | return components.Length > 1 | ||
+ | ? GetFP(o.GetType().GetField(components[0]).GetValue(o), | ||
+ | components.Skip(1).Aggregate((a, | ||
+ | : o.GetType().GetField(path).GetValue(o); | ||
+ | case MemberTypes.Property: | ||
+ | return components.Length > 1 | ||
+ | ? GetFP(o.GetType().GetProperty(components[0], | ||
+ | components.Skip(1).Aggregate((a, | ||
+ | : o.GetType().GetProperty(path).GetValue(o); | ||
+ | } | ||
+ | |||
+ | return null; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | The search is performed by fully qualified name. For instance: | ||
+ | <code csharp> | ||
+ | var o = object.GetFP(" | ||
+ | </ | ||
+ | |||
+ | ====== Merge Sort ====== | ||
+ | |||
+ | ===== Recursive ===== | ||
+ | |||
+ | Recursively and using generics. | ||
+ | |||
+ | <code csharp> | ||
+ | using System; | ||
+ | |||
+ | namespace Sorts.MergeSort.Recursive | ||
+ | { | ||
+ | public class MergeSort | ||
+ | { | ||
+ | private static int[] List { get; set; } | ||
+ | |||
+ | public MergeSort(int[] list) | ||
+ | { | ||
+ | List = list; | ||
+ | } | ||
+ | |||
+ | public int[] Sort() | ||
+ | { | ||
+ | return Partition(List); | ||
+ | } | ||
+ | |||
+ | private static T[] Partition< | ||
+ | { | ||
+ | if (list.Length <= 1) | ||
+ | { | ||
+ | return list; | ||
+ | } | ||
+ | |||
+ | var pivot = list.Length / 2; | ||
+ | |||
+ | T[] l = new T[pivot]; | ||
+ | |||
+ | Array.Copy(list, | ||
+ | |||
+ | T[] r = new T[list.Length - pivot]; | ||
+ | |||
+ | Array.Copy(list, | ||
+ | |||
+ | return Merge(Partition(l), | ||
+ | } | ||
+ | |||
+ | private static T[] Concatenate< | ||
+ | { | ||
+ | T[] rest = new T[a.Length + b.Length]; | ||
+ | |||
+ | Array.Copy(a, | ||
+ | Array.Copy(b, | ||
+ | |||
+ | return rest; | ||
+ | } | ||
+ | |||
+ | private static T[] Concatenate< | ||
+ | { | ||
+ | T[] result = new T[l.Length + 1]; | ||
+ | result[0] = a; | ||
+ | |||
+ | Array.Copy(l, | ||
+ | |||
+ | return result; | ||
+ | } | ||
+ | |||
+ | private static T Car< | ||
+ | { | ||
+ | return l[0]; | ||
+ | } | ||
+ | |||
+ | private static T[] Cdr< | ||
+ | { | ||
+ | T[] cdr = new T[l.Length - 1]; | ||
+ | |||
+ | Array.Copy(l, | ||
+ | |||
+ | return cdr; | ||
+ | } | ||
+ | |||
+ | private static T[] Merge< | ||
+ | { | ||
+ | if (l.Length == 0 || r.Length == 0) | ||
+ | { | ||
+ | return Concatenate(l, | ||
+ | } | ||
+ | |||
+ | if (l[0].CompareTo(r[0]) > 0) | ||
+ | { | ||
+ | return Concatenate(Car(r), | ||
+ | } | ||
+ | |||
+ | return Concatenate(Car(l), | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | May have stack issues so should be called by increasing the stack size: | ||
+ | <code csharp> | ||
+ | var t = new Thread(() => | ||
+ | { | ||
+ | list = new MergeSort.Recursive.MergeSort(list).Sort(); | ||
+ | |||
+ | }, 1024 * 1024 * 50); | ||
+ | |||
+ | t.Start(); | ||
+ | </ | ||
+ | |||
+ | ===== Iterative ===== | ||
+ | |||
+ | <code csharp> | ||
+ | using System; | ||
+ | |||
+ | namespace Sorts.MergeSort.Iterative | ||
+ | { | ||
+ | public class MergeSort | ||
+ | { | ||
+ | private static int[] List { get; set; } | ||
+ | |||
+ | public MergeSort(int[] list) | ||
+ | { | ||
+ | List = list; | ||
+ | } | ||
+ | |||
+ | public int[] Sort() | ||
+ | { | ||
+ | return Sort(List); | ||
+ | } | ||
+ | |||
+ | private static T Min< | ||
+ | { | ||
+ | return x.CompareTo(y) < 0 ? x : y; | ||
+ | } | ||
+ | |||
+ | private static T[] Sort< | ||
+ | { | ||
+ | T[] b = new T[a.Length]; | ||
+ | |||
+ | for (int size = 1; size < a.Length; size *= 2) | ||
+ | { | ||
+ | for (int left = 0; left + size < a.Length; left += size * 2) | ||
+ | { | ||
+ | int l = left + size; | ||
+ | int r = Min(l + size, a.Length); | ||
+ | |||
+ | var k = left; | ||
+ | var i = left; | ||
+ | var j = l; | ||
+ | while (i < l && j < r) | ||
+ | { | ||
+ | if (a[i].CompareTo(a[j]) < 0) | ||
+ | { | ||
+ | b[k] = a[i]; | ||
+ | ++i; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | b[k] = a[j]; | ||
+ | ++j; | ||
+ | } | ||
+ | |||
+ | ++k; | ||
+ | } | ||
+ | while (i < l) | ||
+ | { | ||
+ | b[k] = a[i]; | ||
+ | ++i; | ||
+ | ++k; | ||
+ | } | ||
+ | |||
+ | while (j < r) | ||
+ | { | ||
+ | b[k] = a[j]; | ||
+ | ++j; | ||
+ | ++k; | ||
+ | } | ||
+ | |||
+ | for (k = left; k < r; ++k) | ||
+ | { | ||
+ | a[k] = b[k]; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return a; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||