OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
AsyncSceneObjectGroupDeleter.cs
Go to the documentation of this file.
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 
28 using System;
29 using System.Collections.Generic;
30 using System.Reflection;
31 using System.Timers;
32 using log4net;
33 using OpenMetaverse;
34 using OpenSim.Framework;
35 using OpenSim.Region.Framework.Interfaces;
36 
37 namespace OpenSim.Region.Framework.Scenes
38 {
40  {
43  public List<SceneObjectGroup> objectGroups;
44  public UUID folderID;
45  public bool permissionToDelete;
46  }
47 
53  {
54  private static readonly ILog m_log
55  = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56 
60  public bool Enabled;
61 
62  private Timer m_inventoryTicker = new Timer(2000);
63  private readonly Queue<DeleteToInventoryHolder> m_inventoryDeletes = new Queue<DeleteToInventoryHolder>();
64  private Scene m_scene;
65 
67  {
68  m_scene = scene;
69 
70  m_inventoryTicker.AutoReset = false;
71  m_inventoryTicker.Elapsed += InventoryRunDeleteTimer;
72  }
73 
77  public void DeleteToInventory(DeRezAction action, UUID folderID,
78  List<SceneObjectGroup> objectGroups, IClientAPI remoteClient,
79  bool permissionToDelete)
80  {
81  if (Enabled)
82  lock (m_inventoryTicker)
83  m_inventoryTicker.Stop();
84 
85  lock (m_inventoryDeletes)
86  {
88  dtis.action = action;
89  dtis.folderID = folderID;
90  dtis.objectGroups = objectGroups;
91  dtis.remoteClient = remoteClient;
92  dtis.permissionToDelete = permissionToDelete;
93 
94  m_inventoryDeletes.Enqueue(dtis);
95  }
96 
97  if (Enabled)
98  lock (m_inventoryTicker)
99  m_inventoryTicker.Start();
100 
101  // Visually remove it, even if it isnt really gone yet. This means that if we crash before the object
102  // has gone to inventory, it will reappear in the region again on restart instead of being lost.
103  // This is not ideal since the object will still be available for manipulation when it should be, but it's
104  // better than losing the object for now.
105  if (permissionToDelete)
106  {
107  foreach (SceneObjectGroup g in objectGroups)
108  g.DeleteGroupFromScene(false);
109  }
110  }
111 
112  private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e)
113  {
114 // m_log.Debug("[ASYNC DELETER]: Starting send to inventory loop");
115 
116  // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
117  // in a culture where decimal points are commas and then reloaded in a culture which just treats them as
118  // number seperators.
119  Culture.SetCurrentCulture();
120 
121  while (InventoryDeQueueAndDelete())
122  {
123  //m_log.Debug("[ASYNC DELETER]: Sent item successfully to inventory, continuing...");
124  }
125  }
126 
132  {
133  DeleteToInventoryHolder x = null;
134 
135  try
136  {
137  lock (m_inventoryDeletes)
138  {
139  int left = m_inventoryDeletes.Count;
140  if (left > 0)
141  {
142  x = m_inventoryDeletes.Dequeue();
143 
144 // m_log.DebugFormat(
145 // "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.",
146 // left, x.action, x.objectGroups.Count);
147 
148  try
149  {
150  IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
151  if (invAccess != null)
152  invAccess.CopyToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient, false);
153 
154  if (x.permissionToDelete)
155  {
156  foreach (SceneObjectGroup g in x.objectGroups)
157  m_scene.DeleteSceneObject(g, true);
158  }
159  }
160  catch (Exception e)
161  {
162  m_log.ErrorFormat(
163  "[ASYNC DELETER]: Exception background sending object: {0}{1}", e.Message, e.StackTrace);
164  }
165 
166  return true;
167  }
168  }
169  }
170  catch (Exception e)
171  {
172  // We can't put the object group details in here since the root part may have disappeared (which is where these sit).
173  // FIXME: This needs to be fixed.
174  m_log.ErrorFormat(
175  "[ASYNC DELETER]: Queued sending of scene object to agent {0} {1} failed: {2} {3}",
176  (x != null ? x.remoteClient.Name : "unavailable"),
177  (x != null ? x.remoteClient.AgentId.ToString() : "unavailable"),
178  e.Message,
179  e.StackTrace);
180  }
181 
182 // m_log.Debug("[ASYNC DELETER]: No objects left in inventory send queue.");
183 
184  return false;
185  }
186  }
187 }
Asynchronously derez objects. This is used to derez large number of objects to inventory without hold...
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
bool InventoryDeQueueAndDelete()
Move the next object in the queue to inventory. Then delete it properly from the scene.
System.Timers.Timer Timer
void DeleteToInventory(DeRezAction action, UUID folderID, List< SceneObjectGroup > objectGroups, IClientAPI remoteClient, bool permissionToDelete)
Delete the given object from the scene