diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 193 |
1 files changed, 130 insertions, 63 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index db70d6a..19298d2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -165,9 +165,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
165 | 165 | ||
166 | protected internal void UpdatePresences() | 166 | protected internal void UpdatePresences() |
167 | { | 167 | { |
168 | ScenePresence[] updateScenePresences = GetScenePresences(); | 168 | ForEachScenePresence(delegate(ScenePresence presence) |
169 | for (int i = 0; i < updateScenePresences.Length; i++) | 169 | { |
170 | updateScenePresences[i].Update(); | 170 | presence.Update(); |
171 | }); | ||
171 | } | 172 | } |
172 | 173 | ||
173 | protected internal float UpdatePhysics(double elapsed) | 174 | protected internal float UpdatePhysics(double elapsed) |
@@ -196,9 +197,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
196 | 197 | ||
197 | protected internal void UpdateScenePresenceMovement() | 198 | protected internal void UpdateScenePresenceMovement() |
198 | { | 199 | { |
199 | ScenePresence[] moveEntities = GetScenePresences(); | 200 | ForEachScenePresence(delegate(ScenePresence presence) |
200 | for (int i = 0; i < moveEntities.Length; i++) | 201 | { |
201 | moveEntities[i].UpdateMovement(); | 202 | presence.UpdateMovement(); |
203 | }); | ||
202 | } | 204 | } |
203 | 205 | ||
204 | #endregion | 206 | #endregion |
@@ -640,18 +642,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
640 | 642 | ||
641 | public void RecalculateStats() | 643 | public void RecalculateStats() |
642 | { | 644 | { |
643 | ScenePresence[] presences = GetScenePresences(); | ||
644 | int rootcount = 0; | 645 | int rootcount = 0; |
645 | int childcount = 0; | 646 | int childcount = 0; |
646 | 647 | ||
647 | for (int i = 0; i < presences.Length; i++) | 648 | ForEachScenePresence(delegate(ScenePresence presence) |
648 | { | 649 | { |
649 | ScenePresence user = presences[i]; | 650 | if (presence.IsChildAgent) |
650 | if (user.IsChildAgent) | ||
651 | ++childcount; | 651 | ++childcount; |
652 | else | 652 | else |
653 | ++rootcount; | 653 | ++rootcount; |
654 | } | 654 | }); |
655 | 655 | ||
656 | m_numRootAgents = rootcount; | 656 | m_numRootAgents = rootcount; |
657 | m_numChildAgents = childcount; | 657 | m_numChildAgents = childcount; |
@@ -698,25 +698,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
698 | #endregion | 698 | #endregion |
699 | 699 | ||
700 | #region Get Methods | 700 | #region Get Methods |
701 | |||
702 | /// <summary> | ||
703 | /// Request a List of all scene presences in this scene. This is a new list, so no | ||
704 | /// locking is required to iterate over it. | ||
705 | /// </summary> | ||
706 | /// <returns></returns> | ||
707 | protected internal ScenePresence[] GetScenePresences() | ||
708 | { | ||
709 | return m_scenePresenceArray; | ||
710 | } | ||
711 | |||
712 | protected internal List<ScenePresence> GetAvatars() | ||
713 | { | ||
714 | List<ScenePresence> result = | ||
715 | GetScenePresences(delegate(ScenePresence scenePresence) { return !scenePresence.IsChildAgent; }); | ||
716 | |||
717 | return result; | ||
718 | } | ||
719 | |||
720 | /// <summary> | 701 | /// <summary> |
721 | /// Get the controlling client for the given avatar, if there is one. | 702 | /// Get the controlling client for the given avatar, if there is one. |
722 | /// | 703 | /// |
@@ -742,45 +723,119 @@ namespace OpenSim.Region.Framework.Scenes | |||
742 | return null; | 723 | return null; |
743 | } | 724 | } |
744 | 725 | ||
726 | // The idea is to have a group of method that return a list of avatars meeting some requirement | ||
727 | // ie it could be all m_scenePresences within a certain range of the calling prim/avatar. | ||
728 | // | ||
729 | // GetAvatars returns a new list of all root agent presences in the scene | ||
730 | // GetScenePresences returns a new list of all presences in the scene or a filter may be passed. | ||
731 | // GetScenePresence returns the presence with matching UUID or the first presence matching the passed filter. | ||
732 | // ForEachScenePresence requests the Scene to run a delegate function against all presences. | ||
733 | |||
734 | /// <summary> | ||
735 | /// Request a list of all avatars in this region (no child agents) | ||
736 | /// This list is a new object, so it can be iterated over without locking. | ||
737 | /// </summary> | ||
738 | /// <returns></returns> | ||
739 | public List<ScenePresence> GetAvatars() | ||
740 | { | ||
741 | return GetScenePresences(delegate(ScenePresence scenePresence) | ||
742 | { | ||
743 | return !scenePresence.IsChildAgent; | ||
744 | }); | ||
745 | } | ||
746 | |||
747 | /// <summary> | ||
748 | /// Request a list of m_scenePresences in this World | ||
749 | /// Returns a copy so it can be iterated without a lock. | ||
750 | /// There is no guarantee that presences will remain in the scene after the list is returned. | ||
751 | /// </summary> | ||
752 | /// <returns></returns> | ||
753 | protected internal List<ScenePresence> GetScenePresences() | ||
754 | { | ||
755 | List<ScenePresence> result; | ||
756 | lock (m_scenePresences) | ||
757 | { | ||
758 | result = new List<ScenePresence>(m_scenePresenceArray.Length); | ||
759 | result.AddRange(m_scenePresenceArray); | ||
760 | } | ||
761 | return result; | ||
762 | } | ||
763 | |||
745 | /// <summary> | 764 | /// <summary> |
746 | /// Request a filtered list of m_scenePresences in this World | 765 | /// Request a filtered list of m_scenePresences in this World |
766 | /// Returns a copy so it can be iterated without a lock. | ||
767 | /// There is no guarantee that presences will remain in the scene after the list is returned. | ||
747 | /// </summary> | 768 | /// </summary> |
748 | /// <returns></returns> | 769 | /// <returns></returns> |
749 | protected internal List<ScenePresence> GetScenePresences(FilterAvatarList filter) | 770 | protected internal List<ScenePresence> GetScenePresences(FilterAvatarList filter) |
750 | { | 771 | { |
751 | // No locking of scene presences here since we're passing back a list... | ||
752 | |||
753 | List<ScenePresence> result = new List<ScenePresence>(); | 772 | List<ScenePresence> result = new List<ScenePresence>(); |
754 | ScenePresence[] scenePresences = GetScenePresences(); | 773 | // Check each ScenePresence against the filter |
774 | ForEachScenePresence(delegate(ScenePresence presence) | ||
775 | { | ||
776 | if (filter(presence)) | ||
777 | result.Add(presence); | ||
778 | }); | ||
779 | return result; | ||
780 | } | ||
755 | 781 | ||
756 | for (int i = 0; i < scenePresences.Length; i++) | 782 | /// <summary> |
783 | /// Request the ScenePresence in this region matching filter. | ||
784 | /// Only the first match is returned. | ||
785 | /// | ||
786 | /// </summary> | ||
787 | /// <param name="filter"></param> | ||
788 | /// <returns></returns> | ||
789 | protected internal ScenePresence GetScenePresence(FilterAvatarList filter) | ||
790 | { | ||
791 | ScenePresence result = null; | ||
792 | // Get all of the ScenePresences | ||
793 | List<ScenePresence> presences = GetScenePresences(); | ||
794 | foreach (ScenePresence presence in presences) | ||
757 | { | 795 | { |
758 | ScenePresence avatar = scenePresences[i]; | 796 | if (filter(presence)) |
759 | if (filter(avatar)) | 797 | { |
760 | result.Add(avatar); | 798 | result = presence; |
799 | break; | ||
800 | } | ||
761 | } | 801 | } |
762 | |||
763 | return result; | 802 | return result; |
764 | } | 803 | } |
765 | 804 | ||
805 | protected internal ScenePresence GetScenePresence(string firstName, string lastName) | ||
806 | { | ||
807 | return GetScenePresence(delegate(ScenePresence presence) | ||
808 | { | ||
809 | return(presence.Firstname == firstName && presence.Lastname == lastName); | ||
810 | }); | ||
811 | } | ||
812 | |||
766 | /// <summary> | 813 | /// <summary> |
767 | /// Request a scene presence by UUID | 814 | /// Request a scene presence by UUID |
768 | /// </summary> | 815 | /// </summary> |
769 | /// <param name="avatarID"></param> | 816 | /// <param name="agentID"></param> |
770 | /// <returns>null if the agent was not found</returns> | 817 | /// <returns>null if the agent was not found</returns> |
771 | protected internal ScenePresence GetScenePresence(UUID agentID) | 818 | protected internal ScenePresence GetScenePresence(UUID agentID) |
772 | { | 819 | { |
773 | ScenePresence sp; | 820 | ScenePresence sp; |
774 | 821 | TryGetAvatar(agentID, out sp); | |
775 | lock (m_scenePresences) | ||
776 | { | ||
777 | m_scenePresences.TryGetValue(agentID, out sp); | ||
778 | } | ||
779 | |||
780 | return sp; | 822 | return sp; |
781 | } | 823 | } |
782 | 824 | ||
783 | /// <summary> | 825 | /// <summary> |
826 | /// Request the ScenePresence in this region by localID. | ||
827 | /// </summary> | ||
828 | /// <param name="localID"></param> | ||
829 | /// <returns></returns> | ||
830 | protected internal ScenePresence GetScenePresence(uint localID) | ||
831 | { | ||
832 | return GetScenePresence(delegate(ScenePresence presence) | ||
833 | { | ||
834 | return (presence.LocalId == localID); | ||
835 | }); | ||
836 | } | ||
837 | |||
838 | /// <summary> | ||
784 | /// Get a scene object group that contains the prim with the given local id | 839 | /// Get a scene object group that contains the prim with the given local id |
785 | /// </summary> | 840 | /// </summary> |
786 | /// <param name="localID"></param> | 841 | /// <param name="localID"></param> |
@@ -934,29 +989,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
934 | protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) | 989 | protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) |
935 | { | 990 | { |
936 | lock (m_scenePresences) | 991 | lock (m_scenePresences) |
937 | return m_scenePresences.TryGetValue(avatarId, out avatar); | 992 | { |
993 | m_scenePresences.TryGetValue(avatarId, out avatar); | ||
994 | } | ||
995 | return (avatar != null); | ||
938 | } | 996 | } |
939 | 997 | ||
940 | protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) | 998 | protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) |
941 | { | 999 | { |
942 | ScenePresence[] presences = GetScenePresences(); | 1000 | avatar = GetScenePresence(delegate(ScenePresence presence) |
943 | |||
944 | for (int i = 0; i < presences.Length; i++) | ||
945 | { | 1001 | { |
946 | ScenePresence presence = presences[i]; | 1002 | return (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0); |
947 | 1003 | }); | |
948 | if (!presence.IsChildAgent) | 1004 | return (avatar != null); |
949 | { | ||
950 | if (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0) | ||
951 | { | ||
952 | avatar = presence; | ||
953 | return true; | ||
954 | } | ||
955 | } | ||
956 | } | ||
957 | |||
958 | avatar = null; | ||
959 | return false; | ||
960 | } | 1005 | } |
961 | 1006 | ||
962 | /// <summary> | 1007 | /// <summary> |
@@ -1037,6 +1082,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
1037 | } | 1082 | } |
1038 | } | 1083 | } |
1039 | } | 1084 | } |
1085 | |||
1086 | |||
1087 | /// <summary> | ||
1088 | /// Performs action on all scene presences. | ||
1089 | /// </summary> | ||
1090 | /// <param name="action"></param> | ||
1091 | public void ForEachScenePresence(Action<ScenePresence> action) | ||
1092 | { | ||
1093 | List<ScenePresence> presences = GetScenePresences(); | ||
1094 | try | ||
1095 | { | ||
1096 | foreach(ScenePresence presence in presences) | ||
1097 | { | ||
1098 | action(presence); | ||
1099 | } | ||
1100 | } | ||
1101 | catch (Exception e) | ||
1102 | { | ||
1103 | m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString()); | ||
1104 | m_log.Info("[BUG] Stack Trace: " + e.StackTrace); | ||
1105 | } | ||
1106 | } | ||
1040 | 1107 | ||
1041 | #endregion | 1108 | #endregion |
1042 | 1109 | ||