First pass at cleaning up thread safety in EntityManager and SceneGraph

viewer-2-initial-appearance
John Hurliman 2010-09-10 12:04:12 -07:00
parent 9609faa8eb
commit dd277a0d02
25 changed files with 252 additions and 395 deletions

View File

@ -40,15 +40,4 @@ namespace OpenSim.Data
void Initialise(string connect); void Initialise(string connect);
bool Delete(string id); bool Delete(string id);
} }
public class AssetDataInitialiser : PluginInitialiserBase
{
private string connect;
public AssetDataInitialiser (string s) { connect = s; }
public override void Initialise (IPlugin plugin)
{
IAssetDataPlugin p = plugin as IAssetDataPlugin;
p.Initialise (connect);
}
}
} }

View File

@ -155,15 +155,4 @@ namespace OpenSim.Data
/// </returns> /// </returns>
List<InventoryItemBase> fetchActiveGestures(UUID avatarID); List<InventoryItemBase> fetchActiveGestures(UUID avatarID);
} }
public class InventoryDataInitialiser : PluginInitialiserBase
{
private string connect;
public InventoryDataInitialiser (string s) { connect = s; }
public override void Initialise (IPlugin plugin)
{
IInventoryDataPlugin p = plugin as IInventoryDataPlugin;
p.Initialise (connect);
}
}
} }

View File

@ -436,7 +436,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// We can NOT use the dictionries here, as we are looking // We can NOT use the dictionries here, as we are looking
// for an entity by the fromAssetID, which is NOT the prim UUID // for an entity by the fromAssetID, which is NOT the prim UUID
List<EntityBase> detachEntities = m_scene.GetEntities(); EntityBase[] detachEntities = m_scene.GetEntities();
SceneObjectGroup group; SceneObjectGroup group;
foreach (EntityBase entity in detachEntities) foreach (EntityBase entity in detachEntities)

View File

@ -102,7 +102,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
{ {
Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>(); Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
List<EntityBase> entities = m_scene.GetEntities(); EntityBase[] entities = m_scene.GetEntities();
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
/* /*

View File

@ -794,7 +794,8 @@ namespace OpenSim.Region.CoreModules.World.Land
public void EventManagerOnParcelPrimCountUpdate() public void EventManagerOnParcelPrimCountUpdate()
{ {
ResetAllLandPrimCounts(); ResetAllLandPrimCounts();
foreach (EntityBase obj in m_scene.Entities) EntityBase[] entities = m_scene.Entities.GetEntities();
foreach (EntityBase obj in entities)
{ {
if (obj != null) if (obj != null)
{ {

View File

@ -80,7 +80,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser
{ {
string xmlstream = "<scene>"; string xmlstream = "<scene>";
List<EntityBase> EntityList = scene.GetEntities(); EntityBase[] EntityList = scene.GetEntities();
List<string> EntityXml = new List<string>(); List<string> EntityXml = new List<string>();
foreach (EntityBase ent in EntityList) foreach (EntityBase ent in EntityList)

View File

@ -165,12 +165,12 @@ namespace OpenSim.Region.CoreModules.World.Serialiser
return SceneXmlLoader.SaveGroupToXml2(grp); return SceneXmlLoader.SaveGroupToXml2(grp);
} }
public void SavePrimListToXml2(List<EntityBase> entityList, string fileName) public void SavePrimListToXml2(EntityBase[] entityList, string fileName)
{ {
SceneXmlLoader.SavePrimListToXml2(entityList, fileName); SceneXmlLoader.SavePrimListToXml2(entityList, fileName);
} }
public void SavePrimListToXml2(List<EntityBase> entityList, TextWriter stream, Vector3 min, Vector3 max) public void SavePrimListToXml2(EntityBase[] entityList, TextWriter stream, Vector3 min, Vector3 max)
{ {
SceneXmlLoader.SavePrimListToXml2(entityList, stream, min, max); SceneXmlLoader.SavePrimListToXml2(entityList, stream, min, max);
} }

View File

@ -212,7 +212,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
double[,] hm = whichScene.Heightmap.GetDoubles(); double[,] hm = whichScene.Heightmap.GetDoubles();
tc = Environment.TickCount; tc = Environment.TickCount;
m_log.Info("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); m_log.Info("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile");
List<EntityBase> objs = whichScene.GetEntities(); EntityBase[] objs = whichScene.GetEntities();
Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>(); Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>();
//SortedList<float, RectangleDrawStruct> z_sort = new SortedList<float, RectangleDrawStruct>(); //SortedList<float, RectangleDrawStruct> z_sort = new SortedList<float, RectangleDrawStruct>();
List<float> z_sortheights = new List<float>(); List<float> z_sortheights = new List<float>();

View File

@ -101,7 +101,8 @@ namespace OpenSim.Region.DataSnapshot.Providers
XmlNode parent = nodeFactory.CreateNode(XmlNodeType.Element, "objectdata", ""); XmlNode parent = nodeFactory.CreateNode(XmlNodeType.Element, "objectdata", "");
XmlNode node; XmlNode node;
foreach (EntityBase entity in m_scene.Entities) EntityBase[] entities = m_scene.Entities.GetEntities();
foreach (EntityBase entity in entities)
{ {
// only objects, not avatars // only objects, not avatars
if (entity is SceneObjectGroup) if (entity is SceneObjectGroup)

View File

@ -90,7 +90,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// </summary> /// </summary>
/// <param name="entityList"></param> /// <param name="entityList"></param>
/// <param name="fileName"></param> /// <param name="fileName"></param>
void SavePrimListToXml2(List<EntityBase> entityList, string fileName); void SavePrimListToXml2(EntityBase[] entityList, string fileName);
/// <summary> /// <summary>
/// Save a set of prims in the xml2 format, optionally specifying a bounding box for which /// Save a set of prims in the xml2 format, optionally specifying a bounding box for which
@ -101,7 +101,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="stream"></param> /// <param name="stream"></param>
/// <param name="min"></param> /// <param name="min"></param>
/// <param name="max"></param> /// <param name="max"></param>
void SavePrimListToXml2(List<EntityBase> entityList, TextWriter stream, Vector3 min, Vector3 max); void SavePrimListToXml2(EntityBase[] entityList, TextWriter stream, Vector3 min, Vector3 max);
void SaveNamedPrimsToXml2(Scene scene, string primName, string fileName); void SaveNamedPrimsToXml2(Scene scene, string primName, string fileName);

View File

@ -34,187 +34,89 @@ using OpenMetaverse;
namespace OpenSim.Region.Framework.Scenes namespace OpenSim.Region.Framework.Scenes
{ {
public class EntityManager : IEnumerable<EntityBase> public class EntityManager //: IEnumerable<EntityBase>
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>(); private readonly DoubleDictionary<UUID, uint, EntityBase> m_entities = new DoubleDictionary<UUID, uint, EntityBase>();
private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>();
//private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>();
private readonly Object m_lock = new Object();
[Obsolete("Use Add() instead.")] public int Count
public void Add(UUID id, EntityBase eb)
{ {
Add(eb); get { return m_entities.Count; }
} }
public void Add(EntityBase entity) public void Add(EntityBase entity)
{ {
lock (m_lock) m_entities.Add(entity.UUID, entity.LocalId, entity);
{
try
{
m_eb_uuid.Add(entity.UUID, entity);
m_eb_localID.Add(entity.LocalId, entity);
}
catch(Exception e)
{
m_log.ErrorFormat("Add Entity failed: {0}", e.Message);
}
}
}
public void InsertOrReplace(EntityBase entity)
{
lock (m_lock)
{
try
{
m_eb_uuid[entity.UUID] = entity;
m_eb_localID[entity.LocalId] = entity;
}
catch(Exception e)
{
m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message);
}
}
} }
public void Clear() public void Clear()
{ {
lock (m_lock) m_entities.Clear();
{
m_eb_uuid.Clear();
m_eb_localID.Clear();
}
}
public int Count
{
get
{
return m_eb_uuid.Count;
}
} }
public bool ContainsKey(UUID id) public bool ContainsKey(UUID id)
{ {
try return m_entities.ContainsKey(id);
{
return m_eb_uuid.ContainsKey(id);
}
catch
{
return false;
}
} }
public bool ContainsKey(uint localID) public bool ContainsKey(uint localID)
{ {
try return m_entities.ContainsKey(localID);
{
return m_eb_localID.ContainsKey(localID);
}
catch
{
return false;
}
} }
public bool Remove(uint localID) public bool Remove(uint localID)
{ {
lock (m_lock) return m_entities.Remove(localID);
{
try
{
bool a = false;
EntityBase entity;
if (m_eb_localID.TryGetValue(localID, out entity))
a = m_eb_uuid.Remove(entity.UUID);
bool b = m_eb_localID.Remove(localID);
return a && b;
}
catch (Exception e)
{
m_log.ErrorFormat("Remove Entity failed for {0}", localID, e);
return false;
}
}
} }
public bool Remove(UUID id) public bool Remove(UUID id)
{ {
lock (m_lock) return m_entities.Remove(id);
{
try
{
bool a = false;
EntityBase entity;
if (m_eb_uuid.TryGetValue(id, out entity))
a = m_eb_localID.Remove(entity.LocalId);
bool b = m_eb_uuid.Remove(id);
return a && b;
}
catch (Exception e)
{
m_log.ErrorFormat("Remove Entity failed for {0}", id, e);
return false;
}
}
} }
public List<EntityBase> GetAllByType<T>() public EntityBase[] GetAllByType<T>()
{ {
List<EntityBase> tmp = new List<EntityBase>(); List<EntityBase> tmp = new List<EntityBase>();
lock (m_lock) m_entities.ForEach(
{ delegate(EntityBase entity)
try
{ {
foreach (KeyValuePair<UUID, EntityBase> pair in m_eb_uuid) if (entity is T)
{ tmp.Add(entity);
if (pair.Value is T)
{
tmp.Add(pair.Value);
}
}
} }
catch (Exception e) );
{
m_log.ErrorFormat("GetAllByType failed for {0}", e);
tmp = null;
}
}
return tmp; return tmp.ToArray();
} }
public List<EntityBase> GetEntities() public EntityBase[] GetEntities()
{ {
lock (m_lock) List<EntityBase> tmp = new List<EntityBase>(m_entities.Count);
{ m_entities.ForEach(delegate(EntityBase entity) { tmp.Add(entity); });
return new List<EntityBase>(m_eb_uuid.Values); return tmp.ToArray();
} }
public void ForEach(Action<EntityBase> action)
{
m_entities.ForEach(action);
}
public EntityBase Find(Predicate<EntityBase> predicate)
{
return m_entities.FindValue(predicate);
} }
public EntityBase this[UUID id] public EntityBase this[UUID id]
{ {
get get
{ {
lock (m_lock) EntityBase entity;
{ m_entities.TryGetValue(id, out entity);
EntityBase entity; return entity;
if (m_eb_uuid.TryGetValue(id, out entity))
return entity;
else
return null;
}
} }
set set
{ {
InsertOrReplace(value); Add(value);
} }
} }
@ -222,50 +124,38 @@ namespace OpenSim.Region.Framework.Scenes
{ {
get get
{ {
lock (m_lock) EntityBase entity;
{ m_entities.TryGetValue(localID, out entity);
EntityBase entity; return entity;
if (m_eb_localID.TryGetValue(localID, out entity))
return entity;
else
return null;
}
} }
set set
{ {
InsertOrReplace(value); Add(value);
} }
} }
public bool TryGetValue(UUID key, out EntityBase obj) public bool TryGetValue(UUID key, out EntityBase obj)
{ {
lock (m_lock) return m_entities.TryGetValue(key, out obj);
{
return m_eb_uuid.TryGetValue(key, out obj);
}
} }
public bool TryGetValue(uint key, out EntityBase obj) public bool TryGetValue(uint key, out EntityBase obj)
{ {
lock (m_lock) return m_entities.TryGetValue(key, out obj);
{
return m_eb_localID.TryGetValue(key, out obj);
}
} }
/// <summary> /// <summary>
/// This could be optimised to work on the list 'live' rather than making a safe copy and iterating that. /// This could be optimised to work on the list 'live' rather than making a safe copy and iterating that.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public IEnumerator<EntityBase> GetEnumerator() //public IEnumerator<EntityBase> GetEnumerator()
{ //{
return GetEntities().GetEnumerator(); // return GetEntities().GetEnumerator();
} //}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
//IEnumerator IEnumerable.GetEnumerator()
//{
// return GetEnumerator();
//}
} }
} }

View File

@ -58,7 +58,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_log.Info("[PRIM INVENTORY]: Starting scripts in scene"); m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
foreach (EntityBase group in Entities) EntityBase[] entities = Entities.GetEntities();
foreach (EntityBase group in entities)
{ {
if (group is SceneObjectGroup) if (group is SceneObjectGroup)
{ {

View File

@ -116,9 +116,8 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="remoteClient"></param> /// <param name="remoteClient"></param>
public void RequestPrim(uint primLocalID, IClientAPI remoteClient) public void RequestPrim(uint primLocalID, IClientAPI remoteClient)
{ {
List<EntityBase> EntityList = GetEntities(); EntityBase[] entityList = GetEntities();
foreach (EntityBase ent in entityList)
foreach (EntityBase ent in EntityList)
{ {
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {
@ -138,9 +137,8 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="remoteClient"></param> /// <param name="remoteClient"></param>
public void SelectPrim(uint primLocalID, IClientAPI remoteClient) public void SelectPrim(uint primLocalID, IClientAPI remoteClient)
{ {
List<EntityBase> EntityList = GetEntities(); EntityBase[] entityList = GetEntities();
foreach (EntityBase ent in entityList)
foreach (EntityBase ent in EntityList)
{ {
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {
@ -259,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
{ {
List<EntityBase> EntityList = GetEntities(); EntityBase[] EntityList = GetEntities();
SurfaceTouchEventArgs surfaceArg = null; SurfaceTouchEventArgs surfaceArg = null;
if (surfaceArgs != null && surfaceArgs.Count > 0) if (surfaceArgs != null && surfaceArgs.Count > 0)
@ -303,7 +301,7 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void ProcessObjectGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) public virtual void ProcessObjectGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
{ {
List<EntityBase> EntityList = GetEntities(); EntityBase[] EntityList = GetEntities();
SurfaceTouchEventArgs surfaceArg = null; SurfaceTouchEventArgs surfaceArg = null;
if (surfaceArgs != null && surfaceArgs.Count > 0) if (surfaceArgs != null && surfaceArgs.Count > 0)
@ -343,7 +341,7 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
{ {
List<EntityBase> EntityList = GetEntities(); EntityBase[] EntityList = GetEntities();
SurfaceTouchEventArgs surfaceArg = null; SurfaceTouchEventArgs surfaceArg = null;
if (surfaceArgs != null && surfaceArgs.Count > 0) if (surfaceArgs != null && surfaceArgs.Count > 0)

View File

@ -1029,29 +1029,30 @@ namespace OpenSim.Region.Framework.Scenes
if (ScriptEngine) if (ScriptEngine)
{ {
m_log.Info("Stopping all Scripts in Scene"); m_log.Info("Stopping all Scripts in Scene");
foreach (EntityBase ent in Entities)
EntityBase[] entities = Entities.GetEntities();
foreach (EntityBase ent in entities)
{ {
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ ((SceneObjectGroup)ent).RemoveScriptInstances(false);
((SceneObjectGroup) ent).RemoveScriptInstances(false);
}
} }
} }
else else
{ {
m_log.Info("Starting all Scripts in Scene"); m_log.Info("Starting all Scripts in Scene");
lock (Entities)
EntityBase[] entities = Entities.GetEntities();
foreach (EntityBase ent in entities)
{ {
foreach (EntityBase ent in Entities) if (ent is SceneObjectGroup)
{ {
if (ent is SceneObjectGroup) SceneObjectGroup sog = (SceneObjectGroup)ent;
{ sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0);
((SceneObjectGroup)ent).CreateScriptInstances(0, false, DefaultScriptEngine, 0); sog.ResumeScripts();
((SceneObjectGroup)ent).ResumeScripts();
}
} }
} }
} }
m_scripts_enabled = !ScriptEngine; m_scripts_enabled = !ScriptEngine;
m_log.Info("[TOTEDD]: Here is the method to trigger disabling of the scripting engine"); m_log.Info("[TOTEDD]: Here is the method to trigger disabling of the scripting engine");
} }
@ -1098,7 +1099,7 @@ namespace OpenSim.Region.Framework.Scenes
shuttingdown = true; shuttingdown = true;
m_log.Debug("[SCENE]: Persisting changed objects"); m_log.Debug("[SCENE]: Persisting changed objects");
List<EntityBase> entities = GetEntities(); EntityBase[] entities = GetEntities();
foreach (EntityBase entity in entities) foreach (EntityBase entity in entities)
{ {
if (!entity.IsDeleted && entity is SceneObjectGroup && ((SceneObjectGroup)entity).HasGroupChanged) if (!entity.IsDeleted && entity is SceneObjectGroup && ((SceneObjectGroup)entity).HasGroupChanged)
@ -2037,8 +2038,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
lock (Entities) lock (Entities)
{ {
ICollection<EntityBase> entities = new List<EntityBase>(Entities); EntityBase[] entities = Entities.GetEntities();
foreach (EntityBase e in entities) foreach (EntityBase e in entities)
{ {
if (e is SceneObjectGroup) if (e is SceneObjectGroup)
@ -3977,9 +3977,8 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public void ForceClientUpdate() public void ForceClientUpdate()
{ {
List<EntityBase> EntityList = GetEntities(); EntityBase[] entityList = GetEntities();
foreach (EntityBase ent in entityList)
foreach (EntityBase ent in EntityList)
{ {
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {
@ -3997,9 +3996,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_log.Debug("Searching for Primitive: '" + cmdparams[2] + "'"); m_log.Debug("Searching for Primitive: '" + cmdparams[2] + "'");
List<EntityBase> EntityList = GetEntities(); EntityBase[] entityList = GetEntities();
foreach (EntityBase ent in entityList)
foreach (EntityBase ent in EntityList)
{ {
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {
@ -4368,7 +4366,7 @@ namespace OpenSim.Region.Framework.Scenes
/// will not affect the original list of objects in the scene. /// will not affect the original list of objects in the scene.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public List<EntityBase> GetEntities() public EntityBase[] GetEntities()
{ {
return m_sceneGraph.GetEntities(); return m_sceneGraph.GetEntities();
} }
@ -4402,9 +4400,8 @@ namespace OpenSim.Region.Framework.Scenes
public void CleanTempObjects() public void CleanTempObjects()
{ {
List<EntityBase> objs = GetEntities(); EntityBase[] entities = GetEntities();
foreach (EntityBase obj in entities)
foreach (EntityBase obj in objs)
{ {
if (obj is SceneObjectGroup) if (obj is SceneObjectGroup)
{ {

View File

@ -348,68 +348,57 @@ namespace OpenSim.Region.Framework.Scenes
if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
return false; return false;
lock (sceneObject) if (Entities.ContainsKey(sceneObject.UUID))
{ return false;
if (Entities.ContainsKey(sceneObject.UUID))
// Clamp child prim sizes and add child prims to the m_numPrim count
lock (sceneObject.Children)
{
if (m_parentScene.m_clampPrimSize)
{ {
// m_log.WarnFormat( foreach (SceneObjectPart part in sceneObject.Children.Values)
// "[SCENE GRAPH]: Scene object {0} {1} was already in region {2} on add request",
// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
return false;
}
// m_log.DebugFormat(
// "[SCENE GRAPH]: Adding object {0} {1} to region {2}",
// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
lock (sceneObject.Children)
{
if (m_parentScene.m_clampPrimSize)
{ {
foreach (SceneObjectPart part in sceneObject.Children.Values) Vector3 scale = part.Shape.Scale;
{
Vector3 scale = part.Shape.Scale; if (scale.X > m_parentScene.m_maxNonphys)
scale.X = m_parentScene.m_maxNonphys;
if (scale.X > m_parentScene.m_maxNonphys) if (scale.Y > m_parentScene.m_maxNonphys)
scale.X = m_parentScene.m_maxNonphys; scale.Y = m_parentScene.m_maxNonphys;
if (scale.Y > m_parentScene.m_maxNonphys) if (scale.Z > m_parentScene.m_maxNonphys)
scale.Y = m_parentScene.m_maxNonphys; scale.Z = m_parentScene.m_maxNonphys;
if (scale.Z > m_parentScene.m_maxNonphys)
scale.Z = m_parentScene.m_maxNonphys; part.Shape.Scale = scale;
part.Shape.Scale = scale;
}
} }
m_numPrim += sceneObject.Children.Count;
} }
sceneObject.AttachToScene(m_parentScene);
if (sendClientUpdates) m_numPrim += sceneObject.Children.Count;
sceneObject.ScheduleGroupForFullUpdate(); }
Entities.Add(sceneObject);
if (attachToBackup) sceneObject.AttachToScene(m_parentScene);
sceneObject.AttachToBackup();
if (OnObjectCreate != null) if (sendClientUpdates)
OnObjectCreate(sceneObject); sceneObject.ScheduleGroupForFullUpdate();
lock (SceneObjectGroupsByFullID) Entities.Add(sceneObject);
{
SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; if (attachToBackup)
foreach (SceneObjectPart part in sceneObject.Children.Values) sceneObject.AttachToBackup();
SceneObjectGroupsByFullID[part.UUID] = sceneObject;
} if (OnObjectCreate != null)
OnObjectCreate(sceneObject);
lock (SceneObjectGroupsByLocalID)
{ lock (SceneObjectGroupsByFullID)
SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; {
foreach (SceneObjectPart part in sceneObject.Children.Values) SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; foreach (SceneObjectPart part in sceneObject.Children.Values)
} SceneObjectGroupsByFullID[part.UUID] = sceneObject;
}
lock (SceneObjectGroupsByLocalID)
{
SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
foreach (SceneObjectPart part in sceneObject.Children.Values)
SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
} }
return true; return true;
@ -421,42 +410,38 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>true if the object was deleted, false if there was no object to delete</returns> /// <returns>true if the object was deleted, false if there was no object to delete</returns>
public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked) public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked)
{ {
if (Entities.ContainsKey(uuid)) EntityBase entity;
if (!Entities.TryGetValue(uuid, out entity) && entity is SceneObjectGroup)
return false;
SceneObjectGroup grp = (SceneObjectGroup)entity;
if (!resultOfObjectLinked)
{ {
SceneObjectGroup grp = (SceneObjectGroup)Entities[uuid]; m_numPrim -= grp.PrimCount;
if (!resultOfObjectLinked) if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
{ RemovePhysicalPrim(grp.PrimCount);
m_numPrim -= grp.PrimCount;
if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
RemovePhysicalPrim(grp.PrimCount);
}
if (OnObjectRemove != null)
OnObjectRemove(Entities[uuid]);
lock (SceneObjectGroupsByFullID)
{
foreach (SceneObjectPart part in grp.Children.Values)
SceneObjectGroupsByFullID.Remove(part.UUID);
SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID);
}
lock (SceneObjectGroupsByLocalID)
{
foreach (SceneObjectPart part in grp.Children.Values)
SceneObjectGroupsByLocalID.Remove(part.LocalId);
SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId);
}
Entities.Remove(uuid);
//SceneObjectGroup part;
//((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
return true;
} }
return false; if (OnObjectRemove != null)
OnObjectRemove(Entities[uuid]);
lock (SceneObjectGroupsByFullID)
{
foreach (SceneObjectPart part in grp.Children.Values)
SceneObjectGroupsByFullID.Remove(part.UUID);
SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID);
}
lock (SceneObjectGroupsByLocalID)
{
foreach (SceneObjectPart part in grp.Children.Values)
SceneObjectGroupsByLocalID.Remove(part.LocalId);
SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId);
}
return Entities.Remove(uuid);
} }
/// <summary> /// <summary>
@ -468,9 +453,7 @@ namespace OpenSim.Region.Framework.Scenes
protected internal void AddToUpdateList(SceneObjectGroup obj) protected internal void AddToUpdateList(SceneObjectGroup obj)
{ {
lock (m_updateList) lock (m_updateList)
{
m_updateList[obj.UUID] = obj; m_updateList[obj.UUID] = obj;
}
} }
/// <summary> /// <summary>
@ -480,34 +463,39 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (!Monitor.TryEnter(m_updateLock)) if (!Monitor.TryEnter(m_updateLock))
return; return;
try
List<SceneObjectGroup> updates;
// Some updates add more updates to the updateList.
// Get the current list of updates and clear the list before iterating
lock (m_updateList)
{ {
updates = new List<SceneObjectGroup>(m_updateList.Values); List<SceneObjectGroup> updates;
m_updateList.Clear();
}
// Go through all updates // Some updates add more updates to the updateList.
for (int i = 0; i < updates.Count; i++) // Get the current list of updates and clear the list before iterating
{ lock (m_updateList)
SceneObjectGroup sog = updates[i];
// Don't abort the whole update if one entity happens to give us an exception.
try
{ {
sog.Update(); updates = new List<SceneObjectGroup>(m_updateList.Values);
m_updateList.Clear();
} }
catch (Exception e)
// Go through all updates
for (int i = 0; i < updates.Count; i++)
{ {
m_log.ErrorFormat( SceneObjectGroup sog = updates[i];
"[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
// Don't abort the whole update if one entity happens to give us an exception.
try
{
sog.Update();
}
catch (Exception e)
{
m_log.ErrorFormat(
"[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
}
} }
} }
Monitor.Exit(m_updateLock); finally
{
Monitor.Exit(m_updateLock);
}
} }
protected internal void AddPhysicalPrim(int number) protected internal void AddPhysicalPrim(int number)
@ -864,8 +852,9 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>null if no scene object group containing that prim is found</returns> /// <returns>null if no scene object group containing that prim is found</returns>
public SceneObjectGroup GetGroupByPrim(uint localID) public SceneObjectGroup GetGroupByPrim(uint localID)
{ {
if (Entities.ContainsKey(localID)) EntityBase entity;
return Entities[localID] as SceneObjectGroup; if (Entities.TryGetValue(localID, out entity))
return entity as SceneObjectGroup;
//m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID); //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID);
SceneObjectGroup sog; SceneObjectGroup sog;
@ -879,23 +868,22 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
List<EntityBase> EntityList = GetEntities(); EntityBase[] entityList = GetEntities();
foreach (EntityBase ent in EntityList) foreach (EntityBase ent in entityList)
{ {
//m_log.DebugFormat("Looking at entity {0}", ent.UUID); //m_log.DebugFormat("Looking at entity {0}", ent.UUID);
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {
if (((SceneObjectGroup)ent).HasChildPrim(localID)) sog = (SceneObjectGroup)ent;
if (sog.HasChildPrim(localID))
{ {
sog = (SceneObjectGroup)ent;
lock (SceneObjectGroupsByLocalID) lock (SceneObjectGroupsByLocalID)
{
SceneObjectGroupsByLocalID[localID] = sog; SceneObjectGroupsByLocalID[localID] = sog;
}
return sog; return sog;
} }
} }
} }
return null; return null;
} }
@ -921,23 +909,21 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
List<EntityBase> EntityList = GetEntities(); EntityBase[] entityList = GetEntities();
foreach (EntityBase ent in entityList)
foreach (EntityBase ent in EntityList)
{ {
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {
if (((SceneObjectGroup)ent).HasChildPrim(fullID)) sog = (SceneObjectGroup)ent;
if (sog.HasChildPrim(fullID))
{ {
sog = (SceneObjectGroup)ent;
lock (SceneObjectGroupsByFullID) lock (SceneObjectGroupsByFullID)
{
SceneObjectGroupsByFullID[fullID] = sog; SceneObjectGroupsByFullID[fullID] = sog;
}
return sog; return sog;
} }
} }
} }
return null; return null;
} }
@ -946,7 +932,7 @@ namespace OpenSim.Region.Framework.Scenes
// Primitive Ray Tracing // Primitive Ray Tracing
float closestDistance = 280f; float closestDistance = 280f;
EntityIntersection result = new EntityIntersection(); EntityIntersection result = new EntityIntersection();
List<EntityBase> EntityList = GetEntities(); EntityBase[] EntityList = GetEntities();
foreach (EntityBase ent in EntityList) foreach (EntityBase ent in EntityList)
{ {
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
@ -984,23 +970,28 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>null if the part was not found</returns> /// <returns>null if the part was not found</returns>
protected internal SceneObjectPart GetSceneObjectPart(string name) protected internal SceneObjectPart GetSceneObjectPart(string name)
{ {
List<EntityBase> EntityList = GetEntities(); SceneObjectPart sop = null;
// FIXME: use a dictionary here Entities.Find(
foreach (EntityBase ent in EntityList) delegate(EntityBase entity)
{
if (ent is SceneObjectGroup)
{ {
foreach (SceneObjectPart p in ((SceneObjectGroup) ent).GetParts()) if (entity is SceneObjectGroup)
{ {
if (p.Name == name) foreach (SceneObjectPart p in ((SceneObjectGroup)entity).GetParts())
{ {
return p; if (p.Name == name)
{
sop = p;
return true;
}
} }
} }
return false;
} }
} );
return null;
return sop;
} }
/// <summary> /// <summary>
@ -1021,7 +1012,7 @@ namespace OpenSim.Region.Framework.Scenes
/// it /// it
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
protected internal List<EntityBase> GetEntities() protected internal EntityBase[] GetEntities()
{ {
return Entities.GetEntities(); return Entities.GetEntities();
} }
@ -1030,7 +1021,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
Dictionary<uint, float> topScripts = new Dictionary<uint, float>(); Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
List<EntityBase> EntityList = GetEntities(); EntityBase[] EntityList = GetEntities();
int limit = 0; int limit = 0;
foreach (EntityBase ent in EntityList) foreach (EntityBase ent in EntityList)
{ {
@ -1726,8 +1717,8 @@ namespace OpenSim.Region.Framework.Scenes
UUID objid = UUID.Zero; UUID objid = UUID.Zero;
SceneObjectPart obj = null; SceneObjectPart obj = null;
List<EntityBase> EntityList = GetEntities(); EntityBase[] entityList = GetEntities();
foreach (EntityBase ent in EntityList) foreach (EntityBase ent in entityList)
{ {
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {

View File

@ -75,7 +75,8 @@ namespace OpenSim.Region.Framework.Scenes
lock(m_pendingObjects) lock(m_pendingObjects)
{ {
foreach (EntityBase e in m_presence.Scene.Entities) EntityBase[] entities = m_presence.Scene.Entities.GetEntities();
foreach (EntityBase e in entities)
{ {
if (e != null && e is SceneObjectGroup) if (e != null && e is SceneObjectGroup)
m_pendingObjects.Enqueue((SceneObjectGroup)e); m_pendingObjects.Enqueue((SceneObjectGroup)e);

View File

@ -84,9 +84,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
int primCount = 0; int primCount = 0;
stream.WriteLine("<scene>\n"); stream.WriteLine("<scene>\n");
List<EntityBase> EntityList = scene.GetEntities(); EntityBase[] entityList = scene.GetEntities();
foreach (EntityBase ent in entityList)
foreach (EntityBase ent in EntityList)
{ {
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {
@ -204,16 +203,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
public static void SavePrimsToXml2(Scene scene, string fileName) public static void SavePrimsToXml2(Scene scene, string fileName)
{ {
List<EntityBase> EntityList = scene.GetEntities(); EntityBase[] entityList = scene.GetEntities();
SavePrimListToXml2(entityList, fileName);
SavePrimListToXml2(EntityList, fileName);
} }
public static void SavePrimsToXml2(Scene scene, TextWriter stream, Vector3 min, Vector3 max) public static void SavePrimsToXml2(Scene scene, TextWriter stream, Vector3 min, Vector3 max)
{ {
List<EntityBase> EntityList = scene.GetEntities(); EntityBase[] entityList = scene.GetEntities();
SavePrimListToXml2(entityList, stream, min, max);
SavePrimListToXml2(EntityList, stream, min, max);
} }
public static void SaveNamedPrimsToXml2(Scene scene, string primName, string fileName) public static void SaveNamedPrimsToXml2(Scene scene, string primName, string fileName)
@ -222,7 +219,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
"[SERIALISER]: Saving prims with name {0} in xml2 format for region {1} to {2}", "[SERIALISER]: Saving prims with name {0} in xml2 format for region {1} to {2}",
primName, scene.RegionInfo.RegionName, fileName); primName, scene.RegionInfo.RegionName, fileName);
List<EntityBase> entityList = scene.GetEntities(); EntityBase[] entityList = scene.GetEntities();
List<EntityBase> primList = new List<EntityBase>(); List<EntityBase> primList = new List<EntityBase>();
foreach (EntityBase ent in entityList) foreach (EntityBase ent in entityList)
@ -236,10 +233,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
} }
} }
SavePrimListToXml2(primList, fileName); SavePrimListToXml2(primList.ToArray(), fileName);
} }
public static void SavePrimListToXml2(List<EntityBase> entityList, string fileName) public static void SavePrimListToXml2(EntityBase[] entityList, string fileName)
{ {
FileStream file = new FileStream(fileName, FileMode.Create); FileStream file = new FileStream(fileName, FileMode.Create);
try try
@ -260,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
} }
} }
public static void SavePrimListToXml2(List<EntityBase> entityList, TextWriter stream, Vector3 min, Vector3 max) public static void SavePrimListToXml2(EntityBase[] entityList, TextWriter stream, Vector3 min, Vector3 max)
{ {
int primCount = 0; int primCount = 0;
stream.WriteLine("<scene>\n"); stream.WriteLine("<scene>\n");

View File

@ -375,8 +375,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
private void IRC_SendNamesReply() private void IRC_SendNamesReply()
{ {
List<EntityBase> users = m_scene.Entities.GetAllByType<ScenePresence>(); EntityBase[] users = m_scene.Entities.GetAllByType<ScenePresence>();
foreach (EntityBase user in users) foreach (EntityBase user in users)
{ {
SendServerCommand("353 " + m_nick + " = " + IrcRegionName + " :" + user.Name.Replace(" ", "")); SendServerCommand("353 " + m_nick + " = " + IrcRegionName + " :" + user.Name.Replace(" ", ""));
@ -386,8 +385,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
private void IRC_SendWhoReply() private void IRC_SendWhoReply()
{ {
List<EntityBase> users = m_scene.Entities.GetAllByType<ScenePresence>(); EntityBase[] users = m_scene.Entities.GetAllByType<ScenePresence>();
foreach (EntityBase user in users) foreach (EntityBase user in users)
{ {
/*SendServerCommand(String.Format("352 {0} {1} {2} {3} {4} {5} :0 {6}", IrcRegionName, /*SendServerCommand(String.Format("352 {0} {1} {2} {3} {4} {5} :0 {6}", IrcRegionName,
@ -415,11 +413,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
private void IRC_SendReplyUsers() private void IRC_SendReplyUsers()
{ {
List<EntityBase> users = m_scene.Entities.GetAllByType<ScenePresence>(); EntityBase[] users = m_scene.Entities.GetAllByType<ScenePresence>();
SendServerCommand("392 :UserID Terminal Host"); SendServerCommand("392 :UserID Terminal Host");
if (users.Count == 0) if (users.Length == 0)
{ {
SendServerCommand("395 :Nobody logged in"); SendServerCommand("395 :Nobody logged in");
return; return;

View File

@ -111,7 +111,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
} }
// Check if there are SceneObjectGroups in the list that do not have corresponding ContentManagementGroups in the CMEntityHash // Check if there are SceneObjectGroups in the list that do not have corresponding ContentManagementGroups in the CMEntityHash
public System.Collections.ArrayList CheckForMissingEntities(System.Collections.Generic.List<EntityBase> currList) public System.Collections.ArrayList CheckForMissingEntities(EntityBase[] currList)
{ {
System.Collections.ArrayList missingList = new System.Collections.ArrayList(); System.Collections.ArrayList missingList = new System.Collections.ArrayList();
SceneObjectGroup temp = null; SceneObjectGroup temp = null;

View File

@ -127,7 +127,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
/// </summary> /// </summary>
public void FindDifferences() public void FindDifferences()
{ {
System.Collections.Generic.List<EntityBase> sceneEntityList = m_Entity.Scene.GetEntities(); List<EntityBase> sceneEntityList = new List<EntityBase>(m_Entity.Scene.GetEntities());
DiffersFromSceneGroup = false; DiffersFromSceneGroup = false;
// if group is not contained in scene's list // if group is not contained in scene's list
if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))

View File

@ -41,12 +41,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
private readonly Scene m_scene; private readonly Scene m_scene;
private readonly IEnumerator<EntityBase> m_sogEnum; private readonly IEnumerator<EntityBase> m_sogEnum;
private readonly ISecurityCredential m_security; private readonly ISecurityCredential m_security;
private readonly List<EntityBase> m_entities;
public IObjEnum(Scene scene, ISecurityCredential security) public IObjEnum(Scene scene, ISecurityCredential security)
{ {
m_scene = scene; m_scene = scene;
m_security = security; m_security = security;
m_sogEnum = m_scene.Entities.GetAllByType<SceneObjectGroup>().GetEnumerator(); m_entities = new List<EntityBase>(m_scene.Entities.GetEntities());
m_sogEnum = m_entities.GetEnumerator();
} }
public void Dispose() public void Dispose()

View File

@ -205,10 +205,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
{ {
get get
{ {
List<EntityBase> ents = m_internalScene.Entities.GetAllByType<ScenePresence>(); EntityBase[] ents = m_internalScene.Entities.GetAllByType<ScenePresence>();
IAvatar[] rets = new IAvatar[ents.Count]; IAvatar[] rets = new IAvatar[ents.Length];
for (int i = 0; i < ents.Count; i++) for (int i = 0; i < ents.Length; i++)
{ {
EntityBase ent = ents[i]; EntityBase ent = ents[i];
rets[i] = new SPAvatar(m_internalScene, ent.UUID, m_security); rets[i] = new SPAvatar(m_internalScene, ent.UUID, m_security);

View File

@ -568,8 +568,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
{ {
m_copse = new List<Copse>(); m_copse = new List<Copse>();
List<EntityBase> objs = m_scene.GetEntities(); EntityBase[] objs = m_scene.GetEntities();
foreach (EntityBase obj in objs) foreach (EntityBase obj in objs)
{ {
if (obj is SceneObjectGroup) if (obj is SceneObjectGroup)

View File

@ -286,7 +286,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
} }
else else
{ {
Entities = m_CmdManager.m_ScriptEngine.World.GetEntities(); Entities = new List<EntityBase>(m_CmdManager.m_ScriptEngine.World.GetEntities());
} }
SceneObjectPart SensePoint = ts.host; SceneObjectPart SensePoint = ts.host;

View File

@ -69,7 +69,10 @@ namespace OpenSim.Services.Connectors.SimianGrid
public void OnMakeRootAgent(ScenePresence sp) public void OnMakeRootAgent(ScenePresence sp)
{ {
m_log.DebugFormat("[SIMIAN ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName); m_log.DebugFormat("[SIMIAN ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); Util.FireAndForget(delegate(object o)
{
m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
});
} }
public void OnNewClient(IClientAPI client) public void OnNewClient(IClientAPI client)