diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneViewer.cs | 159 |
1 files changed, 81 insertions, 78 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 15bc33d..5cbd8d9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs | |||
@@ -67,105 +67,108 @@ namespace OpenSim.Region.Framework.Scenes | |||
67 | 67 | ||
68 | public void SendPrimUpdates() | 68 | public void SendPrimUpdates() |
69 | { | 69 | { |
70 | if (m_pendingObjects == null) | 70 | lock(m_pendingObjects) |
71 | { | 71 | { |
72 | if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) | 72 | if (m_pendingObjects == null) |
73 | { | 73 | { |
74 | m_pendingObjects = new Queue<SceneObjectGroup>(); | 74 | if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) |
75 | |||
76 | foreach (EntityBase e in m_presence.Scene.Entities) | ||
77 | { | 75 | { |
78 | if (e is SceneObjectGroup) | 76 | m_pendingObjects = new Queue<SceneObjectGroup>(); |
79 | m_pendingObjects.Enqueue((SceneObjectGroup)e); | 77 | |
78 | foreach (EntityBase e in m_presence.Scene.Entities) | ||
79 | { | ||
80 | if (e != null && e is SceneObjectGroup) | ||
81 | m_pendingObjects.Enqueue((SceneObjectGroup)e); | ||
82 | } | ||
80 | } | 83 | } |
81 | } | 84 | } |
82 | } | ||
83 | |||
84 | while (m_pendingObjects != null && m_pendingObjects.Count > 0) | ||
85 | { | ||
86 | SceneObjectGroup g = m_pendingObjects.Dequeue(); | ||
87 | // Yes, this can really happen | ||
88 | if (g == null) | ||
89 | continue; | ||
90 | |||
91 | // This is where we should check for draw distance | ||
92 | // do culling and stuff. Problem with that is that until | ||
93 | // we recheck in movement, that won't work right. | ||
94 | // So it's not implemented now. | ||
95 | // | ||
96 | |||
97 | // Don't even queue if we have sent this one | ||
98 | // | ||
99 | if (!m_updateTimes.ContainsKey(g.UUID)) | ||
100 | g.ScheduleFullUpdateToAvatar(m_presence); | ||
101 | } | ||
102 | 85 | ||
103 | while (m_partsUpdateQueue.Count > 0) | 86 | while (m_pendingObjects != null && m_pendingObjects.Count > 0) |
104 | { | ||
105 | SceneObjectPart part = m_partsUpdateQueue.Dequeue(); | ||
106 | |||
107 | if (part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
108 | continue; | ||
109 | |||
110 | if (m_updateTimes.ContainsKey(part.UUID)) | ||
111 | { | 87 | { |
112 | ScenePartUpdate update = m_updateTimes[part.UUID]; | 88 | SceneObjectGroup g = m_pendingObjects.Dequeue(); |
89 | // Yes, this can really happen | ||
90 | if (g == null) | ||
91 | continue; | ||
113 | 92 | ||
114 | // We deal with the possibility that two updates occur at | 93 | // This is where we should check for draw distance |
115 | // the same unix time at the update point itself. | 94 | // do culling and stuff. Problem with that is that until |
95 | // we recheck in movement, that won't work right. | ||
96 | // So it's not implemented now. | ||
97 | // | ||
98 | |||
99 | // Don't even queue if we have sent this one | ||
100 | // | ||
101 | if (!m_updateTimes.ContainsKey(g.UUID)) | ||
102 | g.ScheduleFullUpdateToAvatar(m_presence); | ||
103 | } | ||
116 | 104 | ||
117 | if ((update.LastFullUpdateTime < part.TimeStampFull) || | 105 | while (m_partsUpdateQueue.Count > 0) |
118 | part.IsAttachment) | 106 | { |
107 | SceneObjectPart part = m_partsUpdateQueue.Dequeue(); | ||
108 | |||
109 | if (part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
110 | continue; | ||
111 | |||
112 | if (m_updateTimes.ContainsKey(part.UUID)) | ||
119 | { | 113 | { |
120 | // m_log.DebugFormat( | 114 | ScenePartUpdate update = m_updateTimes[part.UUID]; |
121 | // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", | ||
122 | // part.Name, part.UUID, part.TimeStampFull); | ||
123 | 115 | ||
124 | part.SendFullUpdate(m_presence.ControllingClient, | 116 | // We deal with the possibility that two updates occur at |
125 | m_presence.GenerateClientFlags(part.UUID)); | 117 | // the same unix time at the update point itself. |
126 | 118 | ||
127 | // We'll update to the part's timestamp rather than | 119 | if ((update.LastFullUpdateTime < part.TimeStampFull) || |
128 | // the current time to avoid the race condition | 120 | part.IsAttachment) |
129 | // whereby the next tick occurs while we are doing | 121 | { |
130 | // this update. If this happened, then subsequent | 122 | // m_log.DebugFormat( |
131 | // updates which occurred on the same tick or the | 123 | // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", |
132 | // next tick of the last update would be ignored. | 124 | // part.Name, part.UUID, part.TimeStampFull); |
133 | 125 | ||
134 | update.LastFullUpdateTime = part.TimeStampFull; | 126 | part.SendFullUpdate(m_presence.ControllingClient, |
127 | m_presence.GenerateClientFlags(part.UUID)); | ||
135 | 128 | ||
136 | } | 129 | // We'll update to the part's timestamp rather than |
137 | else if (update.LastTerseUpdateTime <= part.TimeStampTerse) | 130 | // the current time to avoid the race condition |
138 | { | 131 | // whereby the next tick occurs while we are doing |
139 | // m_log.DebugFormat( | 132 | // this update. If this happened, then subsequent |
140 | // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", | 133 | // updates which occurred on the same tick or the |
141 | // part.Name, part.UUID, part.TimeStampTerse); | 134 | // next tick of the last update would be ignored. |
142 | 135 | ||
143 | part.SendTerseUpdateToClient(m_presence.ControllingClient); | 136 | update.LastFullUpdateTime = part.TimeStampFull; |
144 | 137 | ||
145 | update.LastTerseUpdateTime = part.TimeStampTerse; | 138 | } |
146 | } | 139 | else if (update.LastTerseUpdateTime <= part.TimeStampTerse) |
147 | } | 140 | { |
148 | else | 141 | // m_log.DebugFormat( |
149 | { | 142 | // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", |
150 | //never been sent to client before so do full update | 143 | // part.Name, part.UUID, part.TimeStampTerse); |
151 | ScenePartUpdate update = new ScenePartUpdate(); | ||
152 | update.FullID = part.UUID; | ||
153 | update.LastFullUpdateTime = part.TimeStampFull; | ||
154 | m_updateTimes.Add(part.UUID, update); | ||
155 | 144 | ||
156 | // Attachment handling | 145 | part.SendTerseUpdateToClient(m_presence.ControllingClient); |
157 | // | 146 | |
158 | if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) | 147 | update.LastTerseUpdateTime = part.TimeStampTerse; |
148 | } | ||
149 | } | ||
150 | else | ||
159 | { | 151 | { |
160 | if (part != part.ParentGroup.RootPart) | 152 | //never been sent to client before so do full update |
153 | ScenePartUpdate update = new ScenePartUpdate(); | ||
154 | update.FullID = part.UUID; | ||
155 | update.LastFullUpdateTime = part.TimeStampFull; | ||
156 | m_updateTimes.Add(part.UUID, update); | ||
157 | |||
158 | // Attachment handling | ||
159 | // | ||
160 | if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) | ||
161 | { | ||
162 | if (part != part.ParentGroup.RootPart) | ||
163 | continue; | ||
164 | |||
165 | part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); | ||
161 | continue; | 166 | continue; |
167 | } | ||
162 | 168 | ||
163 | part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); | 169 | part.SendFullUpdate(m_presence.ControllingClient, |
164 | continue; | 170 | m_presence.GenerateClientFlags(part.UUID)); |
165 | } | 171 | } |
166 | |||
167 | part.SendFullUpdate(m_presence.ControllingClient, | ||
168 | m_presence.GenerateClientFlags(part.UUID)); | ||
169 | } | 172 | } |
170 | } | 173 | } |
171 | } | 174 | } |