diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneManager.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneManager.cs | 669 |
1 files changed, 669 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs new file mode 100644 index 0000000..180f8a1 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs | |||
@@ -0,0 +1,669 @@ | |||
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 OpenSim 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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Net; | ||
31 | using System.Reflection; | ||
32 | using OpenMetaverse; | ||
33 | using log4net; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Region.Framework.Interfaces; | ||
36 | |||
37 | namespace OpenSim.Region.Framework.Scenes | ||
38 | { | ||
39 | public delegate void RestartSim(RegionInfo thisregion); | ||
40 | |||
41 | /// <summary> | ||
42 | /// Manager for adding, closing and restarting scenes. | ||
43 | /// </summary> | ||
44 | public class SceneManager | ||
45 | { | ||
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | |||
48 | public event RestartSim OnRestartSim; | ||
49 | |||
50 | private readonly List<Scene> m_localScenes; | ||
51 | private Scene m_currentScene = null; | ||
52 | |||
53 | public List<Scene> Scenes | ||
54 | { | ||
55 | get { return m_localScenes; } | ||
56 | } | ||
57 | |||
58 | public Scene CurrentScene | ||
59 | { | ||
60 | get { return m_currentScene; } | ||
61 | } | ||
62 | |||
63 | public Scene CurrentOrFirstScene | ||
64 | { | ||
65 | get | ||
66 | { | ||
67 | if (m_currentScene == null) | ||
68 | { | ||
69 | return m_localScenes[0]; | ||
70 | } | ||
71 | else | ||
72 | { | ||
73 | return m_currentScene; | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | |||
78 | public SceneManager() | ||
79 | { | ||
80 | m_localScenes = new List<Scene>(); | ||
81 | } | ||
82 | |||
83 | public void Close() | ||
84 | { | ||
85 | // collect known shared modules in sharedModules | ||
86 | Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>(); | ||
87 | for (int i = 0; i < m_localScenes.Count; i++) | ||
88 | { | ||
89 | // extract known shared modules from scene | ||
90 | foreach (string k in m_localScenes[i].Modules.Keys) | ||
91 | { | ||
92 | if (m_localScenes[i].Modules[k].IsSharedModule && | ||
93 | !sharedModules.ContainsKey(k)) | ||
94 | sharedModules[k] = m_localScenes[i].Modules[k]; | ||
95 | } | ||
96 | // close scene/region | ||
97 | m_localScenes[i].Close(); | ||
98 | } | ||
99 | |||
100 | // all regions/scenes are now closed, we can now safely | ||
101 | // close all shared modules | ||
102 | foreach (IRegionModule mod in sharedModules.Values) | ||
103 | { | ||
104 | mod.Close(); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | public void Close(Scene cscene) | ||
109 | { | ||
110 | if (m_localScenes.Contains(cscene)) | ||
111 | { | ||
112 | for (int i = 0; i < m_localScenes.Count; i++) | ||
113 | { | ||
114 | if (m_localScenes[i].Equals(cscene)) | ||
115 | { | ||
116 | m_localScenes[i].Close(); | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | |||
122 | public void Add(Scene scene) | ||
123 | { | ||
124 | scene.OnRestart += HandleRestart; | ||
125 | m_localScenes.Add(scene); | ||
126 | } | ||
127 | |||
128 | public void HandleRestart(RegionInfo rdata) | ||
129 | { | ||
130 | m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main"); | ||
131 | int RegionSceneElement = -1; | ||
132 | for (int i = 0; i < m_localScenes.Count; i++) | ||
133 | { | ||
134 | if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName) | ||
135 | { | ||
136 | RegionSceneElement = i; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | // Now we make sure the region is no longer known about by the SceneManager | ||
141 | // Prevents duplicates. | ||
142 | |||
143 | if (RegionSceneElement >= 0) | ||
144 | { | ||
145 | m_localScenes.RemoveAt(RegionSceneElement); | ||
146 | } | ||
147 | |||
148 | // Send signal to main that we're restarting this sim. | ||
149 | OnRestartSim(rdata); | ||
150 | } | ||
151 | |||
152 | public void SendSimOnlineNotification(ulong regionHandle) | ||
153 | { | ||
154 | RegionInfo Result = null; | ||
155 | |||
156 | for (int i = 0; i < m_localScenes.Count; i++) | ||
157 | { | ||
158 | if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle) | ||
159 | { | ||
160 | // Inform other regions to tell their avatar about me | ||
161 | Result = m_localScenes[i].RegionInfo; | ||
162 | } | ||
163 | } | ||
164 | if (Result != null) | ||
165 | { | ||
166 | for (int i = 0; i < m_localScenes.Count; i++) | ||
167 | { | ||
168 | if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle) | ||
169 | { | ||
170 | // Inform other regions to tell their avatar about me | ||
171 | //m_localScenes[i].OtherRegionUp(Result); | ||
172 | } | ||
173 | } | ||
174 | } | ||
175 | else | ||
176 | { | ||
177 | m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up"); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | /// <summary> | ||
182 | /// Save the prims in the current scene to an xml file in OpenSimulator's original 'xml' format | ||
183 | /// </summary> | ||
184 | /// <param name="filename"></param> | ||
185 | public void SaveCurrentSceneToXml(string filename) | ||
186 | { | ||
187 | IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>(); | ||
188 | if (serialiser != null) | ||
189 | serialiser.SavePrimsToXml(CurrentOrFirstScene, filename); | ||
190 | } | ||
191 | |||
192 | /// <summary> | ||
193 | /// Load an xml file of prims in OpenSimulator's original 'xml' file format to the current scene | ||
194 | /// </summary> | ||
195 | /// <param name="filename"></param> | ||
196 | /// <param name="generateNewIDs"></param> | ||
197 | /// <param name="loadOffset"></param> | ||
198 | public void LoadCurrentSceneFromXml(string filename, bool generateNewIDs, Vector3 loadOffset) | ||
199 | { | ||
200 | IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>(); | ||
201 | if (serialiser != null) | ||
202 | serialiser.LoadPrimsFromXml(CurrentOrFirstScene, filename, generateNewIDs, loadOffset); | ||
203 | } | ||
204 | |||
205 | /// <summary> | ||
206 | /// Save the prims in the current scene to an xml file in OpenSimulator's current 'xml2' format | ||
207 | /// </summary> | ||
208 | /// <param name="filename"></param> | ||
209 | public void SaveCurrentSceneToXml2(string filename) | ||
210 | { | ||
211 | IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>(); | ||
212 | if (serialiser != null) | ||
213 | serialiser.SavePrimsToXml2(CurrentOrFirstScene, filename); | ||
214 | } | ||
215 | |||
216 | public void SaveNamedPrimsToXml2(string primName, string filename) | ||
217 | { | ||
218 | IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>(); | ||
219 | if (serialiser != null) | ||
220 | serialiser.SaveNamedPrimsToXml2(CurrentOrFirstScene, primName, filename); | ||
221 | } | ||
222 | |||
223 | /// <summary> | ||
224 | /// Load an xml file of prims in OpenSimulator's current 'xml2' file format to the current scene | ||
225 | /// </summary> | ||
226 | public void LoadCurrentSceneFromXml2(string filename) | ||
227 | { | ||
228 | IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>(); | ||
229 | if (serialiser != null) | ||
230 | serialiser.LoadPrimsFromXml2(CurrentOrFirstScene, filename); | ||
231 | } | ||
232 | |||
233 | /// <summary> | ||
234 | /// Save the current scene to an OpenSimulator archive. This archive will eventually include the prim's assets | ||
235 | /// as well as the details of the prims themselves. | ||
236 | /// </summary> | ||
237 | /// <param name="filename"></param> | ||
238 | public void SaveCurrentSceneToArchive(string filename) | ||
239 | { | ||
240 | IRegionArchiverModule archiver = CurrentOrFirstScene.RequestModuleInterface<IRegionArchiverModule>(); | ||
241 | if (archiver != null) | ||
242 | archiver.ArchiveRegion(filename); | ||
243 | } | ||
244 | |||
245 | /// <summary> | ||
246 | /// Load an OpenSim archive into the current scene. This will load both the shapes of the prims and upload | ||
247 | /// their assets to the asset service. | ||
248 | /// </summary> | ||
249 | /// <param name="filename"></param> | ||
250 | public void LoadArchiveToCurrentScene(string filename) | ||
251 | { | ||
252 | IRegionArchiverModule archiver = CurrentOrFirstScene.RequestModuleInterface<IRegionArchiverModule>(); | ||
253 | if (archiver != null) | ||
254 | archiver.DearchiveRegion(filename); | ||
255 | } | ||
256 | |||
257 | public string SaveCurrentSceneMapToXmlString() | ||
258 | { | ||
259 | return CurrentOrFirstScene.Heightmap.SaveToXmlString(); | ||
260 | } | ||
261 | |||
262 | public void LoadCurrenSceneMapFromXmlString(string mapData) | ||
263 | { | ||
264 | CurrentOrFirstScene.Heightmap.LoadFromXmlString(mapData); | ||
265 | } | ||
266 | |||
267 | public void SendCommandToPluginModules(string[] cmdparams) | ||
268 | { | ||
269 | ForEachCurrentScene(delegate(Scene scene) { scene.SendCommandToPlugins(cmdparams); }); | ||
270 | } | ||
271 | |||
272 | public void SetBypassPermissionsOnCurrentScene(bool bypassPermissions) | ||
273 | { | ||
274 | ForEachCurrentScene(delegate(Scene scene) { scene.Permissions.SetBypassPermissions(bypassPermissions); }); | ||
275 | } | ||
276 | |||
277 | private void ForEachCurrentScene(Action<Scene> func) | ||
278 | { | ||
279 | if (m_currentScene == null) | ||
280 | { | ||
281 | m_localScenes.ForEach(func); | ||
282 | } | ||
283 | else | ||
284 | { | ||
285 | func(m_currentScene); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | public void RestartCurrentScene() | ||
290 | { | ||
291 | ForEachCurrentScene(delegate(Scene scene) { scene.RestartNow(); }); | ||
292 | } | ||
293 | |||
294 | public void BackupCurrentScene() | ||
295 | { | ||
296 | ForEachCurrentScene(delegate(Scene scene) { scene.Backup(); }); | ||
297 | } | ||
298 | |||
299 | public void HandleAlertCommandOnCurrentScene(string[] cmdparams) | ||
300 | { | ||
301 | ForEachCurrentScene(delegate(Scene scene) { scene.HandleAlertCommand(cmdparams); }); | ||
302 | } | ||
303 | |||
304 | public void SendGeneralMessage(string msg) | ||
305 | { | ||
306 | ForEachCurrentScene(delegate(Scene scene) { scene.HandleAlertCommand(new string[] { "general", msg }); }); | ||
307 | } | ||
308 | |||
309 | public bool TrySetCurrentScene(string regionName) | ||
310 | { | ||
311 | if ((String.Compare(regionName, "root") == 0) | ||
312 | || (String.Compare(regionName, "..") == 0) | ||
313 | || (String.Compare(regionName, "/") == 0)) | ||
314 | { | ||
315 | m_currentScene = null; | ||
316 | return true; | ||
317 | } | ||
318 | else | ||
319 | { | ||
320 | foreach (Scene scene in m_localScenes) | ||
321 | { | ||
322 | if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0) | ||
323 | { | ||
324 | m_currentScene = scene; | ||
325 | return true; | ||
326 | } | ||
327 | } | ||
328 | |||
329 | return false; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | public bool TrySetCurrentScene(UUID regionID) | ||
334 | { | ||
335 | Console.WriteLine("Searching for Region: '{0}'", regionID.ToString()); | ||
336 | |||
337 | foreach (Scene scene in m_localScenes) | ||
338 | { | ||
339 | if (scene.RegionInfo.RegionID == regionID) | ||
340 | { | ||
341 | m_currentScene = scene; | ||
342 | return true; | ||
343 | } | ||
344 | } | ||
345 | |||
346 | return false; | ||
347 | } | ||
348 | |||
349 | public bool TryGetScene(string regionName, out Scene scene) | ||
350 | { | ||
351 | foreach (Scene mscene in m_localScenes) | ||
352 | { | ||
353 | if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0) | ||
354 | { | ||
355 | scene = mscene; | ||
356 | return true; | ||
357 | } | ||
358 | } | ||
359 | scene = null; | ||
360 | return false; | ||
361 | } | ||
362 | |||
363 | public bool TryGetScene(UUID regionID, out Scene scene) | ||
364 | { | ||
365 | foreach (Scene mscene in m_localScenes) | ||
366 | { | ||
367 | if (mscene.RegionInfo.RegionID == regionID) | ||
368 | { | ||
369 | scene = mscene; | ||
370 | return true; | ||
371 | } | ||
372 | } | ||
373 | |||
374 | scene = null; | ||
375 | return false; | ||
376 | } | ||
377 | |||
378 | public bool TryGetScene(uint locX, uint locY, out Scene scene) | ||
379 | { | ||
380 | foreach (Scene mscene in m_localScenes) | ||
381 | { | ||
382 | if (mscene.RegionInfo.RegionLocX == locX && | ||
383 | mscene.RegionInfo.RegionLocY == locY) | ||
384 | { | ||
385 | scene = mscene; | ||
386 | return true; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | scene = null; | ||
391 | return false; | ||
392 | } | ||
393 | |||
394 | public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene) | ||
395 | { | ||
396 | foreach (Scene mscene in m_localScenes) | ||
397 | { | ||
398 | if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) && | ||
399 | (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port)) | ||
400 | { | ||
401 | scene = mscene; | ||
402 | return true; | ||
403 | } | ||
404 | } | ||
405 | |||
406 | scene = null; | ||
407 | return false; | ||
408 | } | ||
409 | |||
410 | /// <summary> | ||
411 | /// Set the debug packet level on the current scene. This level governs which packets are printed out to the | ||
412 | /// console. | ||
413 | /// </summary> | ||
414 | /// <param name="newDebug"></param> | ||
415 | public void SetDebugPacketLevelOnCurrentScene(int newDebug) | ||
416 | { | ||
417 | ForEachCurrentScene(delegate(Scene scene) | ||
418 | { | ||
419 | List<ScenePresence> scenePresences = scene.GetScenePresences(); | ||
420 | |||
421 | foreach (ScenePresence scenePresence in scenePresences) | ||
422 | { | ||
423 | if (!scenePresence.IsChildAgent) | ||
424 | { | ||
425 | m_log.ErrorFormat("Packet debug for {0} {1} set to {2}", | ||
426 | scenePresence.Firstname, | ||
427 | scenePresence.Lastname, | ||
428 | newDebug); | ||
429 | |||
430 | scenePresence.ControllingClient.SetDebugPacketLevel(newDebug); | ||
431 | } | ||
432 | } | ||
433 | }); | ||
434 | } | ||
435 | |||
436 | public List<ScenePresence> GetCurrentSceneAvatars() | ||
437 | { | ||
438 | List<ScenePresence> avatars = new List<ScenePresence>(); | ||
439 | |||
440 | ForEachCurrentScene(delegate(Scene scene) | ||
441 | { | ||
442 | List<ScenePresence> scenePresences = scene.GetScenePresences(); | ||
443 | |||
444 | foreach (ScenePresence scenePresence in scenePresences) | ||
445 | { | ||
446 | if (!scenePresence.IsChildAgent) | ||
447 | { | ||
448 | avatars.Add(scenePresence); | ||
449 | } | ||
450 | } | ||
451 | }); | ||
452 | |||
453 | return avatars; | ||
454 | } | ||
455 | |||
456 | public List<ScenePresence> GetCurrentScenePresences() | ||
457 | { | ||
458 | List<ScenePresence> presences = new List<ScenePresence>(); | ||
459 | |||
460 | ForEachCurrentScene(delegate(Scene scene) | ||
461 | { | ||
462 | List<ScenePresence> scenePresences = scene.GetScenePresences(); | ||
463 | presences.AddRange(scenePresences); | ||
464 | }); | ||
465 | |||
466 | return presences; | ||
467 | } | ||
468 | |||
469 | public RegionInfo GetRegionInfo(ulong regionHandle) | ||
470 | { | ||
471 | foreach (Scene scene in m_localScenes) | ||
472 | { | ||
473 | if (scene.RegionInfo.RegionHandle == regionHandle) | ||
474 | { | ||
475 | return scene.RegionInfo; | ||
476 | } | ||
477 | } | ||
478 | |||
479 | return null; | ||
480 | } | ||
481 | |||
482 | public void ForceCurrentSceneClientUpdate() | ||
483 | { | ||
484 | ForEachCurrentScene(delegate(Scene scene) { scene.ForceClientUpdate(); }); | ||
485 | } | ||
486 | |||
487 | public void HandleEditCommandOnCurrentScene(string[] cmdparams) | ||
488 | { | ||
489 | ForEachCurrentScene(delegate(Scene scene) { scene.HandleEditCommand(cmdparams); }); | ||
490 | } | ||
491 | |||
492 | public bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) | ||
493 | { | ||
494 | foreach (Scene scene in m_localScenes) | ||
495 | { | ||
496 | if (scene.TryGetAvatar(avatarId, out avatar)) | ||
497 | { | ||
498 | return true; | ||
499 | } | ||
500 | } | ||
501 | |||
502 | avatar = null; | ||
503 | return false; | ||
504 | } | ||
505 | |||
506 | public bool TryGetAvatarsScene(UUID avatarId, out Scene scene) | ||
507 | { | ||
508 | ScenePresence avatar = null; | ||
509 | foreach (Scene mScene in m_localScenes) | ||
510 | { | ||
511 | if (mScene.TryGetAvatar(avatarId, out avatar)) | ||
512 | { | ||
513 | scene = mScene; | ||
514 | return true; | ||
515 | } | ||
516 | } | ||
517 | |||
518 | scene = null; | ||
519 | return false; | ||
520 | } | ||
521 | |||
522 | public void CloseScene(Scene scene) | ||
523 | { | ||
524 | m_localScenes.Remove(scene); | ||
525 | scene.Close(); | ||
526 | } | ||
527 | |||
528 | public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) | ||
529 | { | ||
530 | foreach (Scene scene in m_localScenes) | ||
531 | { | ||
532 | if (scene.TryGetAvatarByName(avatarName, out avatar)) | ||
533 | { | ||
534 | return true; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | avatar = null; | ||
539 | return false; | ||
540 | } | ||
541 | |||
542 | public void ForEachScene(Action<Scene> action) | ||
543 | { | ||
544 | m_localScenes.ForEach(action); | ||
545 | } | ||
546 | |||
547 | public void CacheJ2kDecode(int threads) | ||
548 | { | ||
549 | if (threads < 1) threads = 1; | ||
550 | |||
551 | IJ2KDecoder m_decoder = m_localScenes[0].RequestModuleInterface<IJ2KDecoder>(); | ||
552 | |||
553 | List<UUID> assetRequestList = new List<UUID>(); | ||
554 | |||
555 | #region AssetGathering! | ||
556 | foreach (Scene scene in m_localScenes) | ||
557 | { | ||
558 | List<EntityBase> entitles = scene.GetEntities(); | ||
559 | foreach (EntityBase entity in entitles) | ||
560 | { | ||
561 | if (entity is SceneObjectGroup) | ||
562 | { | ||
563 | SceneObjectGroup sog = (SceneObjectGroup) entity; | ||
564 | foreach (SceneObjectPart part in sog.Children.Values) | ||
565 | { | ||
566 | if (part.Shape != null) | ||
567 | { | ||
568 | if (part.Shape.TextureEntry.Length > 0) | ||
569 | { | ||
570 | OpenMetaverse.Primitive.TextureEntry te = | ||
571 | new Primitive.TextureEntry(part.Shape.TextureEntry, 0, | ||
572 | part.Shape.TextureEntry.Length); | ||
573 | if (te.DefaultTexture != null) // this has been null for some reason... | ||
574 | { | ||
575 | if (te.DefaultTexture.TextureID != UUID.Zero) | ||
576 | assetRequestList.Add(te.DefaultTexture.TextureID); | ||
577 | } | ||
578 | for (int i=0; i<te.FaceTextures.Length; i++) | ||
579 | { | ||
580 | if (te.FaceTextures[i] != null) | ||
581 | { | ||
582 | if (te.FaceTextures[i].TextureID != UUID.Zero) | ||
583 | { | ||
584 | assetRequestList.Add(te.FaceTextures[i].TextureID); | ||
585 | } | ||
586 | } | ||
587 | } | ||
588 | } | ||
589 | if (part.Shape.SculptTexture != UUID.Zero) | ||
590 | { | ||
591 | assetRequestList.Add(part.Shape.SculptTexture); | ||
592 | } | ||
593 | |||
594 | } | ||
595 | } | ||
596 | } | ||
597 | } | ||
598 | } | ||
599 | #endregion | ||
600 | |||
601 | int entries_per_thread = (assetRequestList.Count / threads) + 1; | ||
602 | |||
603 | UUID[] arrAssetRequestList = assetRequestList.ToArray(); | ||
604 | |||
605 | List<UUID[]> arrvalus = new List<UUID[]>(); | ||
606 | |||
607 | //split into separate arrays | ||
608 | for (int j = 0; j < threads; j++) | ||
609 | { | ||
610 | List<UUID> val = new List<UUID>(); | ||
611 | |||
612 | for (int k = j * entries_per_thread; k < ((j + 1) * entries_per_thread); k++) | ||
613 | { | ||
614 | if (k < arrAssetRequestList.Length) | ||
615 | { | ||
616 | val.Add(arrAssetRequestList[k]); | ||
617 | } | ||
618 | |||
619 | } | ||
620 | arrvalus.Add(val.ToArray()); | ||
621 | } | ||
622 | |||
623 | for (int l = 0; l < arrvalus.Count; l++) | ||
624 | { | ||
625 | DecodeThreadContents threadworkItem = new DecodeThreadContents(); | ||
626 | threadworkItem.sn = m_localScenes[0]; | ||
627 | threadworkItem.j2kdecode = m_decoder; | ||
628 | threadworkItem.arrassets = arrvalus[l]; | ||
629 | |||
630 | System.Threading.Thread decodethread = | ||
631 | new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(threadworkItem.run)); | ||
632 | |||
633 | threadworkItem.SetThread(decodethread); | ||
634 | |||
635 | decodethread.Priority = System.Threading.ThreadPriority.Lowest; | ||
636 | decodethread.Name = "J2kCacheDecodeThread_" + l + 1; | ||
637 | ThreadTracker.Add(decodethread); | ||
638 | decodethread.Start(); | ||
639 | |||
640 | } | ||
641 | } | ||
642 | } | ||
643 | |||
644 | public class DecodeThreadContents | ||
645 | { | ||
646 | public Scene sn; | ||
647 | public UUID[] arrassets; | ||
648 | public IJ2KDecoder j2kdecode; | ||
649 | private System.Threading.Thread thisthread; | ||
650 | |||
651 | public void run( object o) | ||
652 | { | ||
653 | for (int i=0;i<arrassets.Length;i++) | ||
654 | { | ||
655 | AssetBase ab = sn.AssetCache.GetAsset(arrassets[i], true); | ||
656 | if (ab != null && ab.Data != null) | ||
657 | { | ||
658 | j2kdecode.syncdecode(arrassets[i], ab.Data); | ||
659 | } | ||
660 | } | ||
661 | ThreadTracker.Remove(thisthread); | ||
662 | } | ||
663 | |||
664 | public void SetThread(System.Threading.Thread thr) | ||
665 | { | ||
666 | thisthread = thr; | ||
667 | } | ||
668 | } | ||
669 | } | ||