123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- // ----------------------------------------------------------------------------
- // <copyright file="Extensions.cs" company="Exit Games GmbH">
- // Photon Extensions - Copyright (C) 2018 Exit Games GmbH
- // </copyright>
- // <summary>
- // Provides some helpful methods and extensions for Hashtables, etc.
- // </summary>
- // <author>developer@photonengine.com</author>
- // ----------------------------------------------------------------------------
- #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
- /// <summary>
- /// This static class defines some useful extension methods for several existing classes (e.g. Vector3, float and others).
- /// </summary>
- public static class Extensions
- {
- /// <summary>
- /// Merges all keys from addHash into the target. Adds new keys and updates the values of existing keys in target.
- /// </summary>
- /// <param name="target">The IDictionary to update.</param>
- /// <param name="addHash">The IDictionary containing data to merge into target.</param>
- 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];
- }
- }
- /// <summary>
- /// Merges keys of type string to target Hashtable.
- /// </summary>
- /// <remarks>
- /// Does not remove keys from target (so non-string keys CAN be in target if they were before).
- /// </remarks>
- /// <param name="target">The target IDictionary passed in plus all string-typed keys from the addHash.</param>
- /// <param name="addHash">A IDictionary that should be merged partly into target to update it.</param>
- 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];
- }
- }
- }
- /// <summary>Helper method for debugging of IDictionary content, including type-information. Using this is not performant.</summary>
- /// <remarks>Should only be used for debugging as necessary.</remarks>
- /// <param name="origin">Some Dictionary or Hashtable.</param>
- /// <returns>String of the content of the IDictionary.</returns>
- public static string ToStringFull(this IDictionary origin)
- {
- return SupportClass.DictionaryToString(origin, false);
- }
- /// <summary>Helper method for debugging of List<T> content. Using this is not performant.</summary>
- /// <remarks>Should only be used for debugging as necessary.</remarks>
- /// <param name="data">Any List<T> where T implements .ToString().</param>
- /// <returns>A comma-separated string containing each value's ToString().</returns>
- public static string ToStringFull<T>(this List<T> 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);
- }
- /// <summary>Helper method for debugging of object[] content. Using this is not performant.</summary>
- /// <remarks>Should only be used for debugging as necessary.</remarks>
- /// <param name="data">Any object[].</param>
- /// <returns>A comma-separated string containing each value's ToString().</returns>
- 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);
- }
- /// <summary>
- /// This method copies all string-typed keys of the original into a new Hashtable.
- /// </summary>
- /// <remarks>
- /// Does not recurse (!) into hashes that might be values in the root-hash.
- /// This does not modify the original.
- /// </remarks>
- /// <param name="original">The original IDictonary to get string-typed keys from.</param>
- /// <returns>New Hashtable containing only string-typed keys of the original.</returns>
- 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;
- }
- /// <summary>
- /// This method copies all string-typed keys of the original into a new Hashtable.
- /// </summary>
- /// <remarks>
- /// Does not recurse (!) into hashes that might be values in the root-hash.
- /// This does not modify the original.
- /// </remarks>
- /// <param name="original">The original IDictonary to get string-typed keys from.</param>
- /// <returns>New Hashtable containing only string-typed keys of the original.</returns>
- public static Hashtable StripToStringKeys(this Hashtable original)
- {
- Hashtable target = new Hashtable();
- if (original != null)
- {
- foreach (DictionaryEntry entry in original)
- {
- if (entry.Key is string)
- {
- target[entry.Key] = original[entry.Key];
- }
- }
- }
- return target;
- }
- /// <summary>Used by StripKeysWithNullValues.</summary>
- /// <remarks>
- /// 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.
- /// </remarks>
- private static readonly List<object> keysWithNullValue = new List<object>();
- /// <summary>Removes all keys with null values.</summary>
- /// <remarks>
- /// 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.
- /// </remarks>
- /// <param name="original">The IDictionary to strip of keys with null value.</param>
- 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);
- }
- }
- }
- /// <summary>Removes all keys with null values.</summary>
- /// <remarks>
- /// 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.
- /// </remarks>
- /// <param name="original">The IDictionary to strip of keys with null value.</param>
- public static void StripKeysWithNullValues(this Hashtable 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);
- }
- }
- }
- /// <summary>
- /// Checks if a particular integer value is in an int-array.
- /// </summary>
- /// <remarks>This might be useful to look up if a particular actorNumber is in the list of players of a room.</remarks>
- /// <param name="target">The array of ints to check.</param>
- /// <param name="nr">The number to lookup in target.</param>
- /// <returns>True if nr was found in target.</returns>
- 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;
- }
- }
- }
|