Differences

This shows you the differences between two versions of the page.


Previous revision
fuss:csharp [2017/02/22 18:30] – external edit 127.0.0.1
Line 1: Line 1:
-======  Wizardry and Steamworks Portable Library Class (PCL) ====== 
- 
-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://svn.grimore.org/wasSharp|wasSharp]] 
- 
-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<int>(new int[Console.WindowWidth]).ForEach(i => Console.Write("-")); 
-</code> 
-which creates an empty list of integers of size ''Console.WindowWidth'' and then for each element it writes a dash to the console. 
- 
-====== Assemblies in Different Directory ====== 
- 
-Assemblies can be loaded from a different directory by creating an ''ASSEMBLY.EXE.conf'' file, where ''ASSEMBLY.EXE'' is the application executable with the following contents: 
- 
-<code xml> 
-<configuration> 
-   <runtime> 
-      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
-         <probing privatePath="lib;bin"/> 
-      </assemblyBinding> 
-   </runtime> 
-</configuration> 
-</code> 
- 
-This will make the application to look for the assemblies in the ''lib/'' and ''bin/'' paths. 
- 
-====== Get Memory Currently In-Use by Process ====== 
- 
-''freeByes'' will contain the amount of memory used by the current process in bytes. 
- 
-<code c#> 
-System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess(); 
-int freeBytes = proc.PrivateMemorySize64; 
-</code> 
- 
-====== Select Even Element of Array ====== 
- 
-Given the array: 
-<code> 
-[ 0, 1, 2, 3, 4, 5, ... ] 
-</code> 
- 
-the following LINQ expression: 
-<code c#> 
-var a = data.Where((value, index) => (index % 2) == 0).ToArray(); 
-</code> 
- 
-will set a to the array: 
-<code> 
-[ 0, 2, 4, ... ] 
-</code> 
- 
-====== 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 [[.:data_structures:key-value_pairs|key-value data]]. The ''ToKeyValueData'' function in the example below uses reflection to loop over the properties of the ''Person'' structure and returns a [[.:data_structures:key-value_pairs|key-value data]] compatible string. 
- 
-<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    // 
-    /////////////////////////////////////////////////////////////////////////// 
-    /// <summary> 
-    /// Serializes a structure to a Wizardry and Steamworks key-value data string. 
-    /// </summary> 
-    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, null).ToString(); 
-            if(string.IsNullOrEmpty(v)) continue; 
-            sb.Append(string.Format("{0}={2}", k.Name, v); 
-                      sb.Append(delimiter); 
-        } 
-        if(sb.Length != 0) sb.Length--; 
-        return sb.ToString(); 
-    } 
-    ... 
-    public string name { get; internal set; } 
-    public string address { get; internal set; } 
-    ... 
-} 
- 
-</code> 
- 
-That is done by enumerating the properties of the ''Person'' structure using ''GetProperties'' on the type of the structure which gives us a ''propertyInfo'' object from which we can extract the name of that property. In order to get the value of that property, we use ''GetProperty'' on the name of property and get the value of the instance object (''this''). 
- 
-====== 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?"). For example, you perform a loop and store data in the upper-scope: 
- 
-<code csharp> 
-int time = 0; 
-int greeting = ""; 
-foreach(var o in ...) { 
-  switch(o) { 
-    case ...: 
-      time = 10; 
-      break; 
-    case ...: 
-      greeting = "Good Day!"; 
-      break; 
-  } 
-} 
-</code> 
- 
-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 
-} 
-</code> 
- 
-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<T>(Expression<Func<T>> e) { 
-    return ((MemberExpression) e.Body).Member.Name; 
-} 
-... 
-Console.WriteLine(GetName(() => ON)); 
-</code> 
- 
-====== Monitoring File Activity ====== 
- 
-When you have to monitor files for changes or access times, ''C#'' comes equipped for that task with the ''FileSystemWatcher'' class. On ''UNIX'' / ''mono'', ''FileSystemWatcher'' is implemented using ''gamin'' as well as other mechanisms to provide the same functionality. 
- 
-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 ''ini'' files and then when any ''ini'' file in the current directory is changed, it will raise ''HandleDirectoryChange''. ''HandleDirectoryChange'' will then print out the file name (in ''e.Name'') to the console: 
- 
-<code csharp> 
-FileSystemWatcher watcher = new FileSystemWatcher(); 
-watcher.Path = Directory.GetCurrentDirectory(); 
-watcher.NotifyFilter = NotifyFilters.LastAccess |  
-                       NotifyFilters.LastWrite |  
-                       NotifyFilters.FileName |  
-                       NotifyFilters.DirectoryName; 
-watcher.Filter = "*.ini"; 
-watched.Changed += HandleDirectoryChange; 
-... 
-private static void HandleDirectoryChange(object sender, FileSystemEventArgs e) 
-{ 
-    Console.WriteLine(e.Name); 
-} 
-</code> 
- 
-Note that ''FileSystemWatcher'' monitors directories and if you want to monitor just a file, you can set the ''Filter'' to the file name, as in: 
- 
-<code csharp> 
-watcher.Path = Directory.GetCurrentDirectory(); 
-watcher.Filter = "Corrade.ini"; 
-</code> 
- 
-====== Try to Parse a Nullable Structure ====== 
- 
-''TryParse'' does not function on nullable types such as ''int?''. The following function can act as a substitute for ''int.TryParse'': 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Attempts to parse a string to a structure. 
-/// </summary> 
-/// <param name="input">the input string</param> 
-/// <param name="variable">the variable holding the parsed type T</param> 
-/// <returns>true if the variable could be parsed</returns> 
-public static bool TryParseNullable<T>(string input, out T? variable) where T:struct  
-{ 
-    if (string.IsNullOrEmpty(input)) 
-    { 
-        variable = null; 
-        return false; 
-    } 
-    T? localVariable; 
-    try 
-    { 
-        IConvertible convertibleString = input; 
-        localVariable = (T)convertibleString.ToType(typeof(T), CultureInfo.CurrentCulture); 
-    } 
-    catch (Exception) 
-    { 
-        variable = null; 
-        return false; 
-    } 
-    variable = localVariable; 
-    return true; 
-} 
-</code> 
- 
-====== 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)) 
-{ 
-   Console.WriteLine(fi.Name); 
-   Console.WriteLine(fi.GetValue(null)); 
-} 
-</code> 
- 
-====== Group a Sequence by Pairs ====== 
- 
-Suppose you have a set of elements: 
-<code> 
-10, 20, 30, 40, 50 
-</code> 
- 
-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, p) => new {o = o, p = p}) 
-    .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()) 
-</code> 
- 
-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 (''CSV'') such as: 
-<code> 
-Color, Red, Life, Good, Day, Sunday 
-</code> 
- 
-where the even strings (''Color'', ''Life'', ''Day'') represent keys and the odd strings (''Red'', ''Good'', ''Sunday'') represent values, one can use regular expressions (''System.Text.RegularExpressions'') to serialise the string into a dictionary of key-value pairs: 
- 
-<code csharp> 
-using System.Text.RegularExpressions; 
-//... 
-Dictionary<string, string> pairs =  
- Regex.Matches(command.Attachments, @"\s*(?<key>.+?)\s*,\s*(?<value>.+?)\s*(,|$)") 
- .Cast<Match>() 
- .ToDictionary(m => m.Groups["key"].Value, m => m.Groups["value"].Value); 
-</code> 
- 
-Note that the regex is sufficiently resistant to abuse, for example, it will work fine if the spaces around the strings are garbled: 
-<code> 
-Color , Red,     Life,Good , Day , Sunday 
-</code> 
- 
-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(@"\s*,\s*(?=(?:[^\""]*\""[^\""]*\"")*(?![^\""]*\""))", 
-            RegexOptions.Compiled); 
-//... 
-foreach (KeyValuePair<string, string> a in CSVRegEx.Split(input).Select((value, index) => new {value, index}) 
-    .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); 
-} 
-</code> 
- 
-For more details, see [[fuss/csharp#group_a_sequence_by_pairs|group a sequence by pairs]]. 
-====== Convert HashTable to Dictionary ====== 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Converts a hash table to a dictionary. 
-/// </summary> 
-/// <typeparam name="K">key type</typeparam> 
-/// <typeparam name="V">value type</typeparam> 
-/// <param name="table">a hash table</param> 
-/// <returns>a dictionary</returns> 
-public static Dictionary<K, V> HashtableToDictionary<K, V>(Hashtable table) 
-{ 
-    return table.Cast<DictionaryEntry>() 
-        .ToDictionary(kvp => (K)kvp.Key, kvp => (V)kvp.Value); 
-} 
-</code> 
- 
-====== Calculate Memory Size of Object ====== 
- 
-<code csharp> 
-/// <summary> 
-/// Calculates the length in bytes of an object  
-/// and returns the size  
-/// </summary> 
-/// <param name="TestObject"></param> 
-/// <returns></returns> 
-private int GetObjectSize(object TestObject) 
-{ 
-    BinaryFormatter bf = new BinaryFormatter(); 
-    MemoryStream ms = new MemoryStream(); 
-    byte[] Array; 
-    bf.Serialize(ms, TestObject); 
-    Array = ms.ToArray(); 
-    return Array.Length; 
-} 
-</code> 
- 
-====== Convert a UNIX Timestamp to DateTime ====== 
- 
-Using  the ''wasUNIXTimeStampToDateTime'' function we can convert a UNIX timestamp to a ''DateTime'' object: 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-/// Returns a DateTime object from a given UNIX timestamp. 
-/// </summary> 
-/// <param name="timeStamp">the UNIX time stamp to convert</param> 
-/// <returns>the DateTime object representing the timeStamp</returns> 
-private static DateTime wasUNIXTimeStampToDateTime(double timeStamp) { 
-    return new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(timeStamp); 
-} 
-</code> 
- 
-an example call is: 
- 
-<code csharp> 
-DateTime date = wasUNIXTimeStampToDateTime(1406583923); 
-</code> 
- 
-====== Convert DateTime to UNIX Timestamp ====== 
- 
-Given a ''DateTime'' object, the ''wasDateTimeToUnixTimeStamp'' function returns the UNIX timestamp. 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-/// Returns the UNIX time from a DateTime object. 
-/// </summary> 
-/// <param name="date"></param> 
-/// <returns></returns> 
-private static double wasDateTimeToUnixTimeStamp(DateTime date) { 
-    return date.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0)).Duration().TotalSeconds; 
-} 
-</code> 
- 
-====== Get an Enumeration Value from Description ====== 
- 
-Suppose you have an enumeration, with the following structure: 
-<code csharp> 
-[Flags] 
-private enum Days : uint 
-{ 
-    [Description("Monday")] 
-    ONE = 1, 
-    [Description("Tuesday")] 
-    TWO = 2 
-} 
-</code> 
- 
-and you want to get the value (the ''uint'' ''1'') of the field that has the description ''Monday''. 
- 
-In that case, using ''wasGetEnumValueFromDescription'': 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Get enumeration value from its description. 
-/// </summary> 
-/// <typeparam name="T">the enumeration type</typeparam> 
-/// <param name="description">the description of a member</param> 
-/// <returns>the value or the default of T if case no description found</returns> 
-private static T wasGetEnumValueFromDescription<T>(string description) 
-{ 
-    var field = typeof (T).GetFields() 
-        .SelectMany(f => f.GetCustomAttributes( 
-            typeof (DescriptionAttribute), false), ( 
-                f, a) => new {Field = f, Att = a}).SingleOrDefault(a => ((DescriptionAttribute) a.Att) 
-                    .Description == description); 
-    return field != null ? (T) field.Field.GetRawConstantValue() : default(T); 
-} 
-</code> 
- 
-you would make a call such as: 
- 
-<code csharp> 
-uint day = (uint) wasGetEnumValueFromDescription(new Days(), "Monday"); 
-</code> 
- 
-such that the ''unit'' ''day'' will hold the value ''1'' after the call. 
-====== Get Description from Enumeration Value ====== 
- 
-Suppose you have an enumeration, with the following structure: 
-<code csharp> 
-[Flags] 
-private enum Days : uint 
-{ 
-    [Description("Monday")] 
-    ONE = 1, 
-    [Description("Tuesday")] 
-    TWO = 2 
-} 
-</code> 
- 
-and you want to get the description (''Monday'') from the value ''1''. 
- 
-Using ''wasGetDescriptionFromEnumValue'': 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Get the description from an enumeration value. 
-/// </summary> 
-/// <param name="value">an enumeration value</param> 
-/// <returns>the description or the empty string</returns> 
-private static string wasGetDescriptionFromEnumValue(Enum value) 
-{ 
-    DescriptionAttribute attribute = value.GetType() 
-        .GetField(value.ToString()) 
-        .GetCustomAttributes(typeof (DescriptionAttribute), false) 
-        .SingleOrDefault() as DescriptionAttribute; 
-    return attribute != null ? attribute.Description : string.Empty; 
-} 
-</code> 
- 
-you would make a call such as: 
- 
-<code csharp> 
-string day = wasGetDescriptionFromEnumValue((Days)1); 
-</code> 
- 
-such that the string ''day'' will hold the value ''Monday'' after the call. 
- 
-====== Get the Description of a Structure Member ====== 
- 
-Suppose that you have a structure: 
-<code csharp> 
-private struct Person 
-{ 
-    [Description("the name")] 
-    public string Name; 
-    [Description("the age")] 
-    public int Age; 
-} 
-</code> 
- 
-and that you have instantiated the structure as: 
-<code csharp> 
-Person person = new Person { 
-    Name = "Mr. Sparky", 
-    Age = 34 
-} 
-</code> 
- 
-and you want to get the description of the ''Age'' member of the struct ''Person''. 
- 
-In that case, using ''wasGetStructureMemberDescription'': 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Get the description of structure member. 
-/// </summary> 
-/// <typeparam name="T">the type of the structure to search</typeparam> 
-/// <param name="structure">the structure to search</param> 
-/// <param name="item">the value of the item to search</param> 
-/// <returns>the description or the empty string</returns> 
-public static string wasGetStructureMemberDescription<T>(T structure, object item) where T : struct 
-{ 
-    var field = typeof(T).GetFields() 
-        .SelectMany(f => f.GetCustomAttributes(typeof(DescriptionAttribute), false), 
-            (f, a) => new { Field = f, Att = a }).SingleOrDefault(f => f.Field.GetValue(structure).Equals(item)); 
-    return field != null ? ((DescriptionAttribute)field.Att).Description : string.Empty; 
-} 
-</code> 
- 
-you would make a call such as: 
-<code csharp> 
-string ageDescription = wasGetStructureMemberDescription(person, person.Age); 
-</code> 
- 
-which will leave ''ageDescription'' containing the string ''the age'' after the call. 
-====== Get All Descriptions of an Enumeration ====== 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Returns all the field descriptions of an enumeration. 
-/// </summary> 
-/// <param name="enumeration">the enumeration</param> 
-/// <returns>the field descriptions</returns> 
-private static IEnumerable<string> wasGetEnumDescriptions(this Enum enumeration) 
-{ 
-    return from fi in enumeration.GetType().GetFields(BindingFlags.Static | BindingFlags.Public) 
-        select ((Enum) fi.GetValue(enumeration)).GetAttribute<DescriptionAttribute>() 
-        into attribute 
-        where attribute != null && !string.IsNullOrEmpty(attribute.Description) 
-        select attribute.Description; 
-} 
-</code> 
- 
-====== Bitwise Flag Enumerations ====== 
- 
-The following are functions that manipulate flag-type enumerations, such as: 
-<code csharp> 
-[Flags] 
-private enum Days : uint 
-{ 
-    Monday = 1, 
-    Tuesday = 2, 
-    Wednesday = 4, 
-    Thursday = 8, 
-    Friday = 16, 
-    Saturday = 32, 
-    Sunday = 64 
-} 
- 
-</code> 
- 
-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. 
-/// <summary> 
-///     Sets flag in flags. 
-/// </summary> 
-/// <param name="flags">an enumeration to set flags on</param> 
-/// <param name="flag">a flag or mask to set on flags</param> 
-private static void SetFlags<T>(ref T flags, T flag) where T : struct 
-{ 
-    flags = (T) (object) ((uint) (object) flags | (uint) (object) flag); 
-} 
- 
-</code> 
- 
-For example, using the ''Days'' structure: 
- 
-<code csharp> 
-Days d = new Days(); 
-SetFlags(ref d, Days.Monday | Days.Friday | Days.Sunday); 
-</code> 
- 
-===== 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. 
-/// <summary> 
-///     Unsets a flag. 
-/// </summary> 
-/// <param name="flags">an enumeration to unset flags on</param> 
-/// <param name="flag">a flag or mask to unset of flags</param> 
-private static void UnsetFlags<T>(ref T flags, T flag) where T : struct 
-{ 
-    flags = (T) (object) ((uint) (object) flags & (~(uint) (object) flag)); 
-} 
- 
-</code> 
- 
-For example, using the ''Days'' structure: 
- 
-<code csharp> 
-Days d = new Days(); 
-UnsetFlags(ref d, Days.Friday); 
-</code> 
- 
-or, for multiple flags: 
-<code csharp> 
-Days d = new Days(); 
-UnsetFlags(ref d, Days.Friday | Days.Sunday); 
-</code> 
- 
-===== Determine if a Flag or Flag Mask is Set ===== 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Determines if the flags in flag are set in the flags structure. 
-/// </summary> 
-/// <param name="flags">the structure to check against</param> 
-/// <param name="flag">a single flag or a mask to check</param> 
-/// <returns>true if flag is set in flags</returns> 
-private static bool IsSetFlags<T>(T flags, T flag) where T : struct 
-{ 
-    return 
-        Enum.GetValues(typeof (T)) 
-        .Cast<uint>() 
-        .Where(f => (f & (uint) (object) flag) == f) 
-        .All(set => ((uint) (object) flags & set) != 0); 
-} 
- 
-</code> 
- 
-For example, using the ''Days'' structure: 
- 
-<code csharp> 
-Days d = new Days(); 
-SetFlags(ref d, Days.Monday | Days.Friday | Days.Sunday); 
-IsSetFlags(ref d, Days.Monday | Days.Friday); 
-</code> 
- 
-the return value of ''IsSetFlags'' will be ''True''. 
- 
-===== 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    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Gets the flag values in flags. 
-/// </summary> 
-/// <param name="flags">an enumeration with certain flags set</param> 
-/// <returns>the values of the flags set</returns> 
-private static IEnumerable<uint> GetSetFlagValues<T>(T flags) where T : struct 
-{ 
-    return Enum.GetValues(typeof(T)).Cast<uint>().Where(f => (f & (uint)(object)flags) == f); 
-} 
- 
-</code> 
- 
-For example, using the ''Days'' structure: 
- 
-<code csharp> 
-Days d = new Days(); 
-SetFlags(ref d, Days.Monday | Days.Friday | Days.Sunday); 
-List<uint> set = GetSetFlagValues(d).ToList(); 
-foreach (uint value in set) { 
-    Console.WriteLine(value.ToString()); 
-} 
-</code> 
- 
-will print out: 
-<code> 
-1 
-16 
-64 
-</code> 
- 
-===== Get the Names of Set Flags ===== 
- 
-Gets the names of set flags. 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Gets the names of the flags set in flags. 
-/// </summary> 
-/// <param name="flags">an enumeration with certain flags set</param> 
-/// <returns>the names of the set flags</returns> 
-private static IEnumerable<string> GetSetFlagNames<T>(T flags) where T : struct 
-{ 
-    return 
-        Enum.GetValues(typeof (T)) 
-        .Cast<uint>() 
-        .Where(f => (f & (uint)(object)flags) == f) 
-        .Select(f => ((T) (object) f).ToString()); 
-} 
- 
-</code> 
- 
-For example, using the ''Days'' structure: 
- 
-<code csharp> 
-Days d = new Days(); 
-SetFlags(ref d, Days.Monday | Days.Friday | Days.Sunday); 
-List<string> set = GetSetFlagNames(d).ToList(); 
-foreach (string name in set) { 
-    Console.WriteLine(name); 
-} 
-</code> 
- 
-will print out: 
-<code> 
-Monday 
-Friday 
-Sunday 
-</code> 
- 
-====== Graceful Shutdown of Console Applications ====== 
- 
-Capturing the closing event of a console under Windows can be done by importing the ''SetConsoleCtrlHandler'' function from ''Kernel32.dll'' and has been discussed in the [[fuss/windows#programatically_capture_console_close_button|windows section]]. However, ''kernel32.dll'' is not available under ''mono'' and will not work on Unix platforms. In order to  be able to capture both the console close and sending a termination signal such as ''SIGTERM'' under Unix, the following variation branches on the platform and uses ''SetConsoleCtrlHandler'' under Windows and signals under Unix: 
- 
-<code csharp> 
-// For Unix signals. 
-using Mono.Unix; 
-using Mono.Unix.Native; 
-// For Windows events. 
-using System.Runtime.InteropServices; 
- 
-//... 
- 
-        /// <summary> 
-        ///     Import console handler for windows. 
-        /// </summary> 
-        [DllImport("Kernel32.dll")] 
-        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<char, ManualResetEvent> semaphore = ConnectionSemaphores.FirstOrDefault(s => s.Key.Equals('u')); 
-            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, true); 
-                    break; 
-                    // For Unix signals, catch SIGTERM (daemon). 
-                case PlatformID.Unix: 
-                    UnixSignal[] signals = 
-                    { 
-                        new UnixSignal(Signum.SIGTERM) 
-                    }; 
-                    new Thread(() => 
-                    { 
-                        UnixSignal.WaitAny(signals, -1); 
- 
-                        KeyValuePair<char, ManualResetEvent> semaphore = 
-                            ConnectionSemaphores.FirstOrDefault(s => s.Key.Equals('u')); 
-                        if (semaphore.Value != null) 
-                        { 
-                            semaphore.Value.Set(); 
-                        } 
-                    }).Start(); 
-                    break; 
-            } 
-             
-            // Rest of the program 
-            // ... 
-        } 
-</code> 
- 
-This method will branch on ''Environment.OSVersion.Platform'' and decide what is suitable for each platform. Note, that if the coding is done on Windows, that the ''Mono.Posix.dll'' library has to be added to the list of references in Visual Studio. This can be accomplished by downloading ''mono'' for Windows and the ''DLL'' can usually be found in: ''C:\Program Files (x86)\Mono-3.2.3\lib\mono\2.0''. 
- 
-====== Split String into Groups of Strings ====== 
- 
-Using LINQ, this can be done by: 
-<code csharp> 
-int groups = 2; 
- 
-IEnumerable<string> strings = data.Select((c, index) => new {c, index}) 
-    .GroupBy(x => x.index/groups) 
-    .Select(xg => string.Join("", xg.Select(x => x.c.ToString(CultureInfo.InvariantCulture)).ToArray())); 
-</code> 
- 
-where ''groups'' represents the number of groups to split a string into. 
- 
-For example, for a string such as: 
-<code> 
-good day! 
-</code> 
- 
-and ''groups'' set to ''2'', the resulting substrings will be: 
-<code> 
-go 
-od 
- d 
-ay 
-! 
-</code> 
- 
-====== RFC3986 URI Escape and Unescape a Data String ====== 
- 
-The ''Uri.EscapeDataString'' function in C# has a ''32766'' character limit, after which the function will throw an ''UriFormatException'' error (as per the [[http://msdn.microsoft.com/en-us/library/system.uri.escapedatastring(v=vs.110).aspx|MSDN documentation]]). The following functions are replacements for both ''Uri.EscapeDataString'' and ''Uri.UnescapeDataString'' that will accept longer strings. 
- 
-===== Unescape ===== 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary>URI Unescapes an RFC3986 string</summary> 
-/// <param name="data">a string to unescape</param> 
-/// <returns>the resulting string</returns> 
-private static string wasUriUnescapeDataString(string data) 
-{ 
-    return 
-        Regex.Matches(data, @"%([0-9A-Fa-f]+?){2}") 
-            .Cast<Match>() 
-            .Select(m => m.Value) 
-            .Distinct() 
-            .Aggregate(data, 
-                (current, match) => 
-                    current.Replace(match, 
-                        ((char) int.Parse(match.Substring(1), NumberStyles.AllowHexSpecifier)).ToString( 
-                            CultureInfo.InvariantCulture))); 
-} 
-</code> 
- 
-===== Escape ===== 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary>RFC3986 URI Escapes a string</summary> 
-/// <param name="data">a string to escape</param> 
-/// <returns>an RFC3986 escaped string</returns> 
-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("%{0:X2}", (int) c); 
-    } 
-    return result.ToString(); 
-} 
- 
-</code> 
- 
-====== Fibonacci Number Generator ====== 
- 
-As a translation of the [[fuss/lolcode#fibonacci_number_generator|lolcode variant]], this Fibonacci number generator will return ''count''-sequential Fibonacci numbers starting with the initialization vector ''first'' and ''second'' (which can be either ''0'', ''1'' or ''1'', ''1''). 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Returns count sequential Fibonacci numbers given the initialization 
-///     vector parameters first and second which can be either 0, 1 or 1, 1. 
-/// </summary> 
-/// <param name="count">the amount of Fibonacci numbers </param> 
-/// <param name="first">the first number, either 0 or 1</param> 
-/// <param name="second">the second number has to be 1</param> 
-/// <returns>count sequential Fibonacci numbers</returns> 
-private static IEnumerable<ulong> wasFibonacci(ulong count, ulong first, ulong second) { 
-    if (count <= 0) yield break; 
-    yield return first; 
-    foreach(ulong f in wasFibonacci(--count, second, first + second)) 
-        yield return f; 
-} 
-</code> 
- 
-====== Determine if Number is a Power of Two ====== 
- 
-The function ''IsPowerOfTwo'' returns true if the number ''n'' is a power of two and false otherwise. 
- 
-<code csharp> 
-private static bool IsPowerOfTwo(uint n) { 
-    return (n & (n - 1)) == 0 && n != 0; 
-} 
-</code> 
- 
-====== XOR Swap Two Integers ====== 
- 
-This is actually very elegant in C# using the ''ref'' operator which allows us to create a function ''wasXORSwap'' that will swap the two integers ''q'' and ''p'' using the XOR swap algorithm. 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Swaps two integers passed by reference using XOR. 
-/// </summary> 
-/// <param name="q">first integer to swap</param> 
-/// <param name="p">second integer to swap</param> 
-private static void wasXORSwap(ref int q, ref int p) 
-{ 
-    q ^= p; 
-    p ^= q; 
-    q ^= p; 
-} 
-</code> 
- 
-====== 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): 
-<code> 
-x x B 
-x x x 
-A x x  
-</code> 
-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, and, were we to have 9 CPUs, then the entire $O^2$ algorithm could be reduced to an $O1$ algorithm. 
- 
-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, we have the following grid: 
-<code> 
-2 5 8 
-1 4 7 
-0 3 6  
-</code> 
-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, sx), x => Parallel.ForEach(Enumerable.Range(y1, sy), y => 
-{ 
-    // 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, y, out height) 
-        ? height 
-        : -1; 
-})); 
-</code> 
- 
-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 ''gzip'' compression to compress a request: 
- 
-<code csharp> 
-using System.IO.Compression; 
- 
-// ... 
- 
-using (Stream requestStream = request.GetRequestStream()) 
-{ 
-    using(var zipStream = new GZipStream(requestStream, CompressionMode.Compress)) 
-    { 
-        zipStream.Write(byteData, 0, byteData.Length);          
-    } 
-} 
-</code> 
- 
-which is different from requesting a compressed response, which is more common. 
- 
-====== Permute an Array ====== 
- 
-''wasReversePermuteArrayElements'' and ''wasForwardPermuteArrayElements'' permute an array by shifting their elements either in reverse or forward directions. 
- 
-===== Reverse ===== 
- 
-Suppose you have an array with the elements: 
-<code> 
-a b c 
-</code> 
- 
-then a call such as ''wasReversePermuteArrayElements(array, 1)'' will return the elements: 
-<code> 
-b c a 
-</code> 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Permutes an array in reverse a given number of times. 
-/// </summary> 
-/// <typeparam name="T">the array type</typeparam> 
-/// <param name="input">the array</param> 
-/// <param name="times">the number of times to permute</param> 
-/// <returns>the array with the elements permuted</returns> 
-private static T[] wasReversePermuteArrayElements<T>(T[] input, int times) 
-{ 
-    if (times.Equals(0)) return input; 
-    T[] slice = new T[input.Length]; 
-    Array.Copy(input, 1, slice, 0, input.Length - 1); 
-    Array.Copy(input, 0, slice, input.Length - 1, 1); 
-    return wasReversePermuteAttayElements(slice, --times); 
-} 
-</code> 
- 
-===== Forward ===== 
- 
-Suppose you have an array with the elements: 
-<code> 
-a b c 
-</code> 
- 
-then a call such as ''wasForwardPermuteArrayElements(array, 1)'' will return the elements: 
-<code> 
-c a b 
-</code> 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Permutes an array forward a given number of times. 
-/// </summary> 
-/// <typeparam name="T">the array type</typeparam> 
-/// <param name="input">the array</param> 
-/// <param name="times">the number of times to permute</param> 
-/// <returns>the array with the elements permuted</returns> 
-private static T[] wasForwardPermuteArrayElements<T>(T[] input, int times) 
-{ 
-    if (times.Equals(0)) return input; 
-    T[] slice = new T[input.Length]; 
-    Array.Copy(input, input.Length - 1, slice, 0, 1); 
-    Array.Copy(input, 0, slice, 1, input.Length - 1); 
-    return wasForwardPermuteArrayElements(slice, --times); 
-} 
-</code> 
- 
-====== Swap Array Elements ====== 
- 
-The ''wasArraySwap'' swaps two elements in an array. 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Swaps two elements in an array. 
-/// </summary> 
-/// <typeparam name="T">the array type</typeparam> 
-/// <param name="input">the array</param> 
-/// <param name="p">first element</param> 
-/// <param name="q">last element</param> 
-/// <returns>the array with the elements swapped</returns> 
-private static T[] wasArraySwap<T>(T[] input, T p, T q) 
-{ 
-    T[] swap = input.Clone() as T[]; 
-    int i = Array.IndexOf(input, p); 
-    int j = Array.IndexOf(input, q); 
-    Array.Copy(input, i, swap, j, 1); 
-    Array.Copy(input, j, swap, i, 1); 
-    return swap; 
-} 
-</code> 
- 
-====== Concatenate Array Elements ====== 
- 
-Given several arrays as input, the ''wasConcatenateArrays'' function returns a flat array with all the elements from the arrays concatenated. 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Concatenate multiple arrays. 
-/// </summary> 
-/// <typeparam name="T">the array type</typeparam> 
-/// <param name="arrays">multiple arrays</param> 
-/// <returns>a flat array with all arrays concatenated</returns> 
-public static T[] wasConcatenateArrays<T>(params T[][] arrays) 
-{ 
-    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; x++) 
-    { 
-        arrays[x].CopyTo(result, offset); 
-        offset += arrays[x].Length; 
-    } 
-    return result; 
-} 
-</code> 
- 
-====== Delete Sub-Array ====== 
- 
-Given an array, the ''wasDeleteSubArray'' function deletes returns all the elements of the array that are not between the ''start'' and ''stop'' indices. Additionally, the ''wasDeleteSubArray'' function allows ''-1'' to be specified as the ''stop'' index meaning the end of the array. 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Delete a sub-array and return the result. 
-/// </summary> 
-/// <typeparam name="T">the array type</typeparam> 
-/// <param name="data">the array</param> 
-/// <param name="start">the start index</param> 
-/// <param name="stop">the stop index (-1 denotes the end)</param> 
-/// <returns>the array without elements between start and stop</returns> 
-public static T[] wasDeleteSubArray<T>(T[] data, int start, int stop) 
-{ 
-    if (stop.Equals(-1)) 
-        stop = data.Length - 1; 
-    T[] result = new T[data.Length - (stop - start) - 1]; 
-    Array.Copy(data, 0, result, 0, start); 
-    Array.Copy(data, stop + 1, result, start, data.Length - stop - 1); 
-    return result; 
-} 
-</code> 
- 
-====== Get Sub-Array ====== 
- 
-The ''wasGetSubArray'' function takes as input an array and returns all the elements between the ''start'' and ''stop'' indices (inclusive). Additionally, the function supports passing ''-1'' to the ''stop'' index meaning the end of the array. 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Gets a sub-array from an array. 
-/// </summary> 
-/// <typeparam name="T">the array type</typeparam> 
-/// <param name="data">the array</param> 
-/// <param name="start">the start index</param> 
-/// <param name="stop">the stop index (-1 denotes the end)</param> 
-/// <returns>the array slice between start and stop</returns> 
-public static T[] wasGetSubArray<T>(T[] data, int start, int stop) 
-{ 
-    if (stop.Equals(-1)) 
-        stop = data.Length - 1; 
-    T[] result = new T[stop - start + 1]; 
-    Array.Copy(data, start, result, 0, stop - start + 1); 
-    return result; 
-} 
-</code> 
- 
-====== Cryptographic Functions ====== 
- 
-A list of cryptographic functions created by Wizardry and Steamworks: 
- 
-{{indexmenu>:fuss/csharp/cryptography/cyphers}} 
- 
-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 }; 
-</code> 
-and we want to determine if ''set'' contains all the elements of ''subset''. 
- 
-In that case we can do: 
-<code csharp> 
-bool contained = !subset.Except(set).Any(); 
-</code> 
- 
-after which ''contained'' will be true if ''subset'' is contained in set. 
- 
-====== Unix Alarm ====== 
- 
-The ''alarm'' function in Unix program is usually used to raise an event after a certain time and, additionally, by calling the ''alarm'' function again, to reschedule the delivery of that event. In C#, .NET does not have a built-in ''alarm''-like class so the following is a quick implementation using ''System.Timers.Timer'': 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//  Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3      // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary>An alarm class similar to the UNIX alarm</summary> 
-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; 
-    } 
-} 
-</code> 
- 
-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(); 
-</code> 
- 
-then, in the event handler, you would reschedule the alarm, with: 
-<code csharp> 
-trigger.Alarm(1000); 
-</code> 
- 
-Finally, you would wait on the alarm to trigger using, for example, ''WaitOne'': 
-<code csharp> 
-trigger.Signal.WaitOne(timeout, false); 
-</code> 
- 
-This class is used throughout [[secondlife/scripted_agents/corrade|Corrade]]. 
- 
-====== Adaptive Alarm ====== 
- 
-''alarm()'' is usually used under UNIX-like systems to deliver a signal once a certain time has elapsed. It is useful for asynchronous code where some tasks can be performed before the alarm is finally triggered. Commonly, the alarm is set at some point and then updated later in order to reschedule the event at an earlier time.  
- 
-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. 
- 
-''wasAdaptiveAlarm'' uses Pythagorean means (although this can be extended) to consider the reschedule interval as well as all the past elapsed times. It performs the mean between the current scheduling request and all the previous recorded elapsed times. 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//  Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3      // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     An alarm class similar to the UNIX alarm with the added benefit 
-///     of a decaying timer that tracks the time between rescheduling. 
-/// </summary> 
-/// <remarks> 
-///     (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 
-/// </remarks> 
-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<double> times = new HashSet<double>(); 
-    private System.Timers.Timer alarm; 
- 
-    /// <summary> 
-    ///     The default constructor using no decay. 
-    /// </summary> 
-    public wasAdaptiveAlarm() 
-    { 
-        Signal = new ManualResetEvent(false); 
-    } 
- 
-    /// <summary> 
-    ///     The constructor for the wasAdaptiveAlarm class taking as parameter a decay type. 
-    /// </summary> 
-    /// <param name="decay">the type of decay: arithmetic, geometric, harmonic, heronian or quadratic</param> 
-    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, b) => b + a)) / (1f + times.Count); 
-                break; 
-            case DECAY_TYPE.GEOMETRIC: 
-                alarm.Interval = Math.Pow(deadline * times.Aggregate((a, b) => b * a), 1f / (1f + times.Count)); 
-                break; 
-            case DECAY_TYPE.HARMONIC: 
-                alarm.Interval = (1f + times.Count) / (1f / deadline + times.Aggregate((a, b) => 1f / b + 1f / a)); 
-                break; 
-            default: 
-                alarm.Interval = deadline; 
-                break; 
-        } 
-    } 
-} 
-</code> 
- 
-As a practical example, ''wasAdaptiveAlarm'' has been incorporated and used throughout [[secondlife/scripted_agents/corrade|Corrade]] in order to receive an unknown number events as fast as possible without raising the signal too soon and thereby losing events. 
-====== Combine Multiple Paths ====== 
- 
-In .NET, ''Path.Combine'' takes two parameters such that you cannot provide several path elements in order to construct a path. Instead the ''wasPathCombine'' takes a variable number of parameters and combines them as a path: 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Combine multiple paths. 
-/// </summary> 
-/// <param name="paths">an array of paths</param> 
-/// <returns>a combined path</returns> 
-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], paths[1]), wasPathCombine(paths.Skip(2).ToArray())); 
-} 
-</code> 
- 
-====== Convert a Decimal Number to a Given Base ====== 
- 
-Inspired from [[http://www.pvladov.com/2012/05/decimal-to-arbitrary-numeral-system.html|Pavel Vladov's converter]], ''wasIntegerToBase'' is able to convert a decimal number to any base (up to base 68) by making use of all the printable characters in the ASCII character set. 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Converts the given decimal value to the numeral system with the 
-///     specified base radix in the range [2, 68]. 
-/// </summary> 
-/// <param name="value">The value to convert.</param> 
-/// <param name="radix">The radix of the destination numeral system (in the range [2, 68]).</param> 
-/// <returns>a string containing the value in base radix</returns> 
-public static string wasIntegerToBase(long value, int radix) { 
-    const string alphabet = @ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ !#$%&'()*+,-./:;<=>?@[\]^_`(|)~"; 
- 
-    if (radix < 2 || radix > alphabet.Length) 
-        throw new ArgumentException("The radix must be >= 2 and <= " + alphabet.Length.ToString(CultureInfo.InvariantCulture) + "."); 
- 
-    if (value == 0) return "0"; 
- 
-    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, i, 64 - i); 
- 
-    return sb.ToString(); 
-} 
- 
-</code> 
- 
-====== 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; 
-            } 
-        } 
-    } 
-} 
-</code> 
- 
-====== 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)/2; 
-    if(a[mid] > i) 
-        return BinarySearch(a, i, min, mid - 1); 
-    if(a[mid] < i) 
-        return BinarySearch(a, i, mid + 1, max); 
-    return i; 
-} 
-</code> 
- 
-====== Quicksort ====== 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-public static List<int> Quicksort(List<int> l) { 
-    if (l.Count <= 1) { 
-        return l; 
-    } 
- 
-    int pivot = l[l.Count / 2]; 
-     
-    List<int> less = new List<int>(); 
-    List<int> more = new List<int>(); 
- 
-    foreach (int i in l) { 
-        if (i < pivot) 
-        { 
-            less.Add(i); 
-        } 
-        if (i > pivot) 
-        { 
-            more.Add(i); 
-        } 
-    } 
- 
-    List<int> result = new List<int>(); 
-    result.AddRange(Quicksort(less)); 
-    result.Add(pivot); 
-    result.AddRange(Quicksort(more)); 
- 
-    return result; 
-} 
-</code> 
- 
-====== Get Field or Property from Nested Class by Fully Qualified Name ====== 
- 
-The ''GetFP'' extension will return either a value of a field in a class, the value of a property or null in case no field or properties matched. 
- 
-<code csharp> 
-/////////////////////////////////////////////////////////////////////////// 
-//    Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3    // 
-/////////////////////////////////////////////////////////////////////////// 
-/// <summary> 
-///     Get field or property from a class by supplying a path. 
-/// </summary> 
-/// <typeparam name="T">the type of the object</typeparam> 
-/// <param name="o">the object</param> 
-/// <param name="path">the fully qualified path to the field of property</param> 
-/// <param name="flags">the binding flags to use</param> 
-/// <returns> 
-///     the last object in the fully qualified path or null in case the field or property could not be found 
-/// </returns> 
-public static object GetFP<T>(this T o, string path, 
-    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], flags); 
- 
-    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, i) => a + @"." + i), flags) 
-                : o.GetType().GetField(path).GetValue(o); 
-        case MemberTypes.Property: 
-            return components.Length > 1 
-                ? GetFP(o.GetType().GetProperty(components[0], flags).GetValue(o), 
-                    components.Skip(1).Aggregate((a, i) => a + @"." + i), flags) 
-                : o.GetType().GetProperty(path).GetValue(o); 
-    } 
- 
-    return null; 
-} 
-</code> 
- 
-The search is performed by fully qualified name. For instance: 
-<code csharp> 
-var o = object.GetFP("Class.Member.Class.Field"); 
-</code> 
  

fuss/csharp.txt · Last modified: 2022/04/19 08:28 by 127.0.0.1

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.