diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 6c71c7184a..306238693a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -361,6 +361,7 @@ namespace OpenSim.Region.Framework.Scenes private SortedDictionary m_targets = new SortedDictionary(); private SortedDictionary m_rotTargets = new SortedDictionary(); + private Dictionary> m_targetsByScript = new Dictionary>(); public SortedDictionary AtTargets { @@ -4810,10 +4811,22 @@ namespace OpenSim.Region.Framework.Scenes waypoint.scriptID = scriptID; int handle = m_scene.AllocateIntId(); waypoint.handle = handle; + lock (m_rotTargets) { - if (m_rotTargets.Count >= 8) - m_rotTargets.Remove(m_rotTargets.ElementAt(0).Key); + if(m_targetsByScript.TryGetValue(scriptID, out List handles)) + { + if (handles.Count >= 8) + { + int todel = handles[0]; + handles.RemoveAt(0); + m_rotTargets.Remove(todel); + } + handles.Add(handle); + } + else + m_targetsByScript[scriptID] = new List(){handle}; + m_rotTargets.Add(handle, waypoint); } m_scene.AddGroupTarget(this); @@ -4824,26 +4837,45 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_targets) { - m_rotTargets.Remove(handle); - if (m_targets.Count == 0) + if(m_rotTargets.TryGetValue(handle, out scriptRotTarget waypoint)) + { + if(m_targetsByScript.TryGetValue(waypoint.scriptID, out Listhandles)) + { + handles.Remove(handle); + if(handles.Count() == 0) + m_targetsByScript.Remove(waypoint.scriptID); + } + m_rotTargets.Remove(handle); + } + if (m_targets.Count == 0 && m_rotTargets.Count == 0) m_scene.RemoveGroupTarget(this); } } public int registerTargetWaypoint(UUID scriptID, Vector3 target, float tolerance) { - int handle = m_scene.AllocateIntId(); - scriptPosTarget waypoint = new scriptPosTarget(); waypoint.targetPos = target; waypoint.tolerance = tolerance * tolerance; waypoint.scriptID = scriptID; + int handle = m_scene.AllocateIntId(); waypoint.handle = handle; lock (m_targets) { - if (m_targets.Count >= 8) - m_targets.Remove(m_targets.ElementAt(0).Key); + if (m_targetsByScript.TryGetValue(scriptID, out List handles)) + { + if (handles.Count >= 8) + { + int todel = handles[0]; + handles.RemoveAt(0); + m_rotTargets.Remove(todel); + } + handles.Add(handle); + } + else + m_targetsByScript[scriptID] = new List() { handle }; + m_targets.Add(handle, waypoint); } m_scene.AddGroupTarget(this); @@ -4854,43 +4886,39 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_targets) { - m_targets.Remove(handle); - if (m_targets.Count == 0) + if (m_targets.TryGetValue(handle, out scriptPosTarget waypoint)) + { + if (m_targetsByScript.TryGetValue(waypoint.scriptID, out List handles)) + { + handles.Remove(handle); + if (handles.Count() == 0) + m_targetsByScript.Remove(waypoint.scriptID); + } + m_targets.Remove(handle); + } + if (m_targets.Count == 0 && m_rotTargets.Count == 0) m_scene.RemoveGroupTarget(this); } } public void RemoveScriptTargets(UUID scriptID) { - List toremove = new List(); lock (m_targets) { - foreach (KeyValuePair kvp in m_targets) + if(m_targetsByScript.TryGetValue(scriptID, out List toremove)) { - if (kvp.Value.scriptID == scriptID) - toremove.Add(kvp.Key); + if (toremove.Count > 0) + { + for (int i = 0; i < toremove.Count; ++i) + { + m_targets.Remove(toremove[i]); + m_rotTargets.Remove(toremove[i]); + } + } + m_targetsByScript.Remove(scriptID); } - if (toremove.Count > 0) - { - for (int i = 0; i < toremove.Count; ++i) - m_targets.Remove(toremove[i]); - toremove.Clear(); - } - } - - lock (m_rotTargets) - { - foreach (KeyValuePair kvp in m_rotTargets) - { - if (kvp.Value.scriptID == scriptID) - toremove.Add(kvp.Key); - } - if (toremove.Count > 0) - { - for (int i = 0; i < toremove.Count; ++i) - m_targets.Remove(toremove[i]); - } - + if (m_targets.Count == 0 && m_rotTargets.Count == 0) + m_scene.RemoveGroupTarget(this); } } @@ -4900,7 +4928,7 @@ namespace OpenSim.Region.Framework.Scenes if (targetsCount > 0 && (m_scriptListens_atTarget || m_scriptListens_notAtTarget)) { List atTargets = new List(); - List notatTargets = new List(targetsCount); + HashSet notatTargets = new HashSet(); Vector3 pos = m_rootPart.GroupPosition; lock (m_targets) { @@ -4910,35 +4938,30 @@ namespace OpenSim.Region.Framework.Scenes { if (m_scriptListens_atTarget) atTargets.Add(target); + notatTargets.Remove(target.scriptID); } else { if (m_scriptListens_notAtTarget) - notatTargets.Add(target); + notatTargets.Add(target.scriptID); } } } - bool hasnot = notatTargets.Count > 0; - HashSet excludes = new HashSet(); if (atTargets.Count > 0) { for (int target = 0; target < atTargets.Count; ++target) { scriptPosTarget att = atTargets[target]; m_scene.EventManager.TriggerAtTargetEvent(att.scriptID, (uint)att.handle, att.targetPos, pos); - if(hasnot) - excludes.Add(att.scriptID); } } - if (hasnot) + if (notatTargets.Count > 0) { - for (int target = 0; target < notatTargets.Count; ++target) + foreach (UUID id in notatTargets) { - UUID id = notatTargets[target].scriptID; - if(!excludes.Contains(id)) - m_scene.EventManager.TriggerNotAtTargetEvent(id); + m_scene.EventManager.TriggerNotAtTargetEvent(id); } } } @@ -4947,7 +4970,7 @@ namespace OpenSim.Region.Framework.Scenes if (targetsCount > 0 && (m_scriptListens_atRotTarget || m_scriptListens_notAtRotTarget)) { List atRotTargets = new List(targetsCount); - List notatRotTargets = new List(targetsCount); + HashSet notatRotTargets = new HashSet(); Quaternion rot = m_rootPart.RotationOffset; lock (m_rotTargets) { @@ -4962,36 +4985,30 @@ namespace OpenSim.Region.Framework.Scenes { if (m_scriptListens_atRotTarget) atRotTargets.Add(target); + notatRotTargets.Remove(target.scriptID); } else { if (m_scriptListens_notAtRotTarget) - notatRotTargets.Add(target); + notatRotTargets.Add(target.scriptID); } } } - bool hasnot = notatRotTargets.Count > 0; - HashSet excludes = new HashSet(); - if (atRotTargets.Count > 0) { for (int target = 0; target < atRotTargets.Count; ++target) { scriptRotTarget att = atRotTargets[target]; m_scene.EventManager.TriggerAtRotTargetEvent(att.scriptID, (uint)att.handle, att.targetRot, rot); - if(hasnot) - excludes.Add(att.scriptID); } } if (notatRotTargets.Count > 0) { - for (int target = 0; target < notatRotTargets.Count; ++target) + foreach (UUID id in notatRotTargets) { - UUID id = notatRotTargets[target].scriptID; - if(!excludes.Contains(id)) - m_scene.EventManager.TriggerNotAtRotTargetEvent(id); + m_scene.EventManager.TriggerNotAtRotTargetEvent(id); } } }