Cleaned up access to scenepresences in scenegraph. GetScenePresences and GetAvatars have been removed to consolidate locking and iteration within SceneGraph. All callers which used these to then iterate over presences have been refactored to instead pass their delegates to Scene.ForEachScenePresence(Action<ScenePresence>).

This commit is contained in:
Dan Lake
2010-03-19 05:51:16 -07:00
committed by John Hurliman
parent 73e9b0be72
commit 859bc717a4
22 changed files with 378 additions and 513 deletions

View File

@@ -468,26 +468,20 @@ namespace OpenSim.Region.CoreModules.World.Estate
private void handleEstateTeleportAllUsersHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID)
{
// Get a fresh list that will not change as people get teleported away
List<ScenePresence> presences = m_scene.GetScenePresences();
foreach(ScenePresence p in presences)
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
if (p.UUID != senderID)
if (sp.UUID != senderID)
{
ScenePresence p = m_scene.GetScenePresence(sp.UUID);
// make sure they are still there, we could be working down a long list
ScenePresence s = m_scene.GetScenePresence(p.UUID);
if (s != null)
// Also make sure they are actually in the region
if (p != null && !p.IsChildAgent)
{
// Also make sure they are actually in the region
if (!s.IsChildAgent)
{
s.ControllingClient.SendTeleportLocationStart();
m_scene.TeleportClientHome(s.UUID, s.ControllingClient);
}
p.ControllingClient.SendTeleportLocationStart();
m_scene.TeleportClientHome(p.UUID, p.ControllingClient);
}
}
}
});
}
private void AbortTerrainXferHandler(IClientAPI remoteClient, ulong XferID)
{
@@ -765,12 +759,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
public void sendRegionInfoPacketToAll()
{
List<ScenePresence> avatars = m_scene.GetAvatars();
for (int i = 0; i < avatars.Count; i++)
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
HandleRegionInfoRequest(avatars[i].ControllingClient);
}
if (!sp.IsChildAgent)
HandleRegionInfoRequest(sp.ControllingClient);
});
}
public void sendRegionHandshake(IClientAPI remoteClient)

View File

@@ -191,9 +191,9 @@ namespace OpenSim.Region.CoreModules.World.Land
forcedPosition = null;
}
//if we are far away, teleport
else if (Vector3.Distance(clientAvatar.AbsolutePosition,forcedPosition.Value) > 3)
else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition.Value) > 3)
{
Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}",forcedPosition.Value,clientAvatar.AbsolutePosition));
Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}", forcedPosition.Value, clientAvatar.AbsolutePosition));
clientAvatar.Teleport(forcedPosition.Value);
forcedPosition = null;
}
@@ -374,30 +374,27 @@ namespace OpenSim.Region.CoreModules.World.Land
}
}
public void SendOutNearestBanLine(IClientAPI avatar)
public void SendOutNearestBanLine(IClientAPI client)
{
List<ScenePresence> avatars = m_scene.GetAvatars();
foreach (ScenePresence presence in avatars)
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp == null || sp.IsChildAgent)
return;
List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition);
foreach (ILandObject checkBan in checkLandParcels)
{
if (presence.UUID == avatar.AgentId)
if (checkBan.IsBannedFromLand(client.AgentId))
{
List<ILandObject> checkLandParcels = ParcelsNearPoint(presence.AbsolutePosition);
foreach (ILandObject checkBan in checkLandParcels)
{
if (checkBan.IsBannedFromLand(avatar.AgentId))
{
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar);
return; //Only send one
}
if (checkBan.IsRestrictedFromLand(avatar.AgentId))
{
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar);
return; //Only send one
}
}
return;
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, client);
return; //Only send one
}
if (checkBan.IsRestrictedFromLand(client.AgentId))
{
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, client);
return; //Only send one
}
}
return;
}
public void SendLandUpdate(ScenePresence avatar, bool force)

View File

@@ -332,36 +332,38 @@ namespace OpenSim.Region.CoreModules.World.Land
public void SendLandUpdateToAvatarsOverMe(bool snap_selection)
{
List<ScenePresence> avatars = m_scene.GetAvatars();
ILandObject over = null;
for (int i = 0; i < avatars.Count; i++)
m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
if (avatar.IsChildAgent)
return;
ILandObject over = null;
try
{
over =
m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatars[i].AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)),
Util.Clamp<int>((int)Math.Round(avatars[i].AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1)));
m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)),
Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1)));
}
catch (Exception)
{
m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " +
Math.Round(avatars[i].AbsolutePosition.Y));
m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " +
Math.Round(avatar.AbsolutePosition.Y));
}
if (over != null)
{
if (over.LandData.LocalID == LandData.LocalID)
{
if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) &&
if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) &&
m_scene.RegionInfo.RegionSettings.AllowDamage)
avatars[i].Invulnerable = false;
avatar.Invulnerable = false;
else
avatars[i].Invulnerable = true;
avatar.Invulnerable = true;
SendLandUpdateToClient(snap_selection, avatars[i].ControllingClient);
SendLandUpdateToClient(snap_selection, avatar.ControllingClient);
}
}
}
});
}
#endregion

View File

@@ -62,40 +62,46 @@ namespace OpenSim.Region.CoreModules.World.Sound
public virtual void PlayAttachedSound(
UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags, float radius)
{
foreach (ScenePresence p in m_scene.GetAvatars())
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
double dis = Util.GetDistanceTo(p.AbsolutePosition, position);
if (sp.IsChildAgent)
return;
double dis = Util.GetDistanceTo(sp.AbsolutePosition, position);
if (dis > 100.0) // Max audio distance
continue;
return;
// Scale by distance
if (radius == 0)
gain = (float)((double)gain * ((100.0 - dis) / 100.0));
else
gain = (float)((double)gain * ((radius - dis) / radius));
p.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags);
}
sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags);
});
}
public virtual void TriggerSound(
UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius)
{
foreach (ScenePresence p in m_scene.GetAvatars())
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
double dis = Util.GetDistanceTo(p.AbsolutePosition, position);
if (sp.IsChildAgent)
return;
double dis = Util.GetDistanceTo(sp.AbsolutePosition, position);
if (dis > 100.0) // Max audio distance
continue;
return;
// Scale by distance
if (radius == 0)
gain = (float)((double)gain * ((100.0 - dis) / 100.0));
else
gain = (float)((double)gain * ((radius - dis) / radius));
p.ControllingClient.SendTriggeredSound(
sp.ControllingClient.SendTriggeredSound(
soundId, ownerID, objectID, parentID, handle, position, (float)gain);
}
});
}
}
}

View File

@@ -509,14 +509,13 @@ namespace OpenSim.Region.CoreModules
private void SunUpdateToAllClients()
{
List<ScenePresence> avatars = m_scene.GetAvatars();
foreach (ScenePresence avatar in avatars)
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
if (!avatar.IsChildAgent)
if (!sp.IsChildAgent)
{
SunToClient(avatar.ControllingClient);
SunToClient(sp.ControllingClient);
}
}
});
}
#region ISunModule Members

View File

@@ -425,9 +425,7 @@ namespace OpenSim.Region.CoreModules
{
if (m_ready)
{
List<ScenePresence> avatars = m_scene.GetAvatars();
if (avatars.Count > 0)
if(m_scene.GetRootAgentCount() > 0)
{
// Ask wind plugin to generate a LL wind array to be cached locally
// Try not to update this too often, as it may involve array copies
@@ -437,11 +435,11 @@ namespace OpenSim.Region.CoreModules
m_frameLastUpdateClientArray = m_frame;
}
foreach (ScenePresence avatar in avatars)
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
if (!avatar.IsChildAgent)
avatar.ControllingClient.SendWindData(windSpeeds);
}
if (!sp.IsChildAgent)
sp.ControllingClient.SendWindData(windSpeeds);
});
}
}
}

View File

@@ -304,25 +304,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
/// <param name="AgentId">AgentID that logged out</param>
private void ClientLoggedOut(UUID AgentId, Scene scene)
{
List<ScenePresence> presences = m_scene.GetAvatars();
int rootcount = 0;
for (int i=0;i<presences.Count;i++)
{
if (presences[i] != null)
{
if (!presences[i].IsChildAgent)
rootcount++;
}
}
if (rootcount <= 1)
StopThread();
lock (m_rootAgents)
{
if (m_rootAgents.Contains(AgentId))
{
m_rootAgents.Remove(AgentId);
}
m_rootAgents.Remove(AgentId);
if(m_rootAgents.Count == 0)
StopThread();
}
}
#endregion
@@ -375,11 +361,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle)
{
// Local Map Item Request
List<ScenePresence> avatars = m_scene.GetAvatars();
int tc = Environment.TickCount;
List<mapItemReply> mapitems = new List<mapItemReply>();
mapItemReply mapitem = new mapItemReply();
if (avatars.Count == 0 || avatars.Count == 1)
if (m_scene.GetRootAgentCount() <= 1)
{
mapitem = new mapItemReply();
mapitem.x = (uint)(xstart + 1);
@@ -392,21 +377,21 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
}
else
{
foreach (ScenePresence av in avatars)
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
// Don't send a green dot for yourself
if (av.UUID != remoteClient.AgentId)
if (!sp.IsChildAgent && sp.UUID != remoteClient.AgentId)
{
mapitem = new mapItemReply();
mapitem.x = (uint)(xstart + av.AbsolutePosition.X);
mapitem.y = (uint)(ystart + av.AbsolutePosition.Y);
mapitem.x = (uint)(xstart + sp.AbsolutePosition.X);
mapitem.y = (uint)(ystart + sp.AbsolutePosition.Y);
mapitem.id = UUID.Zero;
mapitem.name = Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString());
mapitem.Extra = 1;
mapitem.Extra2 = 0;
mapitems.Add(mapitem);
}
}
});
}
remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags);
}
@@ -981,51 +966,35 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart);
OSDMap responsemap = new OSDMap();
List<ScenePresence> avatars = m_scene.GetAvatars();
OSDArray responsearr = new OSDArray(avatars.Count);
OSDMap responsemapdata = new OSDMap();
int tc = Environment.TickCount;
/*
foreach (ScenePresence av in avatars)
if (m_scene.GetRootAgentCount() == 0)
{
responsemapdata = new OSDMap();
responsemapdata["X"] = OSD.FromInteger((int)(xstart + av.AbsolutePosition.X));
responsemapdata["Y"] = OSD.FromInteger((int)(ystart + av.AbsolutePosition.Y));
responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
responsemapdata["Name"] = OSD.FromString("TH");
responsemapdata["Extra"] = OSD.FromInteger(0);
responsemapdata["Extra2"] = OSD.FromInteger(0);
responsearr.Add(responsemapdata);
}
responsemap["1"] = responsearr;
*/
if (avatars.Count == 0)
{
responsemapdata = new OSDMap();
OSDMap responsemapdata = new OSDMap();
responsemapdata["X"] = OSD.FromInteger((int)(xstart + 1));
responsemapdata["Y"] = OSD.FromInteger((int)(ystart + 1));
responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
responsemapdata["Name"] = OSD.FromString(Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString()));
responsemapdata["Extra"] = OSD.FromInteger(0);
responsemapdata["Extra2"] = OSD.FromInteger(0);
OSDArray responsearr = new OSDArray();
responsearr.Add(responsemapdata);
responsemap["6"] = responsearr;
}
else
{
responsearr = new OSDArray(avatars.Count);
foreach (ScenePresence av in avatars)
OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount());
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
responsemapdata = new OSDMap();
responsemapdata["X"] = OSD.FromInteger((int)(xstart + av.AbsolutePosition.X));
responsemapdata["Y"] = OSD.FromInteger((int)(ystart + av.AbsolutePosition.Y));
OSDMap responsemapdata = new OSDMap();
responsemapdata["X"] = OSD.FromInteger((int)(xstart + sp.AbsolutePosition.X));
responsemapdata["Y"] = OSD.FromInteger((int)(ystart + sp.AbsolutePosition.Y));
responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
responsemapdata["Name"] = OSD.FromString(Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString()));
responsemapdata["Extra"] = OSD.FromInteger(1);
responsemapdata["Extra2"] = OSD.FromInteger(0);
responsearr.Add(responsemapdata);
}
});
responsemap["6"] = responsearr;
}
return responsemap;
@@ -1107,25 +1076,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
private void MakeChildAgent(ScenePresence avatar)
{
List<ScenePresence> presences = m_scene.GetAvatars();
int rootcount = 0;
for (int i = 0; i < presences.Count; i++)
{
if (presences[i] != null)
{
if (!presences[i].IsChildAgent)
rootcount++;
}
}
if (rootcount <= 1)
StopThread();
lock (m_rootAgents)
{
if (m_rootAgents.Contains(avatar.UUID))
{
m_rootAgents.Remove(avatar.UUID);
}
m_rootAgents.Remove(avatar.UUID);
if (m_rootAgents.Count == 0)
StopThread();
}
}