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.cs193
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