aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs684
1 files changed, 684 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs
new file mode 100644
index 0000000..465741f
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs
@@ -0,0 +1,684 @@
1// CMController.cs
2// User: bongiojp
3//
4
5using System;
6using System.Collections.Generic;
7using System.Collections;
8using libsecondlife;
9using OpenSim;
10using OpenSim.Framework;
11using OpenSim.Region.Environment.Interfaces;
12using OpenSim.Region.Environment.Scenes;
13using log4net;
14using OpenSim.Region.Physics.Manager;
15using Axiom.Math;
16using System.Threading;
17using System.Diagnostics;
18
19namespace OpenSim.Region.Environment.Modules.ContentManagement
20{
21
22 /// <summary>
23 /// The controller in a Model-View-Controller framework. This controller catches actions by the avatars, creates work packets, loops through these work packets in a separate thread,
24 /// then dictates to the model how the data should change and dictates to the view which data should be displayed. The main mechanism for interaction is through the simchat system.
25 /// </summary>
26 public class CMController
27 {
28
29 /// <value>
30 /// The structure that defines the basic unit of work which is produced when a user sends commands to the ContentMangaementSystem.
31 /// </value>
32 private struct Work
33 {
34 public WorkType Type;
35 public Object Data1; //Just space for holding data.
36 public Object Data2; //Just more space for holding data.
37 public uint LocalId; //Convenient
38 public LLUUID UUID; //Convenient
39 }
40
41 /// <value>
42 /// Identifies what the data in struct Work should be used for.
43 /// </value>
44 private enum WorkType
45 {
46 NONE,
47 OBJECTATTRIBUTECHANGE,
48 PRIMITIVEADDED,
49 OBJECTDUPLICATED,
50 OBJECTKILLED,
51 UNDODID,
52 NEWCLIENT,
53 SIMCHAT
54 }
55
56 /// <value>
57 /// Used to keep track of whether a list has been produced yet and whether that list is up-to-date compard to latest revision on disk.
58 /// </value>
59 [Flags]
60 private enum State
61 {
62 NONE = 0,
63 DIRTY = 1, // The meta entities may not correctly represent the last revision.
64 SHOWING_CHANGES = 1<<1 // The meta entities are being shown to user.
65 }
66
67 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
68
69 /// <value>
70 /// The queue that keeps track of which actions have happened. The MainLoop thread eats through this queue.
71 /// </value>
72 private static OpenSim.Framework.BlockingQueue<Work> m_WorkQueue = new OpenSim.Framework.BlockingQueue<Work>();
73
74 /// <value>
75 /// A list of all the scenes that should be revisioned. Controller is the only class that keeps track of all scenes in the region.
76 /// </value>
77 Hashtable m_sceneList = Hashtable.Synchronized(new Hashtable());
78
79 /// <value>
80 /// The estate module is used to identify which clients are estateManagers. Presently, the controller only pays attention to estate managers.
81 /// </value>
82 IEstateModule m_estateModule = null;
83
84 Thread m_thread = null;
85 State m_state = State.NONE;
86 bool init = false;
87
88 //These have to be global variables, threading doesn't allow for passing parameters. (Used in MainLoop)
89 CMModel m_model = null;
90 CMView m_view = null;
91 int m_channel = -1;
92
93 /// <summary>
94 /// Initializes a work thread with an initial scene. Additional scenes should be added through the RegisterNewRegion method.
95 /// </summary>
96 /// <param name="model">
97 /// <see cref="CMModel"/>
98 /// </param>
99 /// <param name="view">
100 /// <see cref="CMView"/>
101 /// </param>
102 /// <param name="scene">
103 /// The first scene to keep track of. <see cref="Scene"/>
104 /// </param>
105 /// <param name="channel">
106 /// The simchat channel number to listen to for instructions <see cref="System.Int32"/>
107 /// </param>
108 public CMController(CMModel model, CMView view, Scene scene, int channel)
109 {
110 m_model = model; m_view = view; m_channel = channel;
111 RegisterNewRegion(scene);
112 Initialize(model, view, scene, channel);
113 }
114
115 private void Initialize(CMModel model, CMView view, Scene scene, int channel)
116 {
117 lock(this)
118 {
119 m_estateModule = scene.RequestModuleInterface<IEstateModule>();
120 m_thread = new Thread( MainLoop );
121 m_thread.Name = "Content Management";
122 m_thread.IsBackground = true;
123 m_thread.Start();
124 ThreadTracker.Add(m_thread);
125 m_state = State.NONE;
126 }
127 }
128
129 /// <summary>
130 /// Register a new scene object to keep track of for revisioning. Starts the controller monitoring actions of clients within the given scene.
131 /// </summary>
132 /// <param name="scene">
133 /// A <see cref="Scene"/>
134 /// </param>
135 public void RegisterNewRegion(Scene scene)
136 {
137 m_sceneList.Add(scene.RegionInfo.RegionID, scene);
138
139 m_log.Debug("[CONTENT MANAGEMENT] Registering new region: " + scene.RegionInfo.RegionID);
140 m_log.Debug("[CONTENT MANAGEMENT] Initializing Content Management System.");
141
142 scene.EventManager.OnNewClient += StartManaging;
143 scene.EventManager.OnRemovePresence += StopManaging;
144 // scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
145 scene.EventManager.OnObjectBeingRemovedFromScene += GroupBeingDeleted;
146 }
147
148 /// <summary>
149 /// Run in a thread of its own. A endless loop that consumes (or blocks on) and work queue. Thw work queue is filled through client actions.
150 /// </summary>
151 private void MainLoop()
152 {
153 CMModel model = m_model; CMView view = m_view; int channel = m_channel;
154 Work currentJob = new Work();
155 while(true)
156 {
157 currentJob = m_WorkQueue.Dequeue();
158 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- DeQueued a request");
159 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Work type: " + currentJob.Type);
160 switch(currentJob.Type)
161 {
162 case WorkType.NONE:
163 break;
164 case WorkType.OBJECTATTRIBUTECHANGE:
165 ObjectAttributeChanged(model, view, currentJob.LocalId);
166 break;
167 case WorkType.PRIMITIVEADDED:
168 PrimitiveAdded(model, view, currentJob);
169 break;
170 case WorkType.OBJECTDUPLICATED:
171 ObjectDuplicated(model, view, currentJob.LocalId);
172 break;
173 case WorkType.OBJECTKILLED:
174 ObjectKilled(model, view, (SceneObjectGroup) currentJob.Data1);
175 break;
176 case WorkType.UNDODID:
177 UndoDid(model, view, currentJob.UUID);
178 break;
179 case WorkType.NEWCLIENT:
180 NewClient(view, (IClientAPI) currentJob.Data1);
181 break;
182 case WorkType.SIMCHAT:
183 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Message received: " + ((ChatFromViewerArgs) currentJob.Data1).Message);
184 SimChat(model, view, (ChatFromViewerArgs) currentJob.Data1, channel);
185 break;
186 default:
187 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- uuuuuuuuuh, what?");
188 break;
189 }
190 }
191 }
192
193 /// <summary>
194 /// Only called by the MainLoop. Updates the view of a new client with metaentities if diff-mode is currently enabled.
195 /// </summary>
196 private void NewClient(CMView view, IClientAPI client)
197 {
198 if ((m_state & State.SHOWING_CHANGES) > 0)
199 view.SendMetaEntitiesToNewClient(client);
200 }
201
202 /// <summary>
203 /// Only called by the MainLoop. Displays new green auras over the newly created part when a part is shift copied.
204 /// </summary>
205 private void ObjectDuplicated(CMModel model, CMView view, uint localId)
206 {
207 if ((m_state & State.SHOWING_CHANGES) > 0)
208 view.DisplayAuras(model.CheckForNewEntitiesMissingAuras( GetGroupByPrim(localId).Scene ));
209 }
210
211 /// <summary>
212 /// Only called by the MainLoop.
213 /// </summary>
214 private void ObjectKilled(CMModel model, CMView view, SceneObjectGroup group)
215 {
216 if ((m_state & State.SHOWING_CHANGES) > 0)
217 {
218 view.RemoveOrUpdateDeletedEntity(group);
219 model.RemoveOrUpdateDeletedEntity(group);
220 }
221 }
222
223 /// <summary>
224 /// Only called by the MainLoop.
225 /// </summary>
226 private void UndoDid(CMModel model, CMView view, LLUUID uuid)
227 {
228 if ((m_state & State.SHOWING_CHANGES) > 0)
229 {
230 ContentManagementEntity ent = model.FindMetaEntityAffectedByUndo(uuid);
231 if (ent != null)
232 view.DisplayEntity(ent);
233 }
234 }
235
236 /// <summary>
237 /// Only called by the MainLoop.
238 /// </summary>
239 private void ObjectAttributeChanged(CMModel model, CMView view, uint LocalId)
240 {
241 SceneObjectGroup group = null;
242 if ((m_state & State.SHOWING_CHANGES) > 0)
243 {
244 group = GetGroupByPrim(LocalId);
245 if (group != null)
246 {
247 view.DisplayAuras( model.UpdateNormalEntityEffects(group) ); //Might be a normal entity (green aura)
248 m_view.DisplayMetaEntity(group.UUID); //Might be a meta entity (blue aura)
249 }
250 }
251 }
252
253 /// <summary>
254 /// Only called by the MainLoop.
255 /// </summary>
256 private void PrimitiveAdded(CMModel model, CMView view, Work currentJob)
257 {
258 if ((m_state & State.SHOWING_CHANGES) > 0)
259 {
260 foreach(Object scene in m_sceneList.Values)
261 m_view.DisplayAuras(model.CheckForNewEntitiesMissingAuras((Scene) scene));
262 }
263 }
264
265 /// <summary>
266 /// Only called by the MainLoop. Takes the message from a user sent to the channel and executes the proper command.
267 /// </summary>
268 public void SimChat(CMModel model, CMView view, ChatFromViewerArgs e, int channel)
269 {
270 if (e.Channel != channel)
271 return;
272 if (e.Sender == null)
273 return;
274
275 m_log.Debug("[CONTENT MANAGEMENT] Message received: " + e.Message);
276
277 IClientAPI client = e.Sender;
278 Scene scene = (Scene) e.Scene;
279 string message = e.Message;
280 string[] args = e.Message.Split(new char[] {' '});
281
282 ScenePresence avatar = scene.GetScenePresence(client.AgentId);
283
284 if (!(m_estateModule.IsManager(avatar.UUID)))
285 {
286 m_log.Debug("[CONTENT MANAGEMENT] Message sent from non Estate Manager ... ignoring.");
287 view.SendSimChatMessage(scene, "You must be an estate manager to perform that action.");
288 return;
289 }
290
291 switch(args[0])
292 {
293 case "ci":
294 case "commit":
295 commit(message, scene, model, view);
296 break;
297 case "dm":
298 case "diff-mode":
299 diffmode(scene, model, view);
300 break;
301 case "rb":
302 case "rollback":
303 rollback(scene, model, view);
304 break;
305 case "help":
306 m_view.DisplayHelpMenu(scene);
307 break;
308 default:
309 view.SendSimChatMessage(scene, "Command not found: " + args[0]);
310 break;
311 }
312 }
313
314 /// <summary>
315 /// Only called from within the SimChat method. Hides all auras and meta entities,
316 /// retrieves the current scene object list with the most recent revision retrieved from the model for each scene,
317 /// then lets the view update the clients of the new objects.
318 /// </summary>
319 protected void rollback(Scene scene, CMModel model, CMView view)
320 {
321 if ((m_state & State.SHOWING_CHANGES) > 0)
322 {
323 view.HideAllAuras();
324 view.HideAllMetaEntities();
325 }
326
327 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene);
328 foreach(Scene currScene in proximitySceneList)
329 model.RollbackRegion(currScene);
330
331 if ((m_state & State.DIRTY) != 0 )
332 {
333 model.DeleteAllMetaObjects();
334 foreach(Scene currScene in proximitySceneList)
335 model.UpdateCMEntities(currScene);
336 }
337
338 if ((m_state & State.SHOWING_CHANGES) > 0)
339 view.DisplayRecentChanges();
340
341 }
342
343 /// <summary>
344 /// Only called from within the SimChat method.
345 /// </summary>
346 protected void diffmode(Scene scene, CMModel model, CMView view)
347 {
348 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene);
349
350 if ((m_state & State.SHOWING_CHANGES) > 0) // TURN OFF
351 {
352 view.SendSimChatMessage(scene, "Hiding all meta objects.");
353 view.HideAllMetaEntities();
354 view.HideAllAuras();
355 view.SendSimChatMessage(scene, "Diff-mode = OFF");
356
357 m_state &= ~State.SHOWING_CHANGES;
358 return;
359 }
360 else // TURN ON
361 {
362 if ((m_state & State.DIRTY) != 0 || m_state == State.NONE)
363 {
364 view.SendSimChatMessage(scene, "Hiding meta objects and replacing with latest revision");
365 //Hide objects from users and Forget about them
366 view.HideAllMetaEntities();
367 view.HideAllAuras();
368 model.DeleteAllMetaObjects();
369 //Recreate them from backend files
370 foreach(Object currScene in m_sceneList.Values)
371 model.UpdateCMEntities((Scene) currScene);
372 }
373 else if ((m_state & State.DIRTY) != 0) {
374 view.SendSimChatMessage(scene, "Forming list of meta entities with latest revision");
375 foreach(Scene currScene in proximitySceneList)
376 model.UpdateCMEntities(currScene);
377 }
378
379 view.SendSimChatMessage(scene, "Displaying differences between last revision and current environment");
380 foreach(Scene currScene in proximitySceneList)
381 model.CheckForNewEntitiesMissingAuras(currScene);
382 view.DisplayRecentChanges();
383
384 view.SendSimChatMessage(scene, "Diff-mode = ON");
385 m_state |= State.SHOWING_CHANGES;
386 m_state &= ~State.DIRTY;
387 }
388 }
389
390 /// <summary>
391 /// Only called from within the SimChat method.
392 /// </summary>
393 protected void commit(string message, Scene scene, CMModel model, CMView view)
394 {
395 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene);
396
397 string[] args = message.Split(new char[] {' '});
398
399 char[] logMessage = {' '};
400 if (args.Length > 1)
401 {
402 logMessage = new char[message.Length - (args[0].Length)];
403 message.CopyTo(args[0].Length, logMessage, 0, message.Length - (args[0].Length));
404 }
405
406 m_log.Debug("[CONTENT MANAGEMENT] Saving terrain and objects of region.");
407 foreach(Scene currScene in proximitySceneList)
408 {
409 model.CommitRegion(currScene, new String(logMessage));
410 view.SendSimChatMessage(scene, "Region Saved Successfully: " + currScene.RegionInfo.RegionName);
411 }
412
413 view.SendSimChatMessage(scene, "Successfully saved all regions.");
414 m_state |= State.DIRTY;
415
416 if ((m_state & State.SHOWING_CHANGES) > 0) //DISPLAY NEW CHANGES INSTEAD OF OLD CHANGES
417 {
418 view.SendSimChatMessage(scene, "Updating differences between new revision and current environment.");
419 //Hide objects from users and Forget about them
420 view.HideAllMetaEntities();
421 view.HideAllAuras();
422 model.DeleteAllMetaObjects();
423
424 //Recreate them from backend files
425 foreach(Scene currScene in proximitySceneList)
426 {
427 model.UpdateCMEntities(currScene);
428 view.SendSimChatMessage(scene, "Finished updating differences between current scene and last revision: " + currScene.RegionInfo.RegionName);
429 }
430
431 //Display new objects to users1
432 view.DisplayRecentChanges();
433 view.SendSimChatMessage(scene, "Finished updating for DIFF-MODE.");
434 m_state &= ~(State.DIRTY);
435 m_state |= State.SHOWING_CHANGES;
436 }
437 }
438
439 /// <summary>
440 /// Takes a list of scenes and forms a new orderd list according to the proximity of scenes to the second argument.
441 /// </summary>
442 protected static System.Collections.Generic.List<Scene> ScenesInOrderOfProximity( Hashtable sceneList, Scene scene)
443 {
444 int somethingAddedToList = 1;
445 System.Collections.Generic.List<Scene> newList = new List<Scene>();
446 newList.Add(scene);
447
448 if (! sceneList.ContainsValue(scene))
449 {
450 foreach(Object sceneObj in sceneList)
451 newList.Add((Scene) sceneObj);
452 return newList;
453 }
454
455 while(somethingAddedToList > 0)
456 {
457 somethingAddedToList = 0;
458 for(int i = 0; i < newList.Count; i++)
459 {
460 foreach(Object sceneObj in sceneList.Values)
461 {
462 if (newList[i].CheckNeighborRegion(((Scene)sceneObj).RegionInfo) && (! newList.Contains((Scene)sceneObj)) )
463 {
464 newList.Add((Scene)sceneObj);
465 somethingAddedToList++;
466 }
467 }
468 }
469 }
470
471 foreach(Object sceneObj in sceneList.Values)
472 if (! newList.Contains((Scene)sceneObj))
473 newList.Add((Scene)sceneObj);
474
475 return newList;
476 }
477
478 /// <summary>
479 /// Searches in all scenes for a SceneObjectGroup that contains a part with a specific localID. If found, the object is returned. Else null is returned.
480 /// </summary>
481 private SceneObjectGroup GetGroupByPrim(uint localID)
482 {
483 foreach(Object currScene in m_sceneList.Values)
484 {
485 foreach (EntityBase ent in ((Scene)currScene).GetEntities())
486 {
487 if (ent is SceneObjectGroup)
488 {
489 if (((SceneObjectGroup)ent).HasChildPrim(localID))
490 return (SceneObjectGroup)ent;
491 }
492 }
493 }
494 return null;
495 }
496 //------------------------------------------------ EVENTS ----------------------------------------------------//
497
498 private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
499 {
500 }
501
502 /// <summary>
503 /// Adds extra handlers to a number of events so that the controller can produce work based on the client's actions.
504 /// </summary>
505 protected void StartManaging(IClientAPI client)
506 {
507 m_log.Debug("[CONTENT MANAGEMENT] Registering channel with chat services.");
508 client.OnChatFromViewer += SimChatSent;
509 init = true;
510
511 OnNewClient(client);
512
513 m_log.Debug("[CONTENT MANAGEMENT] Adding handlers to client.");
514 client.OnUpdatePrimScale += UpdateSingleScale;
515 client.OnUpdatePrimGroupScale += UpdateMultipleScale;
516 client.OnUpdatePrimGroupPosition += UpdateMultiplePosition;
517 client.OnUpdatePrimSinglePosition += UpdateSinglePosition;
518 client.OnUpdatePrimGroupRotation += UpdateMultipleRotation;
519 client.OnUpdatePrimSingleRotation += UpdateSingleRotation;
520 client.OnAddPrim += UpdateNewParts;
521 client.OnObjectDuplicate += ObjectDuplicated;
522 client.OnObjectDuplicateOnRay += ObjectDuplicatedOnRay;
523 client.OnUndo += OnUnDid;
524 //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
525 }
526
527 /// <summary>
528 ///
529 /// </summary>
530 protected void StopManaging(LLUUID clientUUID)
531 {
532 foreach(Object sceneobj in m_sceneList.Values)
533 {
534 ScenePresence presence = ((Scene)sceneobj).GetScenePresence(clientUUID);
535 if (presence != null)
536 {
537 IClientAPI client = presence.ControllingClient;
538 m_log.Debug("[CONTENT MANAGEMENT] Unregistering channel with chat services.");
539 client.OnChatFromViewer -= SimChatSent;
540
541 m_log.Debug("[CONTENT MANAGEMENT] Removing handlers to client");
542 client.OnUpdatePrimScale -= UpdateSingleScale;
543 client.OnUpdatePrimGroupScale -= UpdateMultipleScale;
544 client.OnUpdatePrimGroupPosition -= UpdateMultiplePosition;
545 client.OnUpdatePrimSinglePosition -= UpdateSinglePosition;
546 client.OnUpdatePrimGroupRotation -= UpdateMultipleRotation;
547 client.OnUpdatePrimSingleRotation -= UpdateSingleRotation;
548 client.OnAddPrim -= UpdateNewParts;
549 client.OnObjectDuplicate -= ObjectDuplicated;
550 client.OnObjectDuplicateOnRay -= ObjectDuplicatedOnRay;
551 client.OnUndo -= OnUnDid;
552 //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
553 return;
554 }
555 }
556 }
557
558 protected void GroupBeingDeleted(SceneObjectGroup group)
559 {
560 m_log.Debug("[CONTENT MANAGEMENT] Something was deleted!!!");
561 Work moreWork = new Work();
562 moreWork.Type = WorkType.OBJECTKILLED;
563 moreWork.Data1 = group.Copy();
564 m_WorkQueue.Enqueue(moreWork);
565 }
566
567 //This is stupid, the same information is contained in the first and second argument
568 protected void SimChatSent(Object x, ChatFromViewerArgs e)
569 {
570 m_log.Debug("[CONTENT MANAGEMENT] SIMCHAT SENT !!!!!!!");
571 m_log.Debug("[CONTENT MANAGEMENT] message was: " + e.Message);
572 Work moreWork = new Work();
573 moreWork.Type = WorkType.SIMCHAT;
574 moreWork.Data1 = e;
575 m_WorkQueue.Enqueue(moreWork);
576 }
577
578 protected void ObjectDuplicated(uint localID, LLVector3 offset, uint dupeFlags, LLUUID AgentID, LLUUID GroupID)
579 {
580 Work moreWork = new Work();
581 moreWork.Type = WorkType.OBJECTDUPLICATED;
582 moreWork.LocalId = localID;
583 m_WorkQueue.Enqueue(moreWork);
584 m_log.Debug("[CONTENT MANAGEMENT] dup queue");
585 }
586
587 protected void ObjectDuplicatedOnRay(uint localID, uint dupeFlags, LLUUID AgentID, LLUUID GroupID,
588 LLUUID RayTargetObj, LLVector3 RayEnd, LLVector3 RayStart,
589 bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
590 {
591 Work moreWork = new Work();
592 moreWork.Type = WorkType.OBJECTDUPLICATED;
593 moreWork.LocalId = localID;
594 m_WorkQueue.Enqueue(moreWork);
595 m_log.Debug("[CONTENT MANAGEMENT] dup queue");
596 }
597
598 protected void OnNewClient(IClientAPI client)
599 {
600 Work moreWork = new Work();
601 moreWork.Type = WorkType.NEWCLIENT;
602 moreWork.Data1 = client;
603 m_WorkQueue.Enqueue(moreWork);
604 m_log.Debug("[CONTENT MANAGEMENT] new client");
605 }
606
607 protected void OnUnDid(IClientAPI remoteClient, LLUUID primId)
608 {
609 Work moreWork = new Work();
610 moreWork.Type = WorkType.UNDODID;
611 moreWork.UUID = primId;
612 m_WorkQueue.Enqueue(moreWork);
613 m_log.Debug("[CONTENT MANAGEMENT] undid");
614 }
615
616 protected void UpdateSinglePosition(uint localID, LLVector3 pos, IClientAPI remoteClient)
617 {
618 Work moreWork = new Work();
619 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
620 moreWork.LocalId = localID;
621 m_WorkQueue.Enqueue(moreWork);
622 m_log.Debug("[CONTENT MANAGEMENT] move");
623 }
624
625 /// <summary>
626 ///
627 /// </summary>
628 protected void UpdateSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient)
629 {
630 Work moreWork = new Work();
631 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
632 moreWork.LocalId = localID;
633 m_WorkQueue.Enqueue(moreWork);
634 m_log.Debug("[CONTENT MANAGEMENT] rot");
635 }
636
637 protected void UpdateSingleScale(uint localID, LLVector3 scale, IClientAPI remoteClient)
638 {
639 Work moreWork = new Work();
640 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
641 moreWork.LocalId = localID;
642 m_WorkQueue.Enqueue(moreWork);
643 m_log.Debug("[CONTENT MANAGEMENT] scale");
644 }
645
646 protected void UpdateMultiplePosition(uint localID, LLVector3 pos, IClientAPI remoteClient)
647 {
648 Work moreWork = new Work();
649 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
650 moreWork.LocalId = localID;
651 m_WorkQueue.Enqueue(moreWork);
652 m_log.Debug("[CONTENT MANAGEMENT] pos");
653 }
654
655 protected void UpdateMultipleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient)
656 {
657 Work moreWork = new Work();
658 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
659 moreWork.LocalId = localID;
660 m_WorkQueue.Enqueue(moreWork);
661 m_log.Debug("[CONTENT MANAGEMENT] rot");
662 }
663
664 protected void UpdateMultipleScale(uint localID, LLVector3 scale, IClientAPI remoteClient)
665 {
666 Work moreWork = new Work();
667 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
668 moreWork.LocalId = localID;
669 m_WorkQueue.Enqueue(moreWork);
670 m_log.Debug("[CONTENT MANAGEMENT]scale");
671 }
672
673 protected void UpdateNewParts(LLUUID ownerID, LLVector3 RayEnd, LLQuaternion rot, PrimitiveBaseShape shape,
674 byte bypassRaycast, LLVector3 RayStart, LLUUID RayTargetID,
675 byte RayEndIsIntersection)
676 {
677 Work moreWork = new Work();
678 moreWork.Type = WorkType.PRIMITIVEADDED;
679 moreWork.UUID = ownerID;
680 m_WorkQueue.Enqueue(moreWork);
681 m_log.Debug("[CONTENT MANAGEMENT] new parts");
682 }
683 }
684}