From 860b2a502f797e5822c6705d4639f370f3ac5861 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 16 Sep 2010 17:30:46 -0700 Subject: Changed SceneObjectGroup to store parts with the fast and thread-safe MapAndArray collection --- .../ContentManagementSystem/CMEntityCollection.cs | 19 +-- .../ContentManagementSystem/CMModel.cs | 35 ++--- .../ContentManagementSystem/CMView.cs | 9 +- .../ContentManagementEntity.cs | 169 ++++++++++----------- .../ContentManagementSystem/MetaEntity.cs | 45 +++--- .../Scripting/Minimodule/SOPObject.cs | 6 +- 6 files changed, 124 insertions(+), 159 deletions(-) (limited to 'OpenSim/Region/OptionalModules') diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs index d21b652..7f64ebd 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs @@ -121,19 +121,16 @@ namespace OpenSim.Region.OptionalModules.ContentManagement continue; temp = (SceneObjectGroup) currObj; - lock (temp.Children) + if (m_CMEntityHash.ContainsKey(temp.UUID)) { - if (m_CMEntityHash.ContainsKey(temp.UUID)) - { - foreach (SceneObjectPart part in temp.Children.Values) - if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) - missingList.Add(part); - } - else //Entire group is missing from revision. (and is a new part in region) - { - foreach (SceneObjectPart part in temp.Children.Values) + foreach (SceneObjectPart part in temp.Parts) + if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) missingList.Add(part); - } + } + else //Entire group is missing from revision. (and is a new part in region) + { + foreach (SceneObjectPart part in temp.Parts) + missingList.Add(part); } } return missingList; diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs index 0b02a9f..3a6996e 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs @@ -167,11 +167,11 @@ namespace OpenSim.Region.OptionalModules.ContentManagement public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) { // Deal with new parts not revisioned that have been deleted. - lock (group.Children) + SceneObjectPart[] parts = group.Parts; + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in group.Children.Values) - if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) - m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID); + if (m_MetaEntityCollection.Auras.ContainsKey(parts[i].UUID)) + m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(parts[i].UUID); } } @@ -210,12 +210,10 @@ namespace OpenSim.Region.OptionalModules.ContentManagement { temp = SceneObjectSerializer.FromXml2Format(xml); temp.SetScene(scene); - - lock (temp.Children) - { - foreach (SceneObjectPart part in temp.Children.Values) - part.RegionHandle = scene.RegionInfo.RegionHandle; - } + + SceneObjectPart[] parts = temp.Parts; + for (int i = 0; i < parts.Length; i++) + parts[i].RegionHandle = scene.RegionInfo.RegionHandle; ReplacementList.Add(temp.UUID, (EntityBase)temp); } @@ -346,17 +344,16 @@ namespace OpenSim.Region.OptionalModules.ContentManagement System.Collections.ArrayList auraList = new System.Collections.ArrayList(); if (group == null) return null; - - lock (group.Children) + + SceneObjectPart[] parts = group.Parts; + for (int i = 0; i < parts.Length; i++) { - foreach (SceneObjectPart part in group.Children.Values) + SceneObjectPart part = parts[i]; + if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) { - if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) - { - ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale); - ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); - auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); - } + ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0, 254, 0), part.Scale); + ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); + auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); } } diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs index f75f40a..3807ccd 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs @@ -186,12 +186,9 @@ namespace OpenSim.Region.OptionalModules.ContentManagement ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll(); // Deal with new parts not revisioned that have been deleted. - lock (group.Children) - { - foreach (SceneObjectPart part in group.Children.Values) - if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) - ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); - } + foreach (SceneObjectPart part in group.Parts) + if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) + ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); } public void SendMetaEntitiesToNewClient(IClientAPI client) diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs index 49d20e1..0248f36 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs @@ -132,33 +132,30 @@ namespace OpenSim.Region.OptionalModules.ContentManagement // if group is not contained in scene's list if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) { - lock (m_UnchangedEntity.Children) + foreach (SceneObjectPart part in m_UnchangedEntity.Parts) { - foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) + // if scene list no longer contains this part, display translucent part and mark with red aura + if (!ContainsKey(sceneEntityList, part.UUID)) { - // if scene list no longer contains this part, display translucent part and mark with red aura - if (!ContainsKey(sceneEntityList, part.UUID)) + // if already displaying a red aura over part, make sure its red + if (m_AuraEntities.ContainsKey(part.UUID)) { - // if already displaying a red aura over part, make sure its red - if (m_AuraEntities.ContainsKey(part.UUID)) - { - m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale); - } - else - { - AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, - part.GetWorldPosition(), - MetaEntity.TRANSLUCENT, - new Vector3(254,0,0), - part.Scale - ); - m_AuraEntities.Add(part.UUID, auraGroup); - } - SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); - SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); + m_AuraEntities[part.UUID].SetAura(new Vector3(254, 0, 0), part.Scale); + } + else + { + AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, + part.GetWorldPosition(), + MetaEntity.TRANSLUCENT, + new Vector3(254, 0, 0), + part.Scale + ); + m_AuraEntities.Add(part.UUID, auraGroup); } - // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id + SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); + SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); } + // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id } // a deleted part has no where to point a beam particle system, @@ -183,11 +180,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement /// public bool HasChildPrim(UUID uuid) { - lock (m_UnchangedEntity.Children) - if (m_UnchangedEntity.Children.ContainsKey(uuid)) - return true; - - return false; + return m_UnchangedEntity.ContainsPart(uuid); } /// @@ -195,12 +188,9 @@ namespace OpenSim.Region.OptionalModules.ContentManagement /// public bool HasChildPrim(uint localID) { - lock (m_UnchangedEntity.Children) - { - foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) - if (part.LocalId == localID) - return true; - } + foreach (SceneObjectPart part in m_UnchangedEntity.Parts) + if (part.LocalId == localID) + return true; return false; } @@ -237,72 +227,37 @@ namespace OpenSim.Region.OptionalModules.ContentManagement // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user // had originally saved. // m_Entity will NOT necessarily be the same entity as the user had saved. - lock (m_UnchangedEntity.Children) + foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Parts) { - foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values) + //This is the part that we use to show changes. + metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum); + if (sceneEntityGroup.ContainsPart(UnchangedPart.UUID)) { - //This is the part that we use to show changes. - metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum); - if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID)) + sceneEntityPart = sceneEntityGroup.GetChildPart(UnchangedPart.UUID); + differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); + if (differences != Diff.NONE) + metaEntityPart.Text = "CHANGE: " + differences.ToString(); + if (differences != 0) { - sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID]; - differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); - if (differences != Diff.NONE) - metaEntityPart.Text = "CHANGE: " + differences.ToString(); - if (differences != 0) - { - // Root Part that has been modified - if ((differences&Diff.POSITION) > 0) - { - // If the position of any part has changed, make sure the RootPart of the - // meta entity is pointing with a beam particle system - if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) - { - m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); - m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); - } - BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, - m_UnchangedEntity.RootPart.GetWorldPosition(), - MetaEntity.TRANSLUCENT, - sceneEntityPart, - new Vector3(0,0,254) - ); - m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup); - } - - if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) - { - m_AuraEntities[UnchangedPart.UUID].HideFromAll(); - m_AuraEntities.Remove(UnchangedPart.UUID); - } - AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, - UnchangedPart.GetWorldPosition(), - MetaEntity.TRANSLUCENT, - new Vector3(0,0,254), - UnchangedPart.Scale - ); - m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); - SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); - - DiffersFromSceneGroup = true; - } - else // no differences between scene part and meta part + // Root Part that has been modified + if ((differences & Diff.POSITION) > 0) { + // If the position of any part has changed, make sure the RootPart of the + // meta entity is pointing with a beam particle system if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) { m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); } - if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) - { - m_AuraEntities[UnchangedPart.UUID].HideFromAll(); - m_AuraEntities.Remove(UnchangedPart.UUID); - } - SetPartTransparency(metaEntityPart, MetaEntity.NONE); + BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, + m_UnchangedEntity.RootPart.GetWorldPosition(), + MetaEntity.TRANSLUCENT, + sceneEntityPart, + new Vector3(0, 0, 254) + ); + m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup); } - } - else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted. - { + if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) { m_AuraEntities[UnchangedPart.UUID].HideFromAll(); @@ -311,14 +266,46 @@ namespace OpenSim.Region.OptionalModules.ContentManagement AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, UnchangedPart.GetWorldPosition(), MetaEntity.TRANSLUCENT, - new Vector3(254,0,0), + new Vector3(0, 0, 254), UnchangedPart.Scale ); m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); - + DiffersFromSceneGroup = true; } + else // no differences between scene part and meta part + { + if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) + { + m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); + m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); + } + if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) + { + m_AuraEntities[UnchangedPart.UUID].HideFromAll(); + m_AuraEntities.Remove(UnchangedPart.UUID); + } + SetPartTransparency(metaEntityPart, MetaEntity.NONE); + } + } + else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted. + { + if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) + { + m_AuraEntities[UnchangedPart.UUID].HideFromAll(); + m_AuraEntities.Remove(UnchangedPart.UUID); + } + AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, + UnchangedPart.GetWorldPosition(), + MetaEntity.TRANSLUCENT, + new Vector3(254, 0, 0), + UnchangedPart.Scale + ); + m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); + SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); + + DiffersFromSceneGroup = true; } } diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs index d7838c5..c7b1ed7 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs @@ -98,10 +98,9 @@ namespace OpenSim.Region.OptionalModules.ContentManagement #region Public Properties - public Dictionary Children + public SceneObjectPart[] Parts { - get { return m_Entity.Children; } - set { m_Entity.Children = value; } + get { return m_Entity.Parts; } } public uint LocalId @@ -150,19 +149,17 @@ namespace OpenSim.Region.OptionalModules.ContentManagement { //make new uuids Dictionary parts = new Dictionary(); - - lock (m_Entity.Children) + + foreach (SceneObjectPart part in m_Entity.Parts) { - foreach (SceneObjectPart part in m_Entity.Children.Values) - { - part.ResetIDs(part.LinkNum); - parts.Add(part.UUID, part); - } - - //finalize - m_Entity.RootPart.PhysActor = null; - m_Entity.Children = parts; + part.ResetIDs(part.LinkNum); + parts.Add(part.UUID, part); } + + //finalize + m_Entity.RootPart.PhysActor = null; + foreach (SceneObjectPart part in parts.Values) + m_Entity.AddPart(part); } #endregion Protected Methods @@ -177,11 +174,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement //This deletes the group without removing from any databases. //This is important because we are not IN any database. //m_Entity.FakeDeleteGroup(); - lock (m_Entity.Children) - { - foreach (SceneObjectPart part in m_Entity.Children.Values) - client.SendKillObject(m_Entity.RegionHandle, part.LocalId); - } + foreach (SceneObjectPart part in m_Entity.Parts) + client.SendKillObject(m_Entity.RegionHandle, part.LocalId); } /// @@ -189,15 +183,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement /// public virtual void HideFromAll() { - lock (m_Entity.Children) + foreach (SceneObjectPart part in m_Entity.Parts) { - foreach (SceneObjectPart part in m_Entity.Children.Values) - { - m_Entity.Scene.ForEachClient( - delegate(IClientAPI controller) - { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } - ); - } + m_Entity.Scene.ForEachClient( + delegate(IClientAPI controller) + { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } + ); } } diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs index 59ad9d8..faed522 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs @@ -193,11 +193,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule int i = 0; - List partList = null; - lock (my.ParentGroup.Children) - partList = new List(my.ParentGroup.Children.Values); - - foreach (SceneObjectPart part in partList) + foreach (SceneObjectPart part in my.ParentGroup.Parts) { rets[i++] = new SOPObject(m_rootScene, part.LocalId, m_security); } -- cgit v1.1