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.cs455
1 files changed, 164 insertions, 291 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 090f379..c16ba12 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -35,6 +35,7 @@ using log4net;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.Framework.Scenes.Types; 36using OpenSim.Region.Framework.Scenes.Types;
37using OpenSim.Region.Physics.Manager; 37using OpenSim.Region.Physics.Manager;
38using OpenSim.Region.Framework.Interfaces;
38 39
39namespace OpenSim.Region.Framework.Scenes 40namespace OpenSim.Region.Framework.Scenes
40{ 41{
@@ -69,6 +70,9 @@ namespace OpenSim.Region.Framework.Scenes
69 70
70 protected Dictionary<UUID, ScenePresence> m_scenePresences = new Dictionary<UUID, ScenePresence>(); 71 protected Dictionary<UUID, ScenePresence> m_scenePresences = new Dictionary<UUID, ScenePresence>();
71 protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0]; 72 protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0];
73 protected List<ScenePresence> m_scenePresenceList = new List<ScenePresence>();
74
75 protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim();
72 76
73 // SceneObjects is not currently populated or used. 77 // SceneObjects is not currently populated or used.
74 //public Dictionary<UUID, SceneObjectGroup> SceneObjects; 78 //public Dictionary<UUID, SceneObjectGroup> SceneObjects;
@@ -131,10 +135,16 @@ namespace OpenSim.Region.Framework.Scenes
131 135
132 protected internal void Close() 136 protected internal void Close()
133 { 137 {
134 lock (m_scenePresences) 138 m_scenePresencesLock.EnterWriteLock();
139 try
135 { 140 {
136 m_scenePresences.Clear(); 141 m_scenePresences.Clear();
137 m_scenePresenceArray = new ScenePresence[0]; 142 m_scenePresenceArray = new ScenePresence[0];
143 m_scenePresenceList = new List<ScenePresence>();
144 }
145 finally
146 {
147 m_scenePresencesLock.ExitWriteLock();
138 } 148 }
139 149
140 lock (m_dictionary_lock) 150 lock (m_dictionary_lock)
@@ -164,9 +174,10 @@ namespace OpenSim.Region.Framework.Scenes
164 174
165 protected internal void UpdatePresences() 175 protected internal void UpdatePresences()
166 { 176 {
167 ScenePresence[] updateScenePresences = GetScenePresences(); 177 ForEachScenePresence(delegate(ScenePresence presence)
168 for (int i = 0; i < updateScenePresences.Length; i++) 178 {
169 updateScenePresences[i].Update(); 179 presence.Update();
180 });
170 } 181 }
171 182
172 protected internal float UpdatePhysics(double elapsed) 183 protected internal float UpdatePhysics(double elapsed)
@@ -195,9 +206,10 @@ namespace OpenSim.Region.Framework.Scenes
195 206
196 protected internal void UpdateScenePresenceMovement() 207 protected internal void UpdateScenePresenceMovement()
197 { 208 {
198 ScenePresence[] moveEntities = GetScenePresences(); 209 ForEachScenePresence(delegate(ScenePresence presence)
199 for (int i = 0; i < moveEntities.Length; i++) 210 {
200 moveEntities[i].UpdateMovement(); 211 presence.UpdateMovement();
212 });
201 } 213 }
202 214
203 #endregion 215 #endregion
@@ -464,9 +476,7 @@ namespace OpenSim.Region.Framework.Scenes
464 { 476 {
465 SceneObjectGroup group = GetGroupByPrim(objectLocalID); 477 SceneObjectGroup group = GetGroupByPrim(objectLocalID);
466 if (group != null) 478 if (group != null)
467 { 479 m_parentScene.AttachmentsModule.DetachSingleAttachmentToGround(group.UUID, remoteClient);
468 m_parentScene.DetachSingleAttachmentToGround(group.UUID, remoteClient);
469 }
470 } 480 }
471 481
472 protected internal void DetachObject(uint objectLocalID, IClientAPI remoteClient) 482 protected internal void DetachObject(uint objectLocalID, IClientAPI remoteClient)
@@ -475,7 +485,7 @@ namespace OpenSim.Region.Framework.Scenes
475 if (group != null) 485 if (group != null)
476 { 486 {
477 //group.DetachToGround(); 487 //group.DetachToGround();
478 m_parentScene.DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient); 488 m_parentScene.AttachmentsModule.ShowDetachInUserInventory(group.GetFromItemID(), remoteClient);
479 } 489 }
480 } 490 }
481 491
@@ -509,212 +519,6 @@ namespace OpenSim.Region.Framework.Scenes
509 } 519 }
510 } 520 }
511 521
512 /// <summary>
513 /// Event Handling routine for Attach Object
514 /// </summary>
515 /// <param name="remoteClient"></param>
516 /// <param name="objectLocalID"></param>
517 /// <param name="AttachmentPt"></param>
518 /// <param name="rot"></param>
519 protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent)
520 {
521 // If we can't take it, we can't attach it!
522 SceneObjectPart part = m_parentScene.GetSceneObjectPart(objectLocalID);
523 if (part == null)
524 return;
525
526 if (!m_parentScene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId))
527 return;
528
529 // Calls attach with a Zero position
530 if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false))
531 {
532 m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
533
534 // Save avatar attachment information
535 ScenePresence presence;
536 if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence))
537 {
538 m_log.Info(
539 "[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
540 + ", AttachmentPoint: " + AttachmentPt);
541
542 m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
543 }
544 }
545 }
546
547 /// <summary>
548 /// Rez an attachment
549 /// </summary>
550 /// <param name="remoteClient"></param>
551 /// <param name="itemID"></param>
552 /// <param name="AttachmentPt"></param>
553 /// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
554 public SceneObjectGroup RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
555 {
556 SceneObjectGroup objatt = m_parentScene.RezObject(remoteClient,
557 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
558 false, false, remoteClient.AgentId, true);
559
560// m_log.DebugFormat(
561// "[SCENE GRAPH]: Retrieved single object {0} for attachment to {1} on point {2}",
562// objatt.Name, remoteClient.Name, AttachmentPt);
563
564 if (objatt != null)
565 {
566 bool tainted = false;
567 if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint())
568 tainted = true;
569
570 AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false);
571 //objatt.ScheduleGroupForFullUpdate();
572
573 if (tainted)
574 objatt.HasGroupChanged = true;
575
576 // Fire after attach, so we don't get messy perms dialogs
577 // 3 == AttachedRez
578 objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3);
579
580 // Do this last so that event listeners have access to all the effects of the attachment
581 m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId);
582 }
583 else
584 {
585 m_log.WarnFormat(
586 "[SCENE GRAPH]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
587 itemID, remoteClient.Name, AttachmentPt);
588 }
589
590 return objatt;
591 }
592
593 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
594 // To LocalId or UUID, *THAT* is the question. How now Brown UUID??
595 public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
596 {
597 if (itemID == UUID.Zero) // If this happened, someone made a mistake....
598 return;
599
600 // We can NOT use the dictionries here, as we are looking
601 // for an entity by the fromAssetID, which is NOT the prim UUID
602 //
603 List<EntityBase> detachEntities = GetEntities();
604 SceneObjectGroup group;
605
606 foreach (EntityBase entity in detachEntities)
607 {
608 if (entity is SceneObjectGroup)
609 {
610 group = (SceneObjectGroup)entity;
611 if (group.GetFromItemID() == itemID)
612 {
613 m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero);
614 bool hasScripts = false;
615 foreach (SceneObjectPart part in group.Children.Values)
616 {
617 if (part.Inventory.ContainsScripts())
618 {
619 hasScripts = true;
620 break;
621 }
622 }
623
624 if (hasScripts) // Allow the object to execute the attach(NULL_KEY) event
625 System.Threading.Thread.Sleep(100);
626 group.DetachToInventoryPrep();
627 m_log.Debug("[DETACH]: Saving attachpoint: " +
628 ((uint)group.GetAttachmentPoint()).ToString());
629 m_parentScene.UpdateKnownItem(remoteClient, group,
630 group.GetFromItemID(), group.OwnerID);
631 m_parentScene.DeleteSceneObject(group, false);
632 return;
633 }
634 }
635 }
636 }
637
638 /// <summary>
639 /// Attach a scene object to an avatar.
640 /// </summary>
641 /// <param name="remoteClient"></param>
642 /// <param name="objectLocalID"></param>
643 /// <param name="AttachmentPt"></param>
644 /// <param name="rot"></param>
645 /// <param name="attachPos"></param>
646 /// <param name="silent"></param>
647 /// <returns>true if the attachment was successful, false otherwise</returns>
648 protected internal bool AttachObject(
649 IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent)
650 {
651 SceneObjectGroup group = GetGroupByPrim(objectLocalID);
652 if (group != null)
653 {
654 if (m_parentScene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId))
655 {
656 // If the attachment point isn't the same as the one previously used
657 // set it's offset position = 0 so that it appears on the attachment point
658 // and not in a weird location somewhere unknown.
659 if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint())
660 {
661 attachPos = Vector3.Zero;
662 }
663
664 // AttachmentPt 0 means the client chose to 'wear' the attachment.
665 if (AttachmentPt == 0)
666 {
667 // Check object for stored attachment point
668 AttachmentPt = (uint)group.GetAttachmentPoint();
669 }
670
671 // if we still didn't find a suitable attachment point.......
672 if (AttachmentPt == 0)
673 {
674 // Stick it on left hand with Zero Offset from the attachment point.
675 AttachmentPt = (uint)AttachmentPoint.LeftHand;
676 attachPos = Vector3.Zero;
677 }
678
679 group.SetAttachmentPoint((byte)AttachmentPt);
680 group.AbsolutePosition = attachPos;
681
682 // Saves and gets itemID
683 UUID itemId;
684
685 if (group.GetFromItemID() == UUID.Zero)
686 {
687 m_parentScene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId);
688 }
689 else
690 {
691 itemId = group.GetFromItemID();
692 }
693
694 m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group);
695
696 group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent);
697 // In case it is later dropped again, don't let
698 // it get cleaned up
699 //
700 group.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
701 group.HasGroupChanged = false;
702 }
703 else
704 {
705 remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false);
706 return false;
707 }
708 }
709 else
710 {
711 m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID);
712 return false;
713 }
714
715 return true;
716 }
717
718 protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) 522 protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance)
719 { 523 {
720 ScenePresence newAvatar = null; 524 ScenePresence newAvatar = null;
@@ -747,7 +551,8 @@ namespace OpenSim.Region.Framework.Scenes
747 551
748 Entities[presence.UUID] = presence; 552 Entities[presence.UUID] = presence;
749 553
750 lock (m_scenePresences) 554 m_scenePresencesLock.EnterWriteLock();
555 try
751 { 556 {
752 if (!m_scenePresences.ContainsKey(presence.UUID)) 557 if (!m_scenePresences.ContainsKey(presence.UUID))
753 { 558 {
@@ -759,11 +564,12 @@ namespace OpenSim.Region.Framework.Scenes
759 Array.Copy(m_scenePresenceArray, newArray, oldLength); 564 Array.Copy(m_scenePresenceArray, newArray, oldLength);
760 newArray[oldLength] = presence; 565 newArray[oldLength] = presence;
761 m_scenePresenceArray = newArray; 566 m_scenePresenceArray = newArray;
567 m_scenePresenceList = new List<ScenePresence>(m_scenePresenceArray);
762 } 568 }
763 else 569 else
764 { 570 {
765 m_scenePresences[presence.UUID] = presence; 571 m_scenePresences[presence.UUID] = presence;
766 572
767 // Do a linear search through the array of ScenePresence references 573 // Do a linear search through the array of ScenePresence references
768 // and update the modified entry 574 // and update the modified entry
769 for (int i = 0; i < m_scenePresenceArray.Length; i++) 575 for (int i = 0; i < m_scenePresenceArray.Length; i++)
@@ -774,8 +580,13 @@ namespace OpenSim.Region.Framework.Scenes
774 break; 580 break;
775 } 581 }
776 } 582 }
583 m_scenePresenceList = new List<ScenePresence>(m_scenePresenceArray);
777 } 584 }
778 } 585 }
586 finally
587 {
588 m_scenePresencesLock.ExitWriteLock();
589 }
779 } 590 }
780 591
781 /// <summary> 592 /// <summary>
@@ -790,7 +601,8 @@ namespace OpenSim.Region.Framework.Scenes
790 agentID); 601 agentID);
791 } 602 }
792 603
793 lock (m_scenePresences) 604 m_scenePresencesLock.EnterWriteLock();
605 try
794 { 606 {
795 if (m_scenePresences.Remove(agentID)) 607 if (m_scenePresences.Remove(agentID))
796 { 608 {
@@ -809,12 +621,17 @@ namespace OpenSim.Region.Framework.Scenes
809 } 621 }
810 } 622 }
811 m_scenePresenceArray = newArray; 623 m_scenePresenceArray = newArray;
624 m_scenePresenceList = new List<ScenePresence>(m_scenePresenceArray);
812 } 625 }
813 else 626 else
814 { 627 {
815 m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 628 m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
816 } 629 }
817 } 630 }
631 finally
632 {
633 m_scenePresencesLock.ExitWriteLock();
634 }
818 } 635 }
819 636
820 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 637 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -845,18 +662,16 @@ namespace OpenSim.Region.Framework.Scenes
845 662
846 public void RecalculateStats() 663 public void RecalculateStats()
847 { 664 {
848 ScenePresence[] presences = GetScenePresences();
849 int rootcount = 0; 665 int rootcount = 0;
850 int childcount = 0; 666 int childcount = 0;
851 667
852 for (int i = 0; i < presences.Length; i++) 668 ForEachScenePresence(delegate(ScenePresence presence)
853 { 669 {
854 ScenePresence user = presences[i]; 670 if (presence.IsChildAgent)
855 if (user.IsChildAgent)
856 ++childcount; 671 ++childcount;
857 else 672 else
858 ++rootcount; 673 ++rootcount;
859 } 674 });
860 675
861 m_numRootAgents = rootcount; 676 m_numRootAgents = rootcount;
862 m_numChildAgents = childcount; 677 m_numChildAgents = childcount;
@@ -903,25 +718,6 @@ namespace OpenSim.Region.Framework.Scenes
903 #endregion 718 #endregion
904 719
905 #region Get Methods 720 #region Get Methods
906
907 /// <summary>
908 /// Request a List of all scene presences in this scene. This is a new list, so no
909 /// locking is required to iterate over it.
910 /// </summary>
911 /// <returns></returns>
912 protected internal ScenePresence[] GetScenePresences()
913 {
914 return m_scenePresenceArray;
915 }
916
917 protected internal List<ScenePresence> GetAvatars()
918 {
919 List<ScenePresence> result =
920 GetScenePresences(delegate(ScenePresence scenePresence) { return !scenePresence.IsChildAgent; });
921
922 return result;
923 }
924
925 /// <summary> 721 /// <summary>
926 /// Get the controlling client for the given avatar, if there is one. 722 /// Get the controlling client for the given avatar, if there is one.
927 /// 723 ///
@@ -948,44 +744,103 @@ namespace OpenSim.Region.Framework.Scenes
948 } 744 }
949 745
950 /// <summary> 746 /// <summary>
951 /// Request a filtered list of m_scenePresences in this World 747 /// Request a copy of m_scenePresences in this World
748 /// There is no guarantee that presences will remain in the scene after the list is returned.
749 /// This list should remain private to SceneGraph. Callers wishing to iterate should instead
750 /// pass a delegate to ForEachScenePresence.
952 /// </summary> 751 /// </summary>
953 /// <returns></returns> 752 /// <returns></returns>
954 protected internal List<ScenePresence> GetScenePresences(FilterAvatarList filter) 753 private List<ScenePresence> GetScenePresences()
955 { 754 {
956 // No locking of scene presences here since we're passing back a list... 755 m_scenePresencesLock.EnterReadLock();
957 756 try
958 List<ScenePresence> result = new List<ScenePresence>();
959 ScenePresence[] scenePresences = GetScenePresences();
960
961 for (int i = 0; i < scenePresences.Length; i++)
962 { 757 {
963 ScenePresence avatar = scenePresences[i]; 758 return m_scenePresenceList;
964 if (filter(avatar)) 759 }
965 result.Add(avatar); 760 finally
761 {
762 m_scenePresencesLock.ExitReadLock();
966 } 763 }
967
968 return result;
969 } 764 }
970 765
971 /// <summary> 766 /// <summary>
972 /// Request a scene presence by UUID 767 /// Request a scene presence by UUID. Fast, indexed lookup.
973 /// </summary> 768 /// </summary>
974 /// <param name="avatarID"></param> 769 /// <param name="agentID"></param>
975 /// <returns>null if the agent was not found</returns> 770 /// <returns>null if the presence was not found</returns>
976 protected internal ScenePresence GetScenePresence(UUID agentID) 771 protected internal ScenePresence GetScenePresence(UUID agentID)
977 { 772 {
978 ScenePresence sp; 773 ScenePresence sp;
979 774 m_scenePresencesLock.EnterReadLock();
980 lock (m_scenePresences) 775 try
981 { 776 {
982 m_scenePresences.TryGetValue(agentID, out sp); 777 m_scenePresences.TryGetValue(agentID, out sp);
983 } 778 }
984 779 finally
780 {
781 m_scenePresencesLock.ExitReadLock();
782 }
985 return sp; 783 return sp;
986 } 784 }
987 785
988 /// <summary> 786 /// <summary>
787 /// Request the scene presence by name.
788 /// </summary>
789 /// <param name="firstName"></param>
790 /// <param name="lastName"></param>
791 /// <returns>null if the presence was not found</returns>
792 protected internal ScenePresence GetScenePresence(string firstName, string lastName)
793 {
794 foreach (ScenePresence presence in GetScenePresences())
795 {
796 if (presence.Firstname == firstName && presence.Lastname == lastName)
797 return presence;
798 }
799 return null;
800 }
801
802 /// <summary>
803 /// Request the scene presence by localID.
804 /// </summary>
805 /// <param name="localID"></param>
806 /// <returns>null if the presence was not found</returns>
807 protected internal ScenePresence GetScenePresence(uint localID)
808 {
809 foreach (ScenePresence presence in GetScenePresences())
810 if (presence.LocalId == localID)
811 return presence;
812 return null;
813 }
814
815 protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar)
816 {
817 m_scenePresencesLock.EnterReadLock();
818 try
819 {
820 m_scenePresences.TryGetValue(agentID, out avatar);
821 }
822 finally
823 {
824 m_scenePresencesLock.ExitReadLock();
825 }
826 return (avatar != null);
827 }
828
829 protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar)
830 {
831 avatar = null;
832 foreach (ScenePresence presence in GetScenePresences())
833 {
834 if (String.Compare(name, presence.ControllingClient.Name, true) == 0)
835 {
836 avatar = presence;
837 break;
838 }
839 }
840 return (avatar != null);
841 }
842
843 /// <summary>
989 /// Get a scene object group that contains the prim with the given local id 844 /// Get a scene object group that contains the prim with the given local id
990 /// </summary> 845 /// </summary>
991 /// <param name="localID"></param> 846 /// <param name="localID"></param>
@@ -1136,34 +991,6 @@ namespace OpenSim.Region.Framework.Scenes
1136 return group.GetChildPart(fullID); 991 return group.GetChildPart(fullID);
1137 } 992 }
1138 993
1139 protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
1140 {
1141 lock (m_scenePresences)
1142 return m_scenePresences.TryGetValue(avatarId, out avatar);
1143 }
1144
1145 protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
1146 {
1147 ScenePresence[] presences = GetScenePresences();
1148
1149 for (int i = 0; i < presences.Length; i++)
1150 {
1151 ScenePresence presence = presences[i];
1152
1153 if (!presence.IsChildAgent)
1154 {
1155 if (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0)
1156 {
1157 avatar = presence;
1158 return true;
1159 }
1160 }
1161 }
1162
1163 avatar = null;
1164 return false;
1165 }
1166
1167 /// <summary> 994 /// <summary>
1168 /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over 995 /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over
1169 /// it 996 /// it
@@ -1226,6 +1053,10 @@ namespace OpenSim.Region.Framework.Scenes
1226 return UUID.Zero; 1053 return UUID.Zero;
1227 } 1054 }
1228 1055
1056 /// <summary>
1057 /// Performs action on all scene object groups.
1058 /// </summary>
1059 /// <param name="action"></param>
1229 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 1060 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1230 { 1061 {
1231 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); 1062 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
@@ -1242,6 +1073,47 @@ namespace OpenSim.Region.Framework.Scenes
1242 } 1073 }
1243 } 1074 }
1244 } 1075 }
1076
1077
1078 /// <summary>
1079 /// Performs action on all scene presences. This can ultimately run the actions in parallel but
1080 /// any delegates passed in will need to implement their own locking on data they reference and
1081 /// modify outside of the scope of the delegate.
1082 /// </summary>
1083 /// <param name="action"></param>
1084 public void ForEachScenePresence(Action<ScenePresence> action)
1085 {
1086 // Once all callers have their delegates configured for parallelism, we can unleash this
1087 /*
1088 Action<ScenePresence> protectedAction = new Action<ScenePresence>(delegate(ScenePresence sp)
1089 {
1090 try
1091 {
1092 action(sp);
1093 }
1094 catch (Exception e)
1095 {
1096 m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
1097 m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
1098 }
1099 });
1100 Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction);
1101 */
1102 // For now, perform actiona serially
1103
1104 foreach (ScenePresence sp in GetScenePresences())
1105 {
1106 try
1107 {
1108 action(sp);
1109 }
1110 catch (Exception e)
1111 {
1112 m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
1113 m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
1114 }
1115 }
1116 }
1245 1117
1246 #endregion 1118 #endregion
1247 1119
@@ -1924,6 +1796,7 @@ namespace OpenSim.Region.Framework.Scenes
1924 copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 0); 1796 copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 0);
1925 copy.HasGroupChanged = true; 1797 copy.HasGroupChanged = true;
1926 copy.ScheduleGroupForFullUpdate(); 1798 copy.ScheduleGroupForFullUpdate();
1799 copy.ResumeScripts();
1927 1800
1928 // required for physics to update it's position 1801 // required for physics to update it's position
1929 copy.AbsolutePosition = copy.AbsolutePosition; 1802 copy.AbsolutePosition = copy.AbsolutePosition;