diff options
author | Dr Scofield | 2009-02-06 16:55:34 +0000 |
---|---|---|
committer | Dr Scofield | 2009-02-06 16:55:34 +0000 |
commit | 9b66108081a8c8cf79faaa6c541554091c40850e (patch) | |
tree | 095a232ae5a9de3a9244bcd34da08294f61eeea5 /OpenSim/Region/Framework/Scenes/SceneManager.cs | |
parent | * removed superfluous constants class (diff) | |
download | opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.zip opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.tar.gz opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.tar.bz2 opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.tar.xz |
This changeset is the step 1 of 2 in refactoring
OpenSim.Region.Environment into a "framework" part and a modules only
part. This first changeset refactors OpenSim.Region.Environment.Scenes,
OpenSim.Region.Environment.Interfaces, and OpenSim.Region.Interfaces
into OpenSim.Region.Framework.{Interfaces,Scenes} leaving only region
modules in OpenSim.Region.Environment.
The next step will be to move region modules up from
OpenSim.Region.Environment.Modules to OpenSim.Region.CoreModules and
then sort out which modules are really core modules and which should
move out to forge.
I've been very careful to NOT BREAK anything. i hope i've
succeeded. as this is the work of a whole week i hope i managed to
keep track with the applied patches of the last week --- could any of
you that did check in stuff have a look at whether it survived? thx!
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 | } | ||