From 4a898fdf8dfb93e464d677c281e732ac0cc2c469 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 17 Jul 2010 00:26:26 +0100 Subject: Fix bugs in llRot2Euler() Applies patch in http://opensimulator.org/mantis/view.php?id=4482. Thanks Micheil Merlin! --- .../Shared/Api/Implementation/LSL_Api.cs | 28 ++++++---------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c5226ba..41e1a33 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -465,22 +465,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke - // Utility function for llRot2Euler - - // normalize an angle between -PI and PI (-180 to +180 degrees) - protected double NormalizeAngle(double angle) - { - if (angle > -Math.PI && angle < Math.PI) - return angle; - - int numPis = (int)(Math.PI / angle); - double remainder = angle - Math.PI * numPis; - if (numPis % 2 == 1) - return Math.PI - angle; - return remainder; - } - - // Old implementation of llRot2Euler, now normalized + // Old implementation of llRot2Euler. Normalization not required as Atan2 function will + // only return values >= -PI (-180 degrees) and <= PI (180 degrees). public LSL_Vector llRot2Euler(LSL_Rotation r) { @@ -492,13 +478,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api double n = 2 * (r.y * r.s + r.x * r.z); double p = m * m - n * n; if (p > 0) - return new LSL_Vector(NormalizeAngle(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s))), - NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))), - NormalizeAngle(Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s)))); + return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), + Math.Atan2(n, Math.Sqrt(p)), + Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); else if (n > 0) - return new LSL_Vector(0.0, Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z))); + return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); else - return new LSL_Vector(0.0, -Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z))); + return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); } /* From wiki: -- cgit v1.1 From 20c68cc531d141536854ff256da2b46ce37a2086 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 17 Jul 2010 00:35:51 +0100 Subject: Allow use of old angle rules PSYS_SRC_INNERANGLE and PSYS_SRC_OUTERANGLE in llParticleSystem() This is a patch from http://opensimulator.org/mantis/view.php?id=3201 Thanks Micheil Martin! --- .../Shared/Api/Implementation/LSL_Api.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 41e1a33..f3f7269 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5860,6 +5860,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api PSYS_PART_MAX_AGE = 7, PSYS_SRC_ACCEL = 8, PSYS_SRC_PATTERN = 9, + PSYS_SRC_INNERANGLE = 10, + PSYS_SRC_OUTERANGLE = 11, PSYS_SRC_TEXTURE = 12, PSYS_SRC_BURST_RATE = 13, PSYS_SRC_BURST_PART_COUNT = 15, @@ -5992,6 +5994,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api prules.Pattern = (Primitive.ParticleSystem.SourcePattern)tmpi; break; + // PSYS_SRC_INNERANGLE and PSYS_SRC_ANGLE_BEGIN use the same variables. The + // PSYS_SRC_OUTERANGLE and PSYS_SRC_ANGLE_END also use the same variable. The + // client tells the difference between the two by looking at the 0x02 bit in + // the PartFlags variable. + case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE: + tempf = (float)rules.GetLSLFloatItem(i + 1); + prules.InnerAngle = (float)tempf; + prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off. + break; + + case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE: + tempf = (float)rules.GetLSLFloatItem(i + 1); + prules.OuterAngle = (float)tempf; + prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off. + break; + case (int)ScriptBaseClass.PSYS_SRC_TEXTURE: prules.Texture = KeyOrName(rules.GetLSLStringItem(i + 1)); break; @@ -6048,11 +6066,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case (int)ScriptBaseClass.PSYS_SRC_ANGLE_BEGIN: tempf = (float)rules.GetLSLFloatItem(i + 1); prules.InnerAngle = (float)tempf; + prules.PartFlags |= 0x02; // Set new angle format. break; case (int)ScriptBaseClass.PSYS_SRC_ANGLE_END: tempf = (float)rules.GetLSLFloatItem(i + 1); prules.OuterAngle = (float)tempf; + prules.PartFlags |= 0x02; // Set new angle format. break; } -- cgit v1.1 From 251740815fe39b99751aac5a6eedc7d4dc5bcbff Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 19 Jul 2010 14:36:53 +0100 Subject: Revert "Thank you, Snoopy, for a patch to reduce sim script startup CPU usage" This reverts commit c404c5fb5405eac24cc8b7cd402eb8d8fb0ff0cf. --- .../Framework/Scenes/SceneObjectPartInventory.cs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3a8f168..866bb6e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -31,7 +31,6 @@ using System.IO; using System.Collections.Generic; using System.Collections; using System.Reflection; -using System.Threading; using OpenMetaverse; using log4net; using OpenSim.Framework; @@ -201,7 +200,6 @@ namespace OpenSim.Region.Framework.Scenes if ((int)InventoryType.LSL == item.InvType) { CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); - Thread.Sleep(10); // workaround for Mono cpu utilization > 100% bug } } } @@ -259,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes // m_log.InfoFormat( // "[PRIM INVENTORY]: " + // "Starting script {0}, {1} in prim {2}, {3}", - // item.Name, item.ItemID, m_part.Name, m_part.UUID); + // item.Name, item.ItemID, Name, UUID); if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) return; @@ -295,20 +293,20 @@ namespace OpenSim.Region.Framework.Scenes } else { + if (m_part.ParentGroup.m_savedScriptState != null) + RestoreSavedScriptState(item.OldItemID, item.ItemID); + lock (m_items) { - if (m_part.ParentGroup.m_savedScriptState != null) - RestoreSavedScriptState(item.OldItemID, item.ItemID); - m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; - - string script = Utils.BytesToString(asset.Data); - m_part.ParentGroup.Scene.EventManager.TriggerRezScript( - m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); - m_part.ParentGroup.AddActiveScriptCount(1); - m_part.ScheduleFullUpdate(); } + + string script = Utils.BytesToString(asset.Data); + m_part.ParentGroup.Scene.EventManager.TriggerRezScript( + m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); + m_part.ParentGroup.AddActiveScriptCount(1); + m_part.ScheduleFullUpdate(); } } } -- cgit v1.1 From 128da70d15b4d432cd717939c112c1b8319d874d Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 19 Jul 2010 14:37:27 +0100 Subject: re-add the sleep lost in the revert. --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 866bb6e..c5a4cf6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -31,6 +31,7 @@ using System.IO; using System.Collections.Generic; using System.Collections; using System.Reflection; +using System.Threading; using OpenMetaverse; using log4net; using OpenSim.Framework; @@ -200,6 +201,7 @@ namespace OpenSim.Region.Framework.Scenes if ((int)InventoryType.LSL == item.InvType) { CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); + Thread.Sleep(10); // workaround for Mono cpu utilization > 100% bug } } } -- cgit v1.1 From 5a8ddfe21144aef54ba3f77b665a8f2a20ecbda4 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 19 Jul 2010 08:07:37 -0700 Subject: Deleted Snoopy's patch completely, including Thread.Sleep. Preliminary tests indicate that this is what causes deadlock. More tests needed. --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index c5a4cf6..3519d4b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -201,7 +201,6 @@ namespace OpenSim.Region.Framework.Scenes if ((int)InventoryType.LSL == item.InvType) { CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); - Thread.Sleep(10); // workaround for Mono cpu utilization > 100% bug } } } -- cgit v1.1 From 699d3b0965a5e77c967365dec41813fe9e196836 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 19 Jul 2010 13:59:11 -0700 Subject: One more stab at http://opensimulator.org/mantis/view.php?id=4858. Eliminated the nested locks of m_Scripts and m_PrimObjects. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 66 +++++++++++++------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 808cf82..b8bdc19 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -818,60 +818,60 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_CompileDict.Remove(itemID); } + IScriptInstance instance = null; + lock (m_Scripts) { // Do we even have it? if (!m_Scripts.ContainsKey(itemID)) return; - IScriptInstance instance=m_Scripts[itemID]; + instance=m_Scripts[itemID]; m_Scripts.Remove(itemID); + } - instance.ClearQueue(); - instance.Stop(0); - + instance.ClearQueue(); + instance.Stop(0); // bool objectRemoved = false; - lock (m_PrimObjects) + lock (m_PrimObjects) + { + // Remove the script from it's prim + if (m_PrimObjects.ContainsKey(localID)) { - // Remove the script from it's prim - if (m_PrimObjects.ContainsKey(localID)) - { - // Remove inventory item record - if (m_PrimObjects[localID].Contains(itemID)) - m_PrimObjects[localID].Remove(itemID); + // Remove inventory item record + if (m_PrimObjects[localID].Contains(itemID)) + m_PrimObjects[localID].Remove(itemID); - // If there are no more scripts, remove prim - if (m_PrimObjects[localID].Count == 0) - { - m_PrimObjects.Remove(localID); + // If there are no more scripts, remove prim + if (m_PrimObjects[localID].Count == 0) + { + m_PrimObjects.Remove(localID); // objectRemoved = true; - } } } + } - instance.RemoveState(); - instance.DestroyScriptInstance(); + instance.RemoveState(); + instance.DestroyScriptInstance(); - m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); - if (m_DomainScripts[instance.AppDomain].Count == 0) - { - m_DomainScripts.Remove(instance.AppDomain); - UnloadAppDomain(instance.AppDomain); - } - - instance = null; + m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); + if (m_DomainScripts[instance.AppDomain].Count == 0) + { + m_DomainScripts.Remove(instance.AppDomain); + UnloadAppDomain(instance.AppDomain); + } - ObjectRemoved handlerObjectRemoved = OnObjectRemoved; - if (handlerObjectRemoved != null) - { - SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); - handlerObjectRemoved(part.UUID); - } + instance = null; - CleanAssemblies(); + ObjectRemoved handlerObjectRemoved = OnObjectRemoved; + if (handlerObjectRemoved != null) + { + SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); + handlerObjectRemoved(part.UUID); } + ScriptRemoved handlerScriptRemoved = OnScriptRemoved; if (handlerScriptRemoved != null) handlerScriptRemoved(itemID); -- cgit v1.1 From 257a46dfb9d722de1e1bcf331c2def0549fb998e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 19 Jul 2010 15:20:34 -0700 Subject: Another stab at http://opensimulator.org/mantis/view.php?id=4858. Eliminated more nested locks. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 64 +++++++++++++++----------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index b8bdc19..aff4bda 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -701,9 +701,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } + ScriptInstance instance = null; lock (m_Scripts) { - ScriptInstance instance = null; // Create the object record if ((!m_Scripts.ContainsKey(itemID)) || @@ -784,28 +784,29 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_Scripts[itemID] = instance; } + } - lock (m_PrimObjects) - { - if (!m_PrimObjects.ContainsKey(localID)) - m_PrimObjects[localID] = new List(); + lock (m_PrimObjects) + { + if (!m_PrimObjects.ContainsKey(localID)) + m_PrimObjects[localID] = new List(); - if (!m_PrimObjects[localID].Contains(itemID)) - m_PrimObjects[localID].Add(itemID); + if (!m_PrimObjects[localID].Contains(itemID)) + m_PrimObjects[localID].Add(itemID); - } + } - if (!m_Assemblies.ContainsKey(assetID)) - m_Assemblies[assetID] = assembly; + if (!m_Assemblies.ContainsKey(assetID)) + m_Assemblies[assetID] = assembly; - lock (m_AddingAssemblies) - { - m_AddingAssemblies[assembly]--; - } - - if (instance!=null) - instance.Init(); + lock (m_AddingAssemblies) + { + m_AddingAssemblies[assembly]--; } + + if (instance != null) + instance.Init(); + return true; } @@ -1005,26 +1006,33 @@ namespace OpenSim.Region.ScriptEngine.XEngine public bool PostObjectEvent(uint localID, EventParams p) { bool result = false; - + List uuids = null; + lock (m_PrimObjects) { if (!m_PrimObjects.ContainsKey(localID)) return false; - - foreach (UUID itemID in m_PrimObjects[localID]) + uuids = m_PrimObjects[localID]; + } + + foreach (UUID itemID in uuids) + { + IScriptInstance instance = null; + try { if (m_Scripts.ContainsKey(itemID)) - { - IScriptInstance instance = m_Scripts[itemID]; - if (instance != null) - { - instance.PostEvent(p); - result = true; - } - } + instance = m_Scripts[itemID]; + } + catch { /* ignore race conditions */ } + + if (instance != null) + { + instance.PostEvent(p); + result = true; } } + return result; } -- cgit v1.1 From d93a442483a6afbcd85b881d2b168d25ac31f0ae Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 20 Jul 2010 05:59:18 -0700 Subject: Relaxed the ultra-conservative lock on m_items. Needs testing under linux and stress. --- .../Framework/Scenes/SceneObjectPartInventory.cs | 407 ++++++++++----------- 1 file changed, 188 insertions(+), 219 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3519d4b..20d5486 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -118,20 +118,20 @@ namespace OpenSim.Region.Framework.Scenes /// Link number for the part public void ResetInventoryIDs() { - lock (Items) + lock (m_items) { - if (0 == Items.Count) + if (0 == m_items.Count) return; HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; - IList items = new List(Items.Values); - Items.Clear(); + IList items = GetInventoryItems(); + m_items.Clear(); foreach (TaskInventoryItem item in items) { item.ResetIDs(m_part.UUID); - Items.Add(item.ItemID, item); + m_items.Add(item.ItemID, item); } } } @@ -148,17 +148,17 @@ namespace OpenSim.Region.Framework.Scenes { return; } + } - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; - IList items = new List(Items.Values); - foreach (TaskInventoryItem item in items) + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + List items = GetInventoryItems(); + foreach (TaskInventoryItem item in items) + { + if (ownerId != item.OwnerID) { - if (ownerId != item.OwnerID) - { - item.LastOwnerID = item.OwnerID; - item.OwnerID = ownerId; - } + item.LastOwnerID = item.OwnerID; + item.OwnerID = ownerId; } } } @@ -175,17 +175,15 @@ namespace OpenSim.Region.Framework.Scenes { return; } + } - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; - IList items = new List(Items.Values); - foreach (TaskInventoryItem item in items) - { - if (groupID != item.GroupID) - { - item.GroupID = groupID; - } - } + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + List items = GetInventoryItems(); + foreach (TaskInventoryItem item in items) + { + if (groupID != item.GroupID) + item.GroupID = groupID; } } @@ -194,16 +192,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) { - lock (m_items) - { - foreach (TaskInventoryItem item in Items.Values) - { - if ((int)InventoryType.LSL == item.InvType) - { - CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); - } - } - } + List scripts = GetInventoryScripts(); + foreach (TaskInventoryItem item in scripts) + CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); } public ArrayList GetScriptErrors(UUID itemID) @@ -236,16 +227,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void RemoveScriptInstances(bool sceneObjectBeingDeleted) { - lock (Items) - { - foreach (TaskInventoryItem item in Items.Values) - { - if ((int)InventoryType.LSL == item.InvType) - { - RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); - } - } - } + List scripts = GetInventoryScripts(); + foreach (TaskInventoryItem item in scripts) + RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); } /// @@ -375,21 +359,15 @@ namespace OpenSim.Region.Framework.Scenes /// public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) { - lock (m_items) - { - if (m_items.ContainsKey(itemId)) - { - CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", - itemId, m_part.Name, m_part.UUID, - m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); - } - } + TaskInventoryItem item = GetInventoryItem(itemId); + if (item != null) + CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); + else + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", + itemId, m_part.Name, m_part.UUID, + m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); } /// @@ -430,16 +408,18 @@ namespace OpenSim.Region.Framework.Scenes /// /// Check if the inventory holds an item with a given name. - /// This method assumes that the task inventory is already locked. /// /// /// private bool InventoryContainsName(string name) { - foreach (TaskInventoryItem item in Items.Values) + lock (m_items) { - if (item.Name == name) - return true; + foreach (TaskInventoryItem item in m_items.Values) + { + if (item.Name == name) + return true; + } } return false; } @@ -482,12 +462,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) { - List il; - - lock (m_items) - { - il = new List(m_items.Values); - } + List il = GetInventoryItems(); foreach (TaskInventoryItem i in il) { @@ -527,14 +502,12 @@ namespace OpenSim.Region.Framework.Scenes item.GroupID = m_part.GroupID; lock (m_items) - { m_items.Add(item.ItemID, item); - if (allowedDrop) - m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); - else - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - } + if (allowedDrop) + m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); + else + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); m_inventorySerial++; //m_inventorySerial += 2; @@ -558,9 +531,8 @@ namespace OpenSim.Region.Framework.Scenes m_items.Add(item.ItemID, item); // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); } + m_inventorySerial++; } - - m_inventorySerial++; } /// @@ -615,45 +587,44 @@ namespace OpenSim.Region.Framework.Scenes public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) { - lock(m_items) + TaskInventoryItem it = GetInventoryItem(item.ItemID); + if (it != null) { - if (m_items.ContainsKey(item.ItemID)) - { - if (m_items.ContainsKey(item.ItemID)) - { - item.ParentID = m_part.UUID; - item.ParentPartID = m_part.UUID; - item.Flags = m_items[item.ItemID].Flags; - - // If group permissions have been set on, check that the groupID is up to date in case it has - // changed since permissions were last set. - if (item.GroupPermissions != (uint)PermissionMask.None) - item.GroupID = m_part.GroupID; + item.ParentID = m_part.UUID; + item.ParentPartID = m_part.UUID; + item.Flags = m_items[item.ItemID].Flags; + + // If group permissions have been set on, check that the groupID is up to date in case it has + // changed since permissions were last set. + if (item.GroupPermissions != (uint)PermissionMask.None) + item.GroupID = m_part.GroupID; - if (item.AssetID == UUID.Zero) - { - item.AssetID = m_items[item.ItemID].AssetID; - } - m_items[item.ItemID] = item; - m_inventorySerial++; - if (fireScriptEvents) - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; - return true; - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", - item.ItemID, m_part.Name, m_part.UUID, - m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); - } + if (item.AssetID == UUID.Zero) + item.AssetID = it.AssetID; + lock (m_items) + { + m_items[item.ItemID] = item; + m_inventorySerial++; } - return false; + + if (fireScriptEvents) + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); + + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + return true; + } + else + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", + item.ItemID, m_part.Name, m_part.UUID, + m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); } + return false; + } /// @@ -664,52 +635,37 @@ namespace OpenSim.Region.Framework.Scenes /// in this prim's inventory. public int RemoveInventoryItem(UUID itemID) { - lock (m_items) + TaskInventoryItem item = GetInventoryItem(itemID); + if (item != null) { - if (m_items.ContainsKey(itemID)) + int type = m_items[itemID].InvType; + if (type == 10) // Script { - int type = m_items[itemID].InvType; - if (type == 10) // Script - { - m_part.RemoveScriptEvents(itemID); - m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); - } - m_items.Remove(itemID); - m_inventorySerial++; - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; + m_part.RemoveScriptEvents(itemID); + m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); + } + m_items.Remove(itemID); + m_inventorySerial++; + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - int scriptcount = 0; - lock (m_items) - { - foreach (TaskInventoryItem item in m_items.Values) - { - if (item.Type == 10) - { - scriptcount++; - } - } - } + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; - if (scriptcount <= 0) - { - m_part.RemFlag(PrimFlags.Scripted); - } + if (!ContainsScripts()) + m_part.RemFlag(PrimFlags.Scripted); - m_part.ScheduleFullUpdate(); + m_part.ScheduleFullUpdate(); - return type; - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", - itemID, m_part.Name, m_part.UUID, - m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); - } + return type; + + } + else + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", + itemID, m_part.Name, m_part.UUID, + m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); } return -1; @@ -763,52 +719,50 @@ namespace OpenSim.Region.Framework.Scenes // isn't available (such as drag from prim inventory to agent inventory) InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); - lock (m_items) + List items = GetInventoryItems(); + foreach (TaskInventoryItem item in items) { - foreach (TaskInventoryItem item in m_items.Values) - { - UUID ownerID = item.OwnerID; - uint everyoneMask = 0; - uint baseMask = item.BasePermissions; - uint ownerMask = item.CurrentPermissions; - uint groupMask = item.GroupPermissions; + UUID ownerID = item.OwnerID; + uint everyoneMask = 0; + uint baseMask = item.BasePermissions; + uint ownerMask = item.CurrentPermissions; + uint groupMask = item.GroupPermissions; - invString.AddItemStart(); - invString.AddNameValueLine("item_id", item.ItemID.ToString()); - invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); + invString.AddItemStart(); + invString.AddNameValueLine("item_id", item.ItemID.ToString()); + invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); - invString.AddPermissionsStart(); + invString.AddPermissionsStart(); - invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); - invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); - invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); - invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); - invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); + invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); + invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); + invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); + invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); + invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); - invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); - invString.AddNameValueLine("owner_id", ownerID.ToString()); + invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); + invString.AddNameValueLine("owner_id", ownerID.ToString()); - invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); + invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); - invString.AddNameValueLine("group_id", item.GroupID.ToString()); - invString.AddSectionEnd(); + invString.AddNameValueLine("group_id", item.GroupID.ToString()); + invString.AddSectionEnd(); - invString.AddNameValueLine("asset_id", item.AssetID.ToString()); - invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); - invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); - invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); + invString.AddNameValueLine("asset_id", item.AssetID.ToString()); + invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); + invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); + invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); - invString.AddSaleStart(); - invString.AddNameValueLine("sale_type", "not"); - invString.AddNameValueLine("sale_price", "0"); - invString.AddSectionEnd(); + invString.AddSaleStart(); + invString.AddNameValueLine("sale_type", "not"); + invString.AddNameValueLine("sale_price", "0"); + invString.AddSectionEnd(); - invString.AddNameValueLine("name", item.Name + "|"); - invString.AddNameValueLine("desc", item.Description + "|"); + invString.AddNameValueLine("name", item.Name + "|"); + invString.AddNameValueLine("desc", item.Description + "|"); - invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); - invString.AddSectionEnd(); - } + invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); + invString.AddSectionEnd(); } fileData = Utils.StringToBytes(invString.BuildString); @@ -830,12 +784,10 @@ namespace OpenSim.Region.Framework.Scenes { if (HasInventoryChanged) { - lock (Items) - { - datastore.StorePrimInventory(m_part.UUID, Items.Values); - } - HasInventoryChanged = false; + List items = GetInventoryItems(); + datastore.StorePrimInventory(m_part.UUID, items); + } } @@ -1001,6 +953,30 @@ namespace OpenSim.Region.Framework.Scenes return ret; } + + public List GetInventoryItems() + { + List ret = new List(); + + lock (m_items) + ret = new List(m_items.Values); + + return ret; + } + + public List GetInventoryScripts() + { + List ret = new List(); + + lock (m_items) + { + foreach (TaskInventoryItem item in m_items.Values) + if (item.InvType == (int)InventoryType.LSL) + ret.Add(item); + } + + return ret; + } public Dictionary GetScriptStates() { @@ -1010,24 +986,20 @@ namespace OpenSim.Region.Framework.Scenes if (engines == null) // No engine at all return ret; - lock (m_items) + List scripts = GetInventoryScripts(); + + foreach (TaskInventoryItem item in scripts) { - foreach (TaskInventoryItem item in m_items.Values) + foreach (IScriptModule e in engines) { - if (item.InvType == (int)InventoryType.LSL) + if (e != null) { - foreach (IScriptModule e in engines) + string n = e.GetXMLState(item.ItemID); + if (n != String.Empty) { - if (e != null) - { - string n = e.GetXMLState(item.ItemID); - if (n != String.Empty) - { - if (!ret.ContainsKey(item.ItemID)) - ret[item.ItemID] = n; - break; - } - } + if (!ret.ContainsKey(item.ItemID)) + ret[item.ItemID] = n; + break; } } } @@ -1042,25 +1014,22 @@ namespace OpenSim.Region.Framework.Scenes if (engines == null) return; - lock (m_items) + List scripts = GetInventoryScripts(); + + foreach (TaskInventoryItem item in scripts) { - foreach (TaskInventoryItem item in m_items.Values) + foreach (IScriptModule engine in engines) { - if (item.InvType == (int)InventoryType.LSL) + if (engine != null) { - foreach (IScriptModule engine in engines) - { - if (engine != null) - { - if (item.OwnerChanged) - engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); - item.OwnerChanged = false; - engine.ResumeScript(item.ItemID); - } - } + if (item.OwnerChanged) + engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); + item.OwnerChanged = false; + engine.ResumeScript(item.ItemID); } - } + } } } + } } -- cgit v1.1