/* * Copyright (c) 2006-2014, openmetaverse.org * All rights reserved. * * - Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - Neither the name of the openmetaverse.org nor the names * of its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ using System; using System.Collections.Generic; namespace OpenMetaverse { /// /// The InternalDictionary class is used through the library for storing key/value pairs. /// It is intended to be a replacement for the generic Dictionary class and should /// be used in its place. It contains several methods for allowing access to the data from /// outside the library that are read only and thread safe. /// /// /// Key /// Value public class InternalDictionary { /// Internal dictionary that this class wraps around. Do not /// modify or enumerate the contents of this dictionary without locking /// on this member internal Dictionary Dictionary; public Dictionary Copy() { lock (Dictionary) return new Dictionary(Dictionary); } /// /// Gets the number of Key/Value pairs contained in the /// public int Count { get { return Dictionary.Count; } } /// /// Initializes a new instance of the Class /// with the specified key/value, has the default initial capacity. /// /// /// /// // initialize a new InternalDictionary named testDict with a string as the key and an int as the value. /// public InternalDictionary<string, int> testDict = new InternalDictionary<string, int>(); /// /// public InternalDictionary() { Dictionary = new Dictionary(); } /// /// Initializes a new instance of the Class /// with the specified key/value, has its initial valies copied from the specified /// /// /// /// to copy initial values from /// /// /// // initialize a new InternalDictionary named testAvName with a UUID as the key and an string as the value. /// // populates with copied values from example KeyNameCache Dictionary. /// /// // create source dictionary /// Dictionary<UUID, string> KeyNameCache = new Dictionary<UUID, string>(); /// KeyNameCache.Add("8300f94a-7970-7810-cf2c-fc9aa6cdda24", "Jack Avatar"); /// KeyNameCache.Add("27ba1e40-13f7-0708-3e98-5819d780bd62", "Jill Avatar"); /// /// // Initialize new dictionary. /// public InternalDictionary<UUID, string> testAvName = new InternalDictionary<UUID, string>(KeyNameCache); /// /// public InternalDictionary(IDictionary dictionary) { Dictionary = new Dictionary(dictionary); } /// /// Initializes a new instance of the Class /// with the specified key/value, With its initial capacity specified. /// /// Initial size of dictionary /// /// /// // initialize a new InternalDictionary named testDict with a string as the key and an int as the value, /// // initially allocated room for 10 entries. /// public InternalDictionary<string, int> testDict = new InternalDictionary<string, int>(10); /// /// public InternalDictionary(int capacity) { Dictionary = new Dictionary(capacity); } /// /// Try to get entry from with specified key /// /// Key to use for lookup /// Value returned /// if specified key exists, if not found /// /// /// // find your avatar using the Simulator.ObjectsAvatars InternalDictionary: /// Avatar av; /// if (Client.Network.CurrentSim.ObjectsAvatars.TryGetValue(Client.Self.AgentID, out av)) /// Console.WriteLine("Found Avatar {0}", av.Name); /// /// /// public bool TryGetValue(TKey key, out TValue value) { lock (Dictionary) { return Dictionary.TryGetValue(key, out value); } } /// /// Finds the specified match. /// /// The match. /// Matched value /// /// /// // use a delegate to find a prim in the ObjectsPrimitives InternalDictionary /// // with the ID 95683496 /// uint findID = 95683496; /// Primitive findPrim = sim.ObjectsPrimitives.Find( /// delegate(Primitive prim) { return prim.ID == findID; }); /// /// public TValue Find(Predicate match) { lock (Dictionary) { foreach (TValue value in Dictionary.Values) { if (match(value)) return value; } } return default(TValue); } /// Find All items in an /// return matching items. /// a containing found items. /// /// Find All prims within 20 meters and store them in a List /// /// int radius = 20; /// List<Primitive> prims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll( /// delegate(Primitive prim) { /// Vector3 pos = prim.Position; /// return ((prim.ParentID == 0) && (pos != Vector3.Zero) && (Vector3.Distance(pos, location) < radius)); /// } /// ); /// /// public List FindAll(Predicate match) { List found = new List(); lock (Dictionary) { foreach (KeyValuePair kvp in Dictionary) { if (match(kvp.Value)) found.Add(kvp.Value); } } return found; } /// Find All items in an /// return matching keys. /// a containing found keys. /// /// Find All keys which also exist in another dictionary /// /// List<UUID> matches = myDict.FindAll( /// delegate(UUID id) { /// return myOtherDict.ContainsKey(id); /// } /// ); /// /// public List FindAll(Predicate match) { List found = new List(); lock (Dictionary) { foreach (KeyValuePair kvp in Dictionary) { if (match(kvp.Key)) found.Add(kvp.Key); } } return found; } /// Perform an on each entry in an /// to perform /// /// /// // Iterates over the ObjectsPrimitives InternalDictionary and prints out some information. /// Client.Network.CurrentSim.ObjectsPrimitives.ForEach( /// delegate(Primitive prim) /// { /// if (prim.Text != null) /// { /// Console.WriteLine("NAME={0} ID = {1} TEXT = '{2}'", /// prim.PropertiesFamily.Name, prim.ID, prim.Text); /// } /// }); /// /// public void ForEach(Action action) { lock (Dictionary) { foreach (TValue value in Dictionary.Values) { action(value); } } } /// Perform an on each key of an /// to perform public void ForEach(Action action) { lock (Dictionary) { foreach (TKey key in Dictionary.Keys) { action(key); } } } /// /// Perform an on each KeyValuePair of an /// /// to perform public void ForEach(Action> action) { lock (Dictionary) { foreach (KeyValuePair entry in Dictionary) { action(entry); } } } /// Check if Key exists in Dictionary /// Key to check for /// if found, otherwise public bool ContainsKey(TKey key) { return Dictionary.ContainsKey(key); } /// Check if Value exists in Dictionary /// Value to check for /// if found, otherwise public bool ContainsValue(TValue value) { return Dictionary.ContainsValue(value); } /// /// Adds the specified key to the dictionary, dictionary locking is not performed, /// /// /// The key /// The value internal void Add(TKey key, TValue value) { lock (Dictionary) Dictionary.Add(key, value); } /// /// Removes the specified key, dictionary locking is not performed /// /// The key. /// if successful, otherwise internal bool Remove(TKey key) { lock (Dictionary) return Dictionary.Remove(key); } /// /// Indexer for the dictionary /// /// The key /// The value public TValue this[TKey key] { get { lock (Dictionary) return Dictionary[key]; } internal set { lock (Dictionary) Dictionary[key] = value; } } } }