diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 186 |
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 | ||