aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneGraph.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs186
1 files changed, 79 insertions, 107 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index d259c42..b6e5995 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -699,116 +699,84 @@ namespace OpenSim.Region.Framework.Scenes
699 return null; 699 return null;
700 } 700 }
701 701
702 // The idea is to have a group of method that return a list of avatars meeting some requirement
703 // ie it could be all m_scenePresences within a certain range of the calling prim/avatar.
704 //
705 // GetAvatars returns a new list of all root agent presences in the scene
706 // GetScenePresences returns a new list of all presences in the scene or a filter may be passed.
707 // GetScenePresence returns the presence with matching UUID or the first presence matching the passed filter.
708 // ForEachScenePresence requests the Scene to run a delegate function against all presences.
709
710 /// <summary> 702 /// <summary>
711 /// Request a list of all avatars in this region (no child agents) 703 /// Request a copy of m_scenePresences in this World
712 /// This list is a new object, so it can be iterated over without locking. 704 /// There is no guarantee that presences will remain in the scene after the list is returned.
705 /// This list should remain private to SceneGraph. Callers wishing to iterate should instead
706 /// pass a delegate to ForEachScenePresence.
713 /// </summary> 707 /// </summary>
714 /// <returns></returns> 708 /// <returns></returns>
715 public List<ScenePresence> GetAvatars() 709 private List<ScenePresence> GetScenePresences()
716 { 710 {
717 return GetScenePresences(delegate(ScenePresence scenePresence) 711 lock (m_scenePresences)
718 { 712 return new List<ScenePresence>(m_scenePresenceArray);
719 return !scenePresence.IsChildAgent;
720 });
721 } 713 }
722 714
723 /// <summary> 715 /// <summary>
724 /// Request a list of m_scenePresences in this World 716 /// Request a scene presence by UUID. Fast, indexed lookup.
725 /// Returns a copy so it can be iterated without a lock.
726 /// There is no guarantee that presences will remain in the scene after the list is returned.
727 /// </summary> 717 /// </summary>
728 /// <returns></returns> 718 /// <param name="agentID"></param>
729 protected internal List<ScenePresence> GetScenePresences() 719 /// <returns>null if the presence was not found</returns>
720 protected internal ScenePresence GetScenePresence(UUID agentID)
730 { 721 {
731 List<ScenePresence> result; 722 ScenePresence sp;
732 lock (m_scenePresences) 723 lock (m_scenePresences)
733 { 724 {
734 result = new List<ScenePresence>(m_scenePresenceArray.Length); 725 m_scenePresences.TryGetValue(agentID, out sp);
735 result.AddRange(m_scenePresenceArray);
736 } 726 }
737 return result; 727 return sp;
738 } 728 }
739 729
740 /// <summary> 730 /// <summary>
741 /// Request a filtered list of m_scenePresences in this World 731 /// Request the scene presence by name.
742 /// Returns a copy so it can be iterated without a lock.
743 /// There is no guarantee that presences will remain in the scene after the list is returned.
744 /// </summary> 732 /// </summary>
745 /// <returns></returns> 733 /// <param name="firstName"></param>
746 protected internal List<ScenePresence> GetScenePresences(FilterAvatarList filter) 734 /// <param name="lastName"></param>
735 /// <returns>null if the presence was not found</returns>
736 protected internal ScenePresence GetScenePresence(string firstName, string lastName)
747 { 737 {
748 List<ScenePresence> result = new List<ScenePresence>(); 738 foreach (ScenePresence presence in GetScenePresences())
749 // Check each ScenePresence against the filter
750 ForEachScenePresence(delegate(ScenePresence presence)
751 { 739 {
752 if (filter(presence)) 740 if (presence.Firstname == firstName && presence.Lastname == lastName)
753 result.Add(presence); 741 return presence;
754 }); 742 }
755 return result; 743 return null;
756 } 744 }
757 745
758 /// <summary> 746 /// <summary>
759 /// Request the ScenePresence in this region matching filter. 747 /// Request the scene presence by localID.
760 /// Only the first match is returned.
761 ///
762 /// </summary> 748 /// </summary>
763 /// <param name="filter"></param> 749 /// <param name="localID"></param>
764 /// <returns></returns> 750 /// <returns>null if the presence was not found</returns>
765 protected internal ScenePresence GetScenePresence(FilterAvatarList filter) 751 protected internal ScenePresence GetScenePresence(uint localID)
766 { 752 {
767 ScenePresence result = null; 753 foreach (ScenePresence presence in GetScenePresences())
768 // Get all of the ScenePresences 754 if (presence.LocalId == localID)
769 List<ScenePresence> presences = GetScenePresences(); 755 return presence;
770 foreach (ScenePresence presence in presences) 756 return null;
771 {
772 if (filter(presence))
773 {
774 result = presence;
775 break;
776 }
777 }
778 return result;
779 } 757 }
780 758
781 protected internal ScenePresence GetScenePresence(string firstName, string lastName) 759 protected internal bool TryGetAvatar(UUID agentID, out ScenePresence avatar)
782 { 760 {
783 return GetScenePresence(delegate(ScenePresence presence) 761 lock (m_scenePresences)
784 { 762 {
785 return(presence.Firstname == firstName && presence.Lastname == lastName); 763 m_scenePresences.TryGetValue(agentID, out avatar);
786 }); 764 }
787 } 765 return (avatar != null);
788
789 /// <summary>
790 /// Request a scene presence by UUID
791 /// </summary>
792 /// <param name="agentID"></param>
793 /// <returns>null if the agent was not found</returns>
794 protected internal ScenePresence GetScenePresence(UUID agentID)
795 {
796 ScenePresence sp;
797 TryGetAvatar(agentID, out sp);
798 return sp;
799 } 766 }
800 767
801 /// <summary> 768 protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar)
802 /// Request the ScenePresence in this region by localID.
803 /// </summary>
804 /// <param name="localID"></param>
805 /// <returns></returns>
806 protected internal ScenePresence GetScenePresence(uint localID)
807 { 769 {
808 return GetScenePresence(delegate(ScenePresence presence) 770 avatar = null;
771 foreach (ScenePresence presence in GetScenePresences())
809 { 772 {
810 return (presence.LocalId == localID); 773 if (String.Compare(name, presence.ControllingClient.Name, true) == 0)
811 }); 774 {
775 avatar = presence;
776 break;
777 }
778 }
779 return (avatar != null);
812 } 780 }
813 781
814 /// <summary> 782 /// <summary>
@@ -962,24 +930,6 @@ namespace OpenSim.Region.Framework.Scenes
962 return group.GetChildPart(fullID); 930 return group.GetChildPart(fullID);
963 } 931 }
964 932
965 protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
966 {
967 lock (m_scenePresences)
968 {
969 m_scenePresences.TryGetValue(avatarId, out avatar);
970 }
971 return (avatar != null);
972 }
973
974 protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
975 {
976 avatar = GetScenePresence(delegate(ScenePresence presence)
977 {
978 return (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0);
979 });
980 return (avatar != null);
981 }
982
983 /// <summary> 933 /// <summary>
984 /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over 934 /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over
985 /// it 935 /// it
@@ -1042,6 +992,10 @@ namespace OpenSim.Region.Framework.Scenes
1042 return UUID.Zero; 992 return UUID.Zero;
1043 } 993 }
1044 994
995 /// <summary>
996 /// Performs action on all scene object groups.
997 /// </summary>
998 /// <param name="action"></param>
1045 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 999 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1046 { 1000 {
1047 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); 1001 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
@@ -1061,23 +1015,41 @@ namespace OpenSim.Region.Framework.Scenes
1061 1015
1062 1016
1063 /// <summary> 1017 /// <summary>
1064 /// Performs action on all scene presences. 1018 /// Performs action on all scene presences. This can ultimately run the actions in parallel but
1019 /// any delegates passed in will need to implement their own locking on data they reference and
1020 /// modify outside of the scope of the delegate.
1065 /// </summary> 1021 /// </summary>
1066 /// <param name="action"></param> 1022 /// <param name="action"></param>
1067 public void ForEachScenePresence(Action<ScenePresence> action) 1023 public void ForEachScenePresence(Action<ScenePresence> action)
1068 { 1024 {
1069 List<ScenePresence> presences = GetScenePresences(); 1025 // Once all callers have their delegates configured for parallelism, we can unleash this
1070 try 1026 /*
1027 Action<ScenePresence> protectedAction = new Action<ScenePresence>(delegate(ScenePresence sp)
1028 {
1029 try
1030 {
1031 action(sp);
1032 }
1033 catch (Exception e)
1034 {
1035 m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
1036 m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
1037 }
1038 });
1039 Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction);
1040 */
1041 // For now, perform actiona serially
1042 foreach (ScenePresence sp in GetScenePresences())
1071 { 1043 {
1072 foreach(ScenePresence presence in presences) 1044 try
1073 { 1045 {
1074 action(presence); 1046 action(sp);
1047 }
1048 catch (Exception e)
1049 {
1050 m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
1051 m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
1075 } 1052 }
1076 }
1077 catch (Exception e)
1078 {
1079 m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
1080 m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
1081 } 1053 }
1082 } 1054 }
1083 1055