aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneViewer.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-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}