try save a few ns on chat to objects
parent
df2536c407
commit
6cadcb8bdf
|
@ -97,7 +97,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
// private static readonly ILog m_log =
|
// private static readonly ILog m_log =
|
||||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private const int DEBUG_CHANNEL = 2147483647;
|
private const int DEBUG_CHANNEL = 0x7fffffff;
|
||||||
|
|
||||||
private ListenerManager m_listenerManager;
|
private ListenerManager m_listenerManager;
|
||||||
private ConcurrentQueue<ListenerInfo> m_pending;
|
private ConcurrentQueue<ListenerInfo> m_pending;
|
||||||
|
@ -131,6 +131,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_whisperdistance *= m_whisperdistance;
|
||||||
|
m_saydistance *= m_saydistance;
|
||||||
|
m_shoutdistance *= m_shoutdistance;
|
||||||
|
|
||||||
if (maxlisteners < 1)
|
if (maxlisteners < 1)
|
||||||
maxlisteners = int.MaxValue;
|
maxlisteners = int.MaxValue;
|
||||||
if (maxhandles < 1)
|
if (maxhandles < 1)
|
||||||
|
@ -314,42 +318,54 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
// m_log.DebugFormat("[WorldComm] got[2] type {0}, channel {1}, name {2}, id {3}, msg {4}",
|
// m_log.DebugFormat("[WorldComm] got[2] type {0}, channel {1}, name {2}, id {3}, msg {4}",
|
||||||
// type, channel, name, id, msg);
|
// type, channel, name, id, msg);
|
||||||
|
|
||||||
|
// validate type and set range
|
||||||
|
float maxDistanceSQ;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case ChatTypeEnum.Whisper:
|
||||||
|
maxDistanceSQ = m_whisperdistance;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ChatTypeEnum.Say:
|
||||||
|
maxDistanceSQ = m_saydistance;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ChatTypeEnum.Shout:
|
||||||
|
maxDistanceSQ = m_shoutdistance;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ChatTypeEnum.Region:
|
||||||
|
maxDistanceSQ = -1f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine which listen event filters match the given set of arguments, this results
|
// Determine which listen event filters match the given set of arguments, this results
|
||||||
// in a limited set of listeners, each belonging a host. If the host is in range, add them
|
// in a limited set of listeners, each belonging a host. If the host is in range, add them
|
||||||
// to the pending queue.
|
// to the pending queue.
|
||||||
|
|
||||||
|
UUID hostID;
|
||||||
foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
|
foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
|
||||||
{
|
{
|
||||||
|
hostID = li.GetHostID();
|
||||||
// Dont process if this message is from yourself!
|
// Dont process if this message is from yourself!
|
||||||
if (li.GetHostID().Equals(id))
|
if (id == hostID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID());
|
if(maxDistanceSQ < 0)
|
||||||
|
{
|
||||||
|
QueueMessage(new ListenerInfo(li, name, id, msg));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneObjectPart sPart = m_scene.GetSceneObjectPart(hostID);
|
||||||
if (sPart == null)
|
if (sPart == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
double dis = Vector3.DistanceSquared(sPart.AbsolutePosition, position);
|
if(maxDistanceSQ > Vector3.DistanceSquared(sPart.AbsolutePosition, position))
|
||||||
switch (type)
|
QueueMessage(new ListenerInfo(li, name, id, msg));
|
||||||
{
|
|
||||||
case ChatTypeEnum.Whisper:
|
|
||||||
if (dis < m_whisperdistance * m_whisperdistance)
|
|
||||||
QueueMessage(new ListenerInfo(li, name, id, msg));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ChatTypeEnum.Say:
|
|
||||||
if (dis < m_saydistance * m_saydistance)
|
|
||||||
QueueMessage(new ListenerInfo(li, name, id, msg));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ChatTypeEnum.Shout:
|
|
||||||
if (dis < m_shoutdistance * m_shoutdistance)
|
|
||||||
QueueMessage(new ListenerInfo(li, name, id, msg));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ChatTypeEnum.Region:
|
|
||||||
QueueMessage(new ListenerInfo(li, name, id, msg));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,8 +522,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
|
|
||||||
public class ListenerManager
|
public class ListenerManager
|
||||||
{
|
{
|
||||||
private Dictionary<int, List<ListenerInfo>> m_listeners =
|
private object mainLock = new object();
|
||||||
new Dictionary<int, List<ListenerInfo>>();
|
private Dictionary<int, List<ListenerInfo>> m_listenersByChannel = new Dictionary<int, List<ListenerInfo>>();
|
||||||
private int m_maxlisteners;
|
private int m_maxlisteners;
|
||||||
private int m_maxhandles;
|
private int m_maxhandles;
|
||||||
private int m_curlisteners;
|
private int m_curlisteners;
|
||||||
|
@ -519,8 +535,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
lock (m_listeners)
|
lock (mainLock)
|
||||||
return m_listeners.Count;
|
return m_listenersByChannel.Count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,8 +559,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
int regexBitfield)
|
int regexBitfield)
|
||||||
{
|
{
|
||||||
// do we already have a match on this particular filter event?
|
// do we already have a match on this particular filter event?
|
||||||
List<ListenerInfo> coll = GetListeners(itemID, channel, name, id,
|
List<ListenerInfo> coll = GetListeners(itemID, channel, name, id, msg);
|
||||||
msg);
|
|
||||||
|
|
||||||
if (coll.Count > 0)
|
if (coll.Count > 0)
|
||||||
{
|
{
|
||||||
|
@ -553,7 +568,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
return coll[0].GetHandle();
|
return coll[0].GetHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_listeners)
|
lock (mainLock)
|
||||||
{
|
{
|
||||||
if (m_curlisteners < m_maxlisteners)
|
if (m_curlisteners < m_maxlisteners)
|
||||||
{
|
{
|
||||||
|
@ -565,12 +580,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
itemID, hostID, channel, name, id, msg,
|
itemID, hostID, channel, name, id, msg,
|
||||||
regexBitfield);
|
regexBitfield);
|
||||||
|
|
||||||
List<ListenerInfo> listeners;
|
if (!m_listenersByChannel.TryGetValue(channel, out List<ListenerInfo> listeners))
|
||||||
if (!m_listeners.TryGetValue(
|
|
||||||
channel, out listeners))
|
|
||||||
{
|
{
|
||||||
listeners = new List<ListenerInfo>();
|
listeners = new List<ListenerInfo>();
|
||||||
m_listeners.Add(channel, listeners);
|
m_listenersByChannel.Add(channel, listeners);
|
||||||
}
|
}
|
||||||
listeners.Add(li);
|
listeners.Add(li);
|
||||||
m_curlisteners++;
|
m_curlisteners++;
|
||||||
|
@ -584,20 +597,18 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
|
|
||||||
public void Remove(UUID itemID, int handle)
|
public void Remove(UUID itemID, int handle)
|
||||||
{
|
{
|
||||||
lock (m_listeners)
|
lock (mainLock)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<int, List<ListenerInfo>> lis
|
foreach (KeyValuePair<int, List<ListenerInfo>> lis in m_listenersByChannel)
|
||||||
in m_listeners)
|
|
||||||
{
|
{
|
||||||
foreach (ListenerInfo li in lis.Value)
|
foreach (ListenerInfo li in lis.Value)
|
||||||
{
|
{
|
||||||
if (li.GetItemID().Equals(itemID) &&
|
if (handle == li.GetHandle() && itemID == li.GetItemID())
|
||||||
li.GetHandle().Equals(handle))
|
|
||||||
{
|
{
|
||||||
lis.Value.Remove(li);
|
lis.Value.Remove(li);
|
||||||
m_curlisteners--;
|
m_curlisteners--;
|
||||||
if (lis.Value.Count == 0)
|
if (lis.Value.Count == 0)
|
||||||
m_listeners.Remove(lis.Key); // bailing of loop so this does not smoke
|
m_listenersByChannel.Remove(lis.Key); // bailing of loop so this does not smoke
|
||||||
// there should be only one, so we bail out early
|
// there should be only one, so we bail out early
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -611,53 +622,44 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
List<int> emptyChannels = new List<int>();
|
List<int> emptyChannels = new List<int>();
|
||||||
List<ListenerInfo> removedListeners = new List<ListenerInfo>();
|
List<ListenerInfo> removedListeners = new List<ListenerInfo>();
|
||||||
|
|
||||||
lock (m_listeners)
|
lock (mainLock)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<int, List<ListenerInfo>> lis
|
foreach (KeyValuePair<int, List<ListenerInfo>> lis in m_listenersByChannel)
|
||||||
in m_listeners)
|
|
||||||
{
|
{
|
||||||
foreach (ListenerInfo li in lis.Value)
|
foreach (ListenerInfo li in lis.Value)
|
||||||
{
|
{
|
||||||
if (li.GetItemID().Equals(itemID))
|
if (itemID == li.GetItemID())
|
||||||
{
|
|
||||||
// store them first, else the enumerated bails on
|
|
||||||
// us
|
|
||||||
removedListeners.Add(li);
|
removedListeners.Add(li);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ListenerInfo li in removedListeners)
|
foreach (ListenerInfo li in removedListeners)
|
||||||
{
|
{
|
||||||
lis.Value.Remove(li);
|
lis.Value.Remove(li);
|
||||||
m_curlisteners--;
|
m_curlisteners--;
|
||||||
}
|
}
|
||||||
|
|
||||||
removedListeners.Clear();
|
removedListeners.Clear();
|
||||||
if (lis.Value.Count == 0)
|
if (lis.Value.Count == 0)
|
||||||
{
|
|
||||||
// again, store first, remove later
|
|
||||||
emptyChannels.Add(lis.Key);
|
emptyChannels.Add(lis.Key);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
foreach (int channel in emptyChannels)
|
foreach (int channel in emptyChannels)
|
||||||
{
|
{
|
||||||
m_listeners.Remove(channel);
|
m_listenersByChannel.Remove(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Activate(UUID itemID, int handle)
|
public void Activate(UUID itemID, int handle)
|
||||||
{
|
{
|
||||||
lock (m_listeners)
|
lock (mainLock)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<int, List<ListenerInfo>> lis
|
foreach (KeyValuePair<int, List<ListenerInfo>> lis in m_listenersByChannel)
|
||||||
in m_listeners)
|
|
||||||
{
|
{
|
||||||
foreach (ListenerInfo li in lis.Value)
|
foreach (ListenerInfo li in lis.Value)
|
||||||
{
|
{
|
||||||
if (li.GetItemID().Equals(itemID) &&
|
if (handle == li.GetHandle() && itemID == li.GetItemID())
|
||||||
li.GetHandle() == handle)
|
|
||||||
{
|
{
|
||||||
li.Activate();
|
li.Activate();
|
||||||
// only one, bail out
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -667,18 +669,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
|
|
||||||
public void Dectivate(UUID itemID, int handle)
|
public void Dectivate(UUID itemID, int handle)
|
||||||
{
|
{
|
||||||
lock (m_listeners)
|
lock (mainLock)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<int, List<ListenerInfo>> lis
|
foreach (KeyValuePair<int, List<ListenerInfo>> lis in m_listenersByChannel)
|
||||||
in m_listeners)
|
|
||||||
{
|
{
|
||||||
foreach (ListenerInfo li in lis.Value)
|
foreach (ListenerInfo li in lis.Value)
|
||||||
{
|
{
|
||||||
if (li.GetItemID().Equals(itemID) &&
|
if (handle == li.GetHandle() && itemID == li.GetItemID())
|
||||||
li.GetHandle() == handle)
|
|
||||||
{
|
{
|
||||||
li.Deactivate();
|
li.Deactivate();
|
||||||
// only one, bail out
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -697,11 +696,11 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
List<int> handles = new List<int>();
|
List<int> handles = new List<int>();
|
||||||
|
|
||||||
// build a list of used keys for this specific itemID...
|
// build a list of used keys for this specific itemID...
|
||||||
foreach (KeyValuePair<int, List<ListenerInfo>> lis in m_listeners)
|
foreach (KeyValuePair<int, List<ListenerInfo>> lis in m_listenersByChannel)
|
||||||
{
|
{
|
||||||
foreach (ListenerInfo li in lis.Value)
|
foreach (ListenerInfo li in lis.Value)
|
||||||
{
|
{
|
||||||
if (li.GetItemID().Equals(itemID))
|
if (itemID == li.GetItemID())
|
||||||
handles.Add(li.GetHandle());
|
handles.Add(li.GetHandle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -741,8 +740,6 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Theres probably a more clever and efficient way to do this, maybe
|
/// Theres probably a more clever and efficient way to do this, maybe
|
||||||
/// with regex.
|
/// with regex.
|
||||||
/// PM2008: Ha, one could even be smart and define a specialized
|
|
||||||
/// Enumerator.
|
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="itemID"></param>
|
/// <param name="itemID"></param>
|
||||||
/// <param name="channel"></param>
|
/// <param name="channel"></param>
|
||||||
|
@ -755,42 +752,52 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
{
|
{
|
||||||
List<ListenerInfo> collection = new List<ListenerInfo>();
|
List<ListenerInfo> collection = new List<ListenerInfo>();
|
||||||
|
|
||||||
lock (m_listeners)
|
lock (mainLock)
|
||||||
{
|
{
|
||||||
List<ListenerInfo> listeners;
|
List<ListenerInfo> listeners;
|
||||||
if (!m_listeners.TryGetValue(channel, out listeners))
|
if (!m_listenersByChannel.TryGetValue(channel, out listeners))
|
||||||
{
|
{
|
||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool itemIDNotZero = itemID != UUID.Zero;
|
||||||
foreach (ListenerInfo li in listeners)
|
foreach (ListenerInfo li in listeners)
|
||||||
{
|
{
|
||||||
if (!li.IsActive())
|
if (!li.IsActive())
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (itemIDNotZero && itemID != li.GetItemID())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (li.GetID() != UUID.Zero && id != li.GetID())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (li.GetName().Length > 0)
|
||||||
|
{
|
||||||
|
if((li.RegexBitfield & OS_LISTEN_REGEX_NAME) == OS_LISTEN_REGEX_NAME)
|
||||||
|
{
|
||||||
|
if (!Regex.IsMatch(name, li.GetName()))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!li.GetName().Equals(name))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!itemID.Equals(UUID.Zero) &&
|
|
||||||
!li.GetItemID().Equals(itemID))
|
if (li.GetMessage().Length > 0)
|
||||||
{
|
{
|
||||||
continue;
|
if((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) == OS_LISTEN_REGEX_MESSAGE)
|
||||||
}
|
{
|
||||||
if (li.GetName().Length > 0 && (
|
if(!Regex.IsMatch(msg, li.GetMessage()))
|
||||||
((li.RegexBitfield & OS_LISTEN_REGEX_NAME) != OS_LISTEN_REGEX_NAME && !li.GetName().Equals(name)) ||
|
continue;
|
||||||
((li.RegexBitfield & OS_LISTEN_REGEX_NAME) == OS_LISTEN_REGEX_NAME && !Regex.IsMatch(name, li.GetName()))
|
}
|
||||||
))
|
else
|
||||||
{
|
{
|
||||||
continue;
|
if(!li.GetMessage().Equals(msg))
|
||||||
}
|
continue;
|
||||||
if (!li.GetID().Equals(UUID.Zero) && !li.GetID().Equals(id))
|
}
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (li.GetMessage().Length > 0 && (
|
|
||||||
((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) != OS_LISTEN_REGEX_MESSAGE && !li.GetMessage().Equals(msg)) ||
|
|
||||||
((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) == OS_LISTEN_REGEX_MESSAGE && !Regex.IsMatch(msg, li.GetMessage()))
|
|
||||||
))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
collection.Add(li);
|
collection.Add(li);
|
||||||
}
|
}
|
||||||
|
@ -802,9 +809,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
{
|
{
|
||||||
List<Object> data = new List<Object>();
|
List<Object> data = new List<Object>();
|
||||||
|
|
||||||
lock (m_listeners)
|
lock (mainLock)
|
||||||
{
|
{
|
||||||
foreach (List<ListenerInfo> list in m_listeners.Values)
|
foreach (List<ListenerInfo> list in m_listenersByChannel.Values)
|
||||||
{
|
{
|
||||||
foreach (ListenerInfo l in list)
|
foreach (ListenerInfo l in list)
|
||||||
{
|
{
|
||||||
|
@ -832,14 +839,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||||
ListenerInfo info =
|
ListenerInfo info =
|
||||||
ListenerInfo.FromData(localID, itemID, hostID, item);
|
ListenerInfo.FromData(localID, itemID, hostID, item);
|
||||||
|
|
||||||
lock (m_listeners)
|
lock (mainLock)
|
||||||
{
|
{
|
||||||
if (!m_listeners.ContainsKey((int)item[2]))
|
if (!m_listenersByChannel.ContainsKey((int)item[2]))
|
||||||
{
|
{
|
||||||
m_listeners.Add((int)item[2],
|
m_listenersByChannel.Add((int)item[2], new List<ListenerInfo>());
|
||||||
new List<ListenerInfo>());
|
|
||||||
}
|
}
|
||||||
m_listeners[(int)item[2]].Add(info);
|
m_listenersByChannel[(int)item[2]].Add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
idx += dataItemLength;
|
idx += dataItemLength;
|
||||||
|
|
Loading…
Reference in New Issue