// ---------------------------------------------------------------------------- // // Photon Extensions - Copyright (C) 2018 Exit Games GmbH // // // Provides some helpful methods and extensions for Hashtables, etc. // // developer@photonengine.com // ---------------------------------------------------------------------------- #if UNITY_4_7 || UNITY_5 || UNITY_5_3_OR_NEWER #define SUPPORTED_UNITY #endif namespace Photon.Realtime { using System.Collections; using System.Collections.Generic; using ExitGames.Client.Photon; #if SUPPORTED_UNITY using UnityEngine; using Debug = UnityEngine.Debug; #endif #if SUPPORTED_UNITY || NETFX_CORE using Hashtable = ExitGames.Client.Photon.Hashtable; using SupportClass = ExitGames.Client.Photon.SupportClass; #endif /// /// This static class defines some useful extension methods for several existing classes (e.g. Vector3, float and others). /// public static class Extensions { /// /// Merges all keys from addHash into the target. Adds new keys and updates the values of existing keys in target. /// /// The IDictionary to update. /// The IDictionary containing data to merge into target. public static void Merge(this IDictionary target, IDictionary addHash) { if (addHash == null || target.Equals(addHash)) { return; } foreach (object key in addHash.Keys) { target[key] = addHash[key]; } } /// /// Merges keys of type string to target Hashtable. /// /// /// Does not remove keys from target (so non-string keys CAN be in target if they were before). /// /// The target IDicitionary passed in plus all string-typed keys from the addHash. /// A IDictionary that should be merged partly into target to update it. public static void MergeStringKeys(this IDictionary target, IDictionary addHash) { if (addHash == null || target.Equals(addHash)) { return; } foreach (object key in addHash.Keys) { // only merge keys of type string if (key is string) { target[key] = addHash[key]; } } } /// Helper method for debugging of IDictionary content, inlcuding type-information. Using this is not performant. /// Should only be used for debugging as necessary. /// Some Dictionary or Hashtable. /// String of the content of the IDictionary. public static string ToStringFull(this IDictionary origin) { return SupportClass.DictionaryToString(origin, false); } /// Helper method for debugging of List content. Using this is not performant. /// Should only be used for debugging as necessary. /// Any List where T implements .ToString(). /// A comma-separated string containing each value's ToString(). public static string ToStringFull(this List data) { if (data == null) return "null"; string[] sb = new string[data.Count]; for (int i = 0; i < data.Count; i++) { object o = data[i]; sb[i] = (o != null) ? o.ToString() : "null"; } return string.Join(", ", sb); } /// Helper method for debugging of object[] content. Using this is not performant. /// Should only be used for debugging as necessary. /// Any object[]. /// A comma-separated string containing each value's ToString(). public static string ToStringFull(this object[] data) { if (data == null) return "null"; string[] sb = new string[data.Length]; for (int i = 0; i < data.Length; i++) { object o = data[i]; sb[i] = (o != null) ? o.ToString() : "null"; } return string.Join(", ", sb); } /// /// This method copies all string-typed keys of the original into a new Hashtable. /// /// /// Does not recurse (!) into hashes that might be values in the root-hash. /// This does not modify the original. /// /// The original IDictonary to get string-typed keys from. /// New Hashtable containing only string-typed keys of the original. public static Hashtable StripToStringKeys(this IDictionary original) { Hashtable target = new Hashtable(); if (original != null) { foreach (object key in original.Keys) { if (key is string) { target[key] = original[key]; } } } return target; } /// Used by StripKeysWithNullValues. /// /// By making keysWithNullValue a static variable to clear before using, allocations only happen during the warm-up phase /// as the list needs to grow. Once it hit the high water mark for keys you need to remove. /// private static readonly List keysWithNullValue = new List(); /// Removes all keys with null values. /// /// Photon properties are removed by setting their value to null. Changes the original IDictionary! /// Uses lock(keysWithNullValue), which should be no problem in expected use cases. /// /// The IDictionary to strip of keys with null value. public static void StripKeysWithNullValues(this IDictionary original) { lock (keysWithNullValue) { keysWithNullValue.Clear(); foreach (DictionaryEntry entry in original) { if (entry.Value == null) { keysWithNullValue.Add(entry.Key); } } for (int i = 0; i < keysWithNullValue.Count; i++) { var key = keysWithNullValue[i]; original.Remove(key); } } } /// /// Checks if a particular integer value is in an int-array. /// /// This might be useful to look up if a particular actorNumber is in the list of players of a room. /// The array of ints to check. /// The number to lookup in target. /// True if nr was found in target. public static bool Contains(this int[] target, int nr) { if (target == null) { return false; } for (int index = 0; index < target.Length; index++) { if (target[index] == nr) { return true; } } return false; } } }