aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneViewer.cs
diff options
context:
space:
mode:
authorDan Lake2011-11-11 17:16:52 -0800
committerDan Lake2011-11-11 17:16:52 -0800
commit5fd17491509fb4b939666cdc37951e213f054242 (patch)
tree966baad538ac254ca1e1ba6cd83cc6487bf2726d /OpenSim/Region/Framework/Scenes/SceneViewer.cs
parentdoh - correct build break (diff)
downloadopensim-SC_OLD-5fd17491509fb4b939666cdc37951e213f054242.zip
opensim-SC_OLD-5fd17491509fb4b939666cdc37951e213f054242.tar.gz
opensim-SC_OLD-5fd17491509fb4b939666cdc37951e213f054242.tar.bz2
opensim-SC_OLD-5fd17491509fb4b939666cdc37951e213f054242.tar.xz
Remove SceneViewer from ScenePresence to reduce quadruple queueing of
prim update to only triple queuing. Existing method was: 1. Schedule prim for update, adding to scene update list 2. Update on SOGs during heartbeat queues update onto each SceneViewer 3. Update on SPs during heartbeat queues update onto each IClientAPI 4. ProcessEntityUpdates queues updates into UDP send stack Now the SceneViewer has been eliminated so updates are scheduled at any time and then put onto the IClientAPI priority queues immediately during SceneGraph.UpdateObjectGroups.
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneViewer.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs251
1 files changed, 0 insertions, 251 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
deleted file mode 100644
index d6bb81c..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.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}