From 5c19a8883eafa6b2a45491694f59f0f73e251016 Mon Sep 17 00:00:00 2001 From: Date: Mon, 9 Jun 2008 23:14:04 +0000 Subject: [PATCH] Slightly different method for addressing LIBOMV-102 (cleanup in OBJECT_TRACKING) git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@1898 52acb1d6-8a22-11de-b505-999d5b087335 --- libsecondlife/ObjectManager.cs | 99 ++++++++++++++++------------------ 1 file changed, 46 insertions(+), 53 deletions(-) diff --git a/libsecondlife/ObjectManager.cs b/libsecondlife/ObjectManager.cs index 9a6dd801..dcb9f387 100644 --- a/libsecondlife/ObjectManager.cs +++ b/libsecondlife/ObjectManager.cs @@ -2123,73 +2123,66 @@ namespace libsecondlife for (int i = 0; i < kill.ObjectData.Length; i++) FireOnObjectKilled(simulator, kill.ObjectData[i].ID); - // Run the for loop multiple times so we only have to lock a total - // of two times. Locking is by far the most expensive operation here - - if (Client.Settings.OBJECT_TRACKING) + lock (simulator.ObjectsPrimitives.Dictionary) { - lock (simulator.ObjectsPrimitives.Dictionary) + List removePrims = new List(); + + if (Client.Settings.OBJECT_TRACKING) { uint localID; for (int i = 0; i < kill.ObjectData.Length; i++) { localID = kill.ObjectData[i].ID; - if (simulator.ObjectsPrimitives.Dictionary.ContainsKey(localID)) - { - FireOnObjectKilled(simulator, localID); - simulator.ObjectsPrimitives.Dictionary.Remove(localID); - } + if (simulator.ObjectsPrimitives.Dictionary.ContainsKey(localID)) removePrims.Add(localID); - simulator.ObjectsPrimitives.ForEach(delegate(Primitive prim) + foreach (KeyValuePair prim in simulator.ObjectsPrimitives.Dictionary) { - if (prim.ParentID == localID) + if (prim.Value.ParentID == localID) { - FireOnObjectKilled(simulator, prim.LocalID); - simulator.ObjectsPrimitives.Dictionary.Remove(prim.LocalID); + FireOnObjectKilled(simulator, prim.Key); + removePrims.Add(prim.Key); } - }); - } - } - } - - if (Client.Settings.AVATAR_TRACKING) - { - lock (simulator.ObjectsPrimitives.Dictionary) - { - lock (simulator.ObjectsAvatars.Dictionary) - { - uint localID; - for (int i = 0; i < kill.ObjectData.Length; i++) - { - localID = kill.ObjectData[i].ID; - - if (simulator.ObjectsAvatars.Dictionary.ContainsKey(localID)) - simulator.ObjectsAvatars.Dictionary.Remove(localID); - - List rootPrims = new List(); - - simulator.ObjectsPrimitives.ForEach(delegate(Primitive prim) - { - if (prim.ParentID == localID) - { - FireOnObjectKilled(simulator, prim.LocalID); - simulator.ObjectsPrimitives.Dictionary.Remove(prim.LocalID); - rootPrims.Add(prim.LocalID); - } - }); - - simulator.ObjectsPrimitives.ForEach(delegate(Primitive prim) - { - if (rootPrims.Contains(prim.ParentID)) - { - FireOnObjectKilled(simulator, prim.LocalID); - simulator.ObjectsPrimitives.Dictionary.Remove(prim.LocalID); - } - }); } } } + + if (Client.Settings.AVATAR_TRACKING) + { + uint localID; + for (int i = 0; i < kill.ObjectData.Length; i++) + { + localID = kill.ObjectData[i].ID; + + if (simulator.ObjectsAvatars.Dictionary.ContainsKey(localID)) removePrims.Add(localID); + + List rootPrims = new List(); + + foreach (KeyValuePair prim in simulator.ObjectsPrimitives.Dictionary) + { + if (prim.Value.ParentID == localID) + { + FireOnObjectKilled(simulator, prim.Key); + removePrims.Add(prim.Key); + rootPrims.Add(prim.Key); + } + } + + foreach (KeyValuePair prim in simulator.ObjectsPrimitives.Dictionary) + { + if (rootPrims.Contains(prim.Value.ParentID)) + { + FireOnObjectKilled(simulator, prim.Key); + removePrims.Add(prim.Key); + } + } + } + } + + //Do the actual removing outside of the loops but still inside the lock. + //This safely prevents the collection from being modified during a loop. + foreach (uint removeID in removePrims) + simulator.ObjectsPrimitives.Remove(removeID); } }