aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IFriendsModule.cs7
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISceneViewer.cs50
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs68
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs28
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs251
7 files changed, 24 insertions, 414 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
index 8143164..fdede34 100644
--- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
@@ -34,18 +34,15 @@ namespace OpenSim.Region.Framework.Interfaces
34 public interface IFriendsModule 34 public interface IFriendsModule
35 { 35 {
36 /// <summary> 36 /// <summary>
37 /// Add a friend for the given user. 37 /// Add a friendship between two users.
38 /// </summary> 38 /// </summary>
39 /// <remarks> 39 /// <remarks>
40 /// This is a one-way friendship. To make a two way friendship you will need to call this again with the
41 /// client and friend reversed.
42 ///
43 /// Ultimately, it would be more useful to take in a user account here rather than having to have a user 40 /// Ultimately, it would be more useful to take in a user account here rather than having to have a user
44 /// present in the scene. 41 /// present in the scene.
45 /// </remarks> 42 /// </remarks>
46 /// <param name="client"></param> 43 /// <param name="client"></param>
47 /// <param name="friendID"></param> 44 /// <param name="friendID"></param>
48 void AddFriend(IClientAPI client, UUID friendID); 45 void AddFriendship(IClientAPI client, UUID friendID);
49 46
50 uint GetFriendPerms(UUID PrincipalID, UUID FriendID); 47 uint GetFriendPerms(UUID PrincipalID, UUID FriendID);
51 bool SendFriendsOnlineIfNeeded(IClientAPI client); 48 bool SendFriendsOnlineIfNeeded(IClientAPI client);
diff --git a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs
deleted file mode 100644
index e715e70..0000000
--- a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Framework.Scenes;
30
31namespace OpenSim.Region.Framework.Interfaces
32{
33 /// <summary>
34 /// Sends scheduled updates to it's associated ScenePresence.
35 /// </summary>
36 public interface ISceneViewer
37 {
38// void Reset();
39 void Close();
40
41 /// <summary>
42 /// Add the part to the queue of parts for which we need to send an update to the client
43 /// </summary>
44 /// <param name="part"></param>
45 void QueuePartForUpdate(SceneObjectPart part);
46
47 void SendPrimUpdates();
48 int GetPendingObjectsCount();
49 }
50} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index e668790..149d2d3 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2657,6 +2657,16 @@ namespace OpenSim.Region.Framework.Scenes
2657 land.SendLandUpdateToClient(client); 2657 land.SendLandUpdateToClient(client);
2658 } 2658 }
2659 } 2659 }
2660
2661 // Send all scene object to the new client
2662 Util.FireAndForget(delegate
2663 {
2664 Entities.ForEach(delegate(EntityBase e)
2665 {
2666 if (e != null && e is SceneObjectGroup)
2667 ((SceneObjectGroup)e).SendFullUpdateToClient(client);
2668 });
2669 });
2660 } 2670 }
2661 2671
2662 /// <summary> 2672 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index da10505..dd5e986 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2148,30 +2148,6 @@ namespace OpenSim.Region.Framework.Scenes
2148 } 2148 }
2149 } 2149 }
2150 2150
2151 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
2152 {
2153// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name);
2154
2155 RootPart.AddFullUpdateToAvatar(presence);
2156
2157 SceneObjectPart[] parts = m_parts.GetArray();
2158 for (int i = 0; i < parts.Length; i++)
2159 {
2160 SceneObjectPart part = parts[i];
2161 if (part != RootPart)
2162 part.AddFullUpdateToAvatar(presence);
2163 }
2164 }
2165
2166 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
2167 {
2168// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1} just to avatar {2}", Name, UUID, presence.Name);
2169
2170 SceneObjectPart[] parts = m_parts.GetArray();
2171 for (int i = 0; i < parts.Length; i++)
2172 parts[i].AddTerseUpdateToAvatar(presence);
2173 }
2174
2175 /// <summary> 2151 /// <summary>
2176 /// Schedule a full update for this scene object 2152 /// Schedule a full update for this scene object
2177 /// </summary> 2153 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 7025551..45ca0b7 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1425,25 +1425,6 @@ namespace OpenSim.Region.Framework.Scenes
1425 // m_log.Debug("Aprev: " + prevflag.ToString() + " curr: " + Flags.ToString()); 1425 // m_log.Debug("Aprev: " + prevflag.ToString() + " curr: " + Flags.ToString());
1426 } 1426 }
1427 1427
1428 /// <summary>
1429 /// Tell all scene presences that they should send updates for this part to their clients
1430 /// </summary>
1431 public void AddFullUpdateToAllAvatars()
1432 {
1433 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
1434 {
1435 AddFullUpdateToAvatar(avatar);
1436 });
1437 }
1438
1439 /// <summary>
1440 /// Tell the scene presence that it should send updates for this part to its client
1441 /// </summary>
1442 public void AddFullUpdateToAvatar(ScenePresence presence)
1443 {
1444 presence.SceneViewer.QueuePartForUpdate(this);
1445 }
1446
1447 public void AddNewParticleSystem(Primitive.ParticleSystem pSystem) 1428 public void AddNewParticleSystem(Primitive.ParticleSystem pSystem)
1448 { 1429 {
1449 m_particleSystem = pSystem.GetBytes(); 1430 m_particleSystem = pSystem.GetBytes();
@@ -1454,20 +1435,6 @@ namespace OpenSim.Region.Framework.Scenes
1454 m_particleSystem = new byte[0]; 1435 m_particleSystem = new byte[0];
1455 } 1436 }
1456 1437
1457 /// Terse updates
1458 public void AddTerseUpdateToAllAvatars()
1459 {
1460 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
1461 {
1462 AddTerseUpdateToAvatar(avatar);
1463 });
1464 }
1465
1466 public void AddTerseUpdateToAvatar(ScenePresence presence)
1467 {
1468 presence.SceneViewer.QueuePartForUpdate(this);
1469 }
1470
1471 public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim) 1438 public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim)
1472 { 1439 {
1473 byte[] data = new byte[16]; 1440 byte[] data = new byte[16];
@@ -2703,8 +2670,6 @@ namespace OpenSim.Region.Framework.Scenes
2703 //ParentGroup.RootPart.m_groupPosition = newpos; 2670 //ParentGroup.RootPart.m_groupPosition = newpos;
2704 } 2671 }
2705 ScheduleTerseUpdate(); 2672 ScheduleTerseUpdate();
2706
2707 //SendTerseUpdateToAllClients();
2708 } 2673 }
2709 2674
2710 public void PreloadSound(string sound) 2675 public void PreloadSound(string sound)
@@ -2888,6 +2853,13 @@ namespace OpenSim.Region.Framework.Scenes
2888 if (ParentGroup == null) 2853 if (ParentGroup == null)
2889 return; 2854 return;
2890 2855
2856 // This was pulled from SceneViewer. Attachments always receive full updates.
2857 // I could not verify if this is a requirement but this maintains existing behavior
2858 if (ParentGroup.IsAttachment)
2859 {
2860 ScheduleFullUpdate();
2861 }
2862
2891 if (UpdateFlag == UpdateRequired.NONE) 2863 if (UpdateFlag == UpdateRequired.NONE)
2892 { 2864 {
2893 ParentGroup.HasGroupChanged = true; 2865 ParentGroup.HasGroupChanged = true;
@@ -2982,23 +2954,6 @@ namespace OpenSim.Region.Framework.Scenes
2982 } 2954 }
2983 2955
2984 /// <summary> 2956 /// <summary>
2985 /// Send a full update to all clients except the one nominated.
2986 /// </summary>
2987 /// <param name="agentID"></param>
2988 public void SendFullUpdateToAllClientsExcept(UUID agentID)
2989 {
2990 if (ParentGroup == null)
2991 return;
2992
2993 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2994 {
2995 // Ugly reference :(
2996 if (avatar.UUID != agentID)
2997 SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID));
2998 });
2999 }
3000
3001 /// <summary>
3002 /// Sends a full update to the client 2957 /// Sends a full update to the client
3003 /// </summary> 2958 /// </summary>
3004 /// <param name="remoteClient"></param> 2959 /// <param name="remoteClient"></param>
@@ -3074,7 +3029,8 @@ namespace OpenSim.Region.Framework.Scenes
3074 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3029 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
3075 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3030 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
3076 { 3031 {
3077 AddTerseUpdateToAllAvatars(); 3032
3033 SendTerseUpdateToAllClients();
3078 ClearUpdateSchedule(); 3034 ClearUpdateSchedule();
3079 3035
3080 // Update the "last" values 3036 // Update the "last" values
@@ -3089,7 +3045,7 @@ namespace OpenSim.Region.Framework.Scenes
3089 } 3045 }
3090 case UpdateRequired.FULL: 3046 case UpdateRequired.FULL:
3091 { 3047 {
3092 AddFullUpdateToAllAvatars(); 3048 SendFullUpdateToAllClients();
3093 break; 3049 break;
3094 } 3050 }
3095 } 3051 }
@@ -3193,9 +3149,9 @@ namespace OpenSim.Region.Framework.Scenes
3193 /// </summary> 3149 /// </summary>
3194 public void SendTerseUpdateToAllClients() 3150 public void SendTerseUpdateToAllClients()
3195 { 3151 {
3196 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3152 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
3197 { 3153 {
3198 SendTerseUpdateToClient(avatar.ControllingClient); 3154 SendTerseUpdateToClient(client);
3199 }); 3155 });
3200 } 3156 }
3201 3157
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 8906c6f..839259f 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -135,7 +135,6 @@ namespace OpenSim.Region.Framework.Scenes
135 private Vector3 m_lastPosition; 135 private Vector3 m_lastPosition;
136 private Quaternion m_lastRotation; 136 private Quaternion m_lastRotation;
137 private Vector3 m_lastVelocity; 137 private Vector3 m_lastVelocity;
138 //private int m_lastTerseSent;
139 138
140 private Vector3? m_forceToApply; 139 private Vector3? m_forceToApply;
141 private int m_userFlags; 140 private int m_userFlags;
@@ -645,14 +644,6 @@ namespace OpenSim.Region.Framework.Scenes
645 set { m_health = value; } 644 set { m_health = value; }
646 } 645 }
647 646
648 private ISceneViewer m_sceneViewer;
649
650 public ISceneViewer SceneViewer
651 {
652 get { return m_sceneViewer; }
653 private set { m_sceneViewer = value; }
654 }
655
656 public void AdjustKnownSeeds() 647 public void AdjustKnownSeeds()
657 { 648 {
658 Dictionary<ulong, string> seeds; 649 Dictionary<ulong, string> seeds;
@@ -756,7 +747,6 @@ namespace OpenSim.Region.Framework.Scenes
756 AttachmentsSyncLock = new Object(); 747 AttachmentsSyncLock = new Object();
757 748
758 m_sendCourseLocationsMethod = SendCoarseLocationsDefault; 749 m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
759 SceneViewer = new SceneViewer(this);
760 Animator = new ScenePresenceAnimator(this); 750 Animator = new ScenePresenceAnimator(this);
761 PresenceType = type; 751 PresenceType = type;
762 DrawDistance = world.DefaultDrawDistance; 752 DrawDistance = world.DefaultDrawDistance;
@@ -867,16 +857,6 @@ namespace OpenSim.Region.Framework.Scenes
867 return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID); 857 return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID);
868 } 858 }
869 859
870 /// <summary>
871 /// Send updates to the client about prims which have been placed on the update queue. We don't
872 /// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent
873 /// timestamp has already been sent.
874 /// </summary>
875 public void SendPrimUpdates()
876 {
877 SceneViewer.SendPrimUpdates();
878 }
879
880 #region Status Methods 860 #region Status Methods
881 861
882 /// <summary> 862 /// <summary>
@@ -2420,10 +2400,6 @@ namespace OpenSim.Region.Framework.Scenes
2420 const float ROTATION_TOLERANCE = 0.01f; 2400 const float ROTATION_TOLERANCE = 0.01f;
2421 const float VELOCITY_TOLERANCE = 0.001f; 2401 const float VELOCITY_TOLERANCE = 0.001f;
2422 const float POSITION_TOLERANCE = 0.05f; 2402 const float POSITION_TOLERANCE = 0.05f;
2423 //const int TIME_MS_TOLERANCE = 3000;
2424
2425 if (!sendingPrims)
2426 Util.FireAndForget(delegate { sendingPrims = true; SendPrimUpdates(); sendingPrims = false; });
2427 2403
2428 if (IsChildAgent == false) 2404 if (IsChildAgent == false)
2429 { 2405 {
@@ -2435,7 +2411,6 @@ namespace OpenSim.Region.Framework.Scenes
2435 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || 2411 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2436 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 2412 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2437 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) 2413 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2438 //Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2439 { 2414 {
2440 SendTerseUpdateToAllClients(); 2415 SendTerseUpdateToAllClients();
2441 2416
@@ -2443,7 +2418,6 @@ namespace OpenSim.Region.Framework.Scenes
2443 m_lastPosition = m_pos; 2418 m_lastPosition = m_pos;
2444 m_lastRotation = Rotation; 2419 m_lastRotation = Rotation;
2445 m_lastVelocity = Velocity; 2420 m_lastVelocity = Velocity;
2446 //m_lastTerseSent = Environment.TickCount;
2447 } 2421 }
2448 2422
2449 // followed suggestion from mic bowman. reversed the two lines below. 2423 // followed suggestion from mic bowman. reversed the two lines below.
@@ -3430,8 +3404,6 @@ namespace OpenSim.Region.Framework.Scenes
3430 // unsetting the elapsed callback should be enough to allow for cleanup however. 3404 // unsetting the elapsed callback should be enough to allow for cleanup however.
3431 // m_reprioritizationTimer.Dispose(); 3405 // m_reprioritizationTimer.Dispose();
3432 3406
3433 SceneViewer.Close();
3434
3435 RemoveFromPhysicalScene(); 3407 RemoveFromPhysicalScene();
3436 Animator.Close(); 3408 Animator.Close();
3437 Animator = null; 3409 Animator = null;
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
deleted file mode 100644
index 2c3084c..0000000
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ /dev/null
@@ -1,251 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31using log4net;
32using OpenSim.Framework;
33using OpenSim.Framework.Client;
34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes.Types;
36
37namespace OpenSim.Region.Framework.Scenes
38{
39 public class SceneViewer : ISceneViewer
40 {
41 /// <summary>
42 /// Is this scene viewer enabled?
43 /// </summary>
44 private bool IsEnabled { get; set; }
45
46 /// <summary>
47 /// The scene presence serviced by this viewer.
48 /// </summary>
49 protected ScenePresence m_presence;
50
51 /// <summary>
52 /// The queue of parts for which we need to send out updates.
53 /// </summary>
54 protected UpdateQueue m_partsUpdateQueue = new UpdateQueue();
55
56 /// <summary>
57 /// The queue of objects for which we need to send out updates.
58 /// </summary>
59 protected Queue<SceneObjectGroup> m_pendingObjects;
60
61 /// <summary>
62 /// The last update assocated with a given part update.
63 /// </summary>
64 protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>();
65
66 public SceneViewer(ScenePresence presence)
67 {
68 m_presence = presence;
69 IsEnabled = true;
70 }
71
72 public void QueuePartForUpdate(SceneObjectPart part)
73 {
74 if (!IsEnabled)
75 return;
76
77 lock (m_partsUpdateQueue)
78 {
79 m_partsUpdateQueue.Enqueue(part);
80 }
81 }
82
83 public void SendPrimUpdates()
84 {
85 if (m_pendingObjects == null)
86 {
87 m_pendingObjects = new Queue<SceneObjectGroup>();
88
89 lock (m_pendingObjects)
90 {
91 EntityBase[] entities = m_presence.Scene.Entities.GetEntities();
92 foreach (EntityBase e in entities)
93 {
94 if (e != null && e is SceneObjectGroup)
95 m_pendingObjects.Enqueue((SceneObjectGroup)e);
96 }
97 }
98 }
99
100 lock (m_pendingObjects)
101 {
102 // We must do this under lock so that we don't suffer a race condition if another thread closes the
103 // viewer
104 if (!IsEnabled)
105 return;
106
107 while (m_pendingObjects != null && m_pendingObjects.Count > 0)
108 {
109 SceneObjectGroup g = m_pendingObjects.Dequeue();
110 // Yes, this can really happen
111 if (g == null)
112 continue;
113
114 // This is where we should check for draw distance
115 // do culling and stuff. Problem with that is that until
116 // we recheck in movement, that won't work right.
117 // So it's not implemented now.
118 //
119
120 // Don't even queue if we have sent this one
121 //
122 if (!m_updateTimes.ContainsKey(g.UUID))
123 g.ScheduleFullUpdateToAvatar(m_presence);
124 }
125
126 while (m_partsUpdateQueue != null && m_partsUpdateQueue.Count != null && m_partsUpdateQueue.Count > 0)
127 {
128 SceneObjectPart part = m_partsUpdateQueue.Dequeue();
129
130 if (part.ParentGroup.IsDeleted)
131 continue;
132
133 if (m_updateTimes.ContainsKey(part.UUID))
134 {
135 ScenePartUpdate update = m_updateTimes[part.UUID];
136
137 // We deal with the possibility that two updates occur at
138 // the same unix time at the update point itself.
139 if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment)
140 {
141 // m_log.DebugFormat(
142 // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}",
143 // part.Name, part.UUID, part.TimeStampFull);
144
145 part.SendFullUpdate(m_presence.ControllingClient,
146 m_presence.GenerateClientFlags(part.UUID));
147
148 // We'll update to the part's timestamp rather than
149 // the current time to avoid the race condition
150 // whereby the next tick occurs while we are doing
151 // this update. If this happened, then subsequent
152 // updates which occurred on the same tick or the
153 // next tick of the last update would be ignored.
154 update.LastFullUpdateTime = part.TimeStampFull;
155 }
156 else if (update.LastTerseUpdateTime <= part.TimeStampTerse)
157 {
158 // m_log.DebugFormat(
159 // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}",
160 // part.Name, part.UUID, part.TimeStampTerse);
161
162 part.SendTerseUpdateToClient(m_presence.ControllingClient);
163
164 update.LastTerseUpdateTime = part.TimeStampTerse;
165 }
166 }
167 else
168 {
169 //never been sent to client before so do full update
170 ScenePartUpdate update = new ScenePartUpdate();
171 update.FullID = part.UUID;
172 update.LastFullUpdateTime = part.TimeStampFull;
173 m_updateTimes.Add(part.UUID, update);
174
175 // Attachment handling
176 //
177 if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0)
178 {
179 if (part != part.ParentGroup.RootPart)
180 continue;
181
182 part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient);
183 continue;
184 }
185
186 part.SendFullUpdate(m_presence.ControllingClient,
187 m_presence.GenerateClientFlags(part.UUID));
188 }
189 }
190 }
191 }
192
193// public void Reset()
194// {
195// if (m_pendingObjects == null)
196// return;
197//
198// lock (m_pendingObjects)
199// {
200// if (m_pendingObjects != null)
201// {
202// m_pendingObjects.Clear();
203// m_pendingObjects = null;
204// }
205// }
206// }
207
208 public void Close()
209 {
210 lock (m_pendingObjects)
211 {
212 // We perform this under the m_pendingObjects lock in order to avoid a race condition with another
213 // thread on SendPrimUpdates()
214 IsEnabled = false;
215
216 lock (m_updateTimes)
217 {
218 m_updateTimes.Clear();
219 }
220
221 lock (m_partsUpdateQueue)
222 {
223 m_partsUpdateQueue.Clear();
224 }
225 }
226 }
227
228 public int GetPendingObjectsCount()
229 {
230 if (m_pendingObjects != null)
231 lock (m_pendingObjects)
232 return m_pendingObjects.Count;
233
234 return 0;
235 }
236
237 public class ScenePartUpdate
238 {
239 public UUID FullID;
240 public uint LastFullUpdateTime;
241 public uint LastTerseUpdateTime;
242
243 public ScenePartUpdate()
244 {
245 FullID = UUID.Zero;
246 LastFullUpdateTime = 0;
247 LastTerseUpdateTime = 0;
248 }
249 }
250 }
251}