From 4b75353cbf50de3cae4c48ec90b55f30c1612c92 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 15 Oct 2009 16:35:27 -0700 Subject: Object update prioritization by Jim Greensky of Intel Labs, part one. This implements a simple distance prioritizer based on initial agent positions. Re-prioritizing and more advanced priority algorithms will follow soon --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 344 ++++++++------------- 1 file changed, 135 insertions(+), 209 deletions(-) (limited to 'OpenSim/Region/ClientStack') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 93fdeef..0a7d923 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -320,14 +320,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP private readonly IGroupsModule m_GroupsModule; private int m_cachedTextureSerial; - private Timer m_avatarTerseUpdateTimer; - private PriorityQueue m_avatarTerseUpdates_ = + private PriorityQueue m_avatarTerseUpdates = new PriorityQueue(); - private Timer m_primTerseUpdateTimer; - private PriorityQueue m_primTerseUpdates_ = + private PriorityQueue m_primTerseUpdates = new PriorityQueue(); - private Timer m_primFullUpdateTimer; - private PriorityQueue m_primFullUpdates_ = + private PriorityQueue m_primFullUpdates = new PriorityQueue(); private int m_moneyBalance; private int m_animationSequenceNumber = 1; @@ -353,9 +350,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP // LL uses these limits, apparently. Compressed terse would be 23, but we don't have that yet protected int m_primTerseUpdatesPerPacket = 10; protected int m_primFullUpdatesPerPacket = 14; - protected int m_primTerseUpdateRate = 10; - protected int m_primFullUpdateRate = 14; - protected int m_avatarTerseUpdateRate = 50; protected int m_avatarTerseUpdatesPerPacket = 5; /// Number of texture packets to put on the queue each time the /// OnQueueEmpty event is triggered for the texture category @@ -479,25 +473,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Remove ourselves from the scene m_scene.RemoveClient(AgentId); - // Shut down timers. Thread Context of this method is murky. Lock all timers - if (m_avatarTerseUpdateTimer.Enabled) - lock (m_avatarTerseUpdateTimer) - m_avatarTerseUpdateTimer.Stop(); - if (m_primTerseUpdateTimer.Enabled) - lock (m_primTerseUpdateTimer) - m_primTerseUpdateTimer.Stop(); - if (m_primFullUpdateTimer.Enabled) - lock (m_primFullUpdateTimer) - m_primFullUpdateTimer.Stop(); - // We can't reach into other scenes and close the connection // We need to do this over grid communications //m_scene.CloseAllAgents(CircuitCode); - m_avatarTerseUpdateTimer.Dispose(); - m_primTerseUpdateTimer.Dispose(); - m_primFullUpdateTimer.Dispose(); - // Disable UDP handling for this client m_udpClient.Shutdown(); @@ -524,18 +503,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void Stop() { - // Shut down timers. Thread Context is Murky, lock all timers! - if (m_avatarTerseUpdateTimer.Enabled) - lock (m_avatarTerseUpdateTimer) - m_avatarTerseUpdateTimer.Stop(); - - if (m_primTerseUpdateTimer.Enabled) - lock (m_primTerseUpdateTimer) - m_primTerseUpdateTimer.Stop(); - if (m_primFullUpdateTimer.Enabled) - lock (m_primFullUpdateTimer) - m_primFullUpdateTimer.Stop(); } #endregion Client Methods @@ -631,18 +599,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP public virtual void Start() { - m_avatarTerseUpdateTimer = new Timer(m_avatarTerseUpdateRate); - m_avatarTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); - m_avatarTerseUpdateTimer.AutoReset = false; - - m_primTerseUpdateTimer = new Timer(m_primTerseUpdateRate); - m_primTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimTerseUpdates); - m_primTerseUpdateTimer.AutoReset = false; - - m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); - m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); - m_primFullUpdateTimer.AutoReset = false; - m_scene.AddNewClient(this); RefreshGroupMembership(); @@ -3394,28 +3350,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// send a objectupdate packet with information about the clients avatar /// - public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, - uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) + public void SendAvatarData(SendAvatarData data) { ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); // TODO: don't create new blocks if recycling an old packet - objupdate.RegionData.RegionHandle = regionHandle; + objupdate.RegionData.RegionHandle = data.regionHandle; objupdate.RegionData.TimeDilation = ushort.MaxValue; objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; - objupdate.ObjectData[0] = CreateDefaultAvatarPacket(textureEntry); + objupdate.ObjectData[0] = CreateDefaultAvatarPacket(data.textureEntry); //give this avatar object a local id and assign the user a name - objupdate.ObjectData[0].ID = avatarLocalID; - objupdate.ObjectData[0].FullID = avatarID; - objupdate.ObjectData[0].ParentID = parentID; + objupdate.ObjectData[0].ID = data.avatarLocalID; + objupdate.ObjectData[0].FullID = data.avatarID; + objupdate.ObjectData[0].ParentID = data.parentID; objupdate.ObjectData[0].NameValue = - Utils.StringToBytes("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName + "\nTitle STRING RW SV " + grouptitle); + Utils.StringToBytes("FirstName STRING RW SV " + data.firstName + "\nLastName STRING RW SV " + data.lastName + "\nTitle STRING RW SV " + data.grouptitle); - Vector3 pos2 = new Vector3(Pos.X, Pos.Y, Pos.Z); + Vector3 pos2 = new Vector3(data.Pos.X, data.Pos.Y, data.Pos.Z); byte[] pb = pos2.GetBytes(); Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); - byte[] rot = rotation.GetBytes(); + byte[] rot = data.rotation.GetBytes(); Array.Copy(rot, 0, objupdate.ObjectData[0].ObjectData, 52, rot.Length); objupdate.Header.Zerocoded = true; @@ -3426,38 +3381,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Send a terse positional/rotation/velocity update about an avatar /// to the client. This avatar can be that of the client itself. /// - public virtual void SendAvatarTerseUpdate(ulong regionHandle, - ushort timeDilation, uint localID, Vector3 position, - Vector3 velocity, Quaternion rotation, UUID agentid) + public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) { + if (data.priority == double.NaN) + { + m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update"); + return; + } + + Quaternion rotation = data.rotation; + if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) rotation = Quaternion.Identity; ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = - CreateAvatarImprovedBlock(localID, position, velocity,rotation); + CreateAvatarImprovedBlock(data.localID, data.position, data.velocity, rotation); - lock (m_avatarTerseUpdates_.SyncRoot) - { - m_avatarTerseUpdates_.Enqueue(DateTime.Now.ToOADate(), terseBlock, localID); - - // If packet is full or own movement packet, send it. - if (m_avatarTerseUpdates_.Count >= m_avatarTerseUpdatesPerPacket) - { - ProcessAvatarTerseUpdates(this, null); - } - else if (m_avatarTerseUpdates_.Count == 1) - { - lock (m_avatarTerseUpdateTimer) - m_avatarTerseUpdateTimer.Start(); - } - } + lock (m_avatarTerseUpdates.SyncRoot) + m_avatarTerseUpdates.Enqueue(data.priority, terseBlock, data.localID); } - private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e) + private void ProcessAvatarTerseUpdates() { - lock (m_avatarTerseUpdates_.SyncRoot) + lock (m_avatarTerseUpdates.SyncRoot) { ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); @@ -3468,8 +3416,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP (ushort)(Scene.TimeDilation * ushort.MaxValue); int max = m_avatarTerseUpdatesPerPacket; - if (max > m_avatarTerseUpdates_.Count) - max = m_avatarTerseUpdates_.Count; + if (max > m_avatarTerseUpdates.Count) + max = m_avatarTerseUpdates.Count; int count = 0; int size = 0; @@ -3482,12 +3430,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (count = 0 ; count < max ; count++) { int length = 0; - m_avatarTerseUpdates_.Peek().ToBytes(blockbuffer, ref length); + m_avatarTerseUpdates.Peek().ToBytes(blockbuffer, ref length); length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); if (size + length > Packet.MTU) break; size += length; - updates.Enqueue(m_avatarTerseUpdates_.Dequeue()); + updates.Enqueue(m_avatarTerseUpdates.Dequeue()); } terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; @@ -3497,14 +3445,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP terse.Header.Reliable = false; terse.Header.Zerocoded = true; - // FIXME: Move this to ThrottleOutPacketType.State when the real prioritization code is committed - OutPacket(terse, ThrottleOutPacketType.Task); - if (m_avatarTerseUpdates_.Count == 0) - { - lock (m_avatarTerseUpdateTimer) - m_avatarTerseUpdateTimer.Stop(); - } + OutPacket(terse, ThrottleOutPacketType.State); } } @@ -3569,54 +3511,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(attach, ThrottleOutPacketType.Task); } - public void SendPrimitiveToClient( - ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, - Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, - uint flags, UUID objectID, UUID ownerID, string text, byte[] color, - uint parentID, byte[] particleSystem, byte clickAction, byte material) + public void SendPrimitiveToClient(SendPrimitiveData data) { - byte[] textureanim = new byte[0]; + if (data.priority == double.NaN) + { + m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update"); + return; + } - SendPrimitiveToClient(regionHandle, timeDilation, localID, primShape, pos, vel, - acc, rotation, rvel, flags, - objectID, ownerID, text, color, parentID, particleSystem, - clickAction, material, textureanim, false, 0, UUID.Zero, UUID.Zero, 0, 0, 0); - } + Quaternion rotation = data.rotation; - public void SendPrimitiveToClient( - ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, - Vector3 pos, Vector3 velocity, Vector3 acceleration, Quaternion rotation, Vector3 rotational_velocity, - uint flags, - UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, - byte clickAction, byte material, byte[] textureanim, bool attachment, uint AttachPoint, UUID AssetId, UUID SoundId, double SoundGain, byte SoundFlags, double SoundRadius) - { - - if (AttachPoint > 30 && ownerID != AgentId) // Someone else's HUD + if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD return; - if (primShape.PCode == 9 && primShape.State != 0 && parentID == 0) + if (data.primShape.PCode == 9 && data.primShape.State != 0 && data.parentID == 0) return; - if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) + if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0.0f) rotation = Quaternion.Identity; - ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(primShape, flags); - - objectData.ID = localID; - objectData.FullID = objectID; - objectData.OwnerID = ownerID; - - objectData.Text = Util.StringToBytes256(text); - objectData.TextColor[0] = color[0]; - objectData.TextColor[1] = color[1]; - objectData.TextColor[2] = color[2]; - objectData.TextColor[3] = color[3]; - objectData.ParentID = parentID; - objectData.PSBlock = particleSystem; - objectData.ClickAction = clickAction; - objectData.Material = material; + ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data.primShape, data.flags); + + objectData.ID = data.localID; + objectData.FullID = data.objectID; + objectData.OwnerID = data.ownerID; + + objectData.Text = Util.StringToBytes256(data.text); + objectData.TextColor[0] = data.color[0]; + objectData.TextColor[1] = data.color[1]; + objectData.TextColor[2] = data.color[2]; + objectData.TextColor[3] = data.color[3]; + objectData.ParentID = data.parentID; + objectData.PSBlock = data.particleSystem; + objectData.ClickAction = data.clickAction; + objectData.Material = data.material; objectData.Flags = 0; - if (attachment) + if (data.attachment) { // Necessary??? objectData.JointAxisOrAnchor = new Vector3(0, 0, 2); @@ -3624,14 +3554,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Item from inventory??? objectData.NameValue = - Utils.StringToBytes("AttachItemID STRING RW SV " + AssetId.Guid); - objectData.State = (byte)((AttachPoint % 16) * 16 + (AttachPoint / 16)); + Utils.StringToBytes("AttachItemID STRING RW SV " + data.AssetId.Guid); + objectData.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16)); } // Xantor 20080528: Send sound info as well // Xantor 20080530: Zero out everything if there's no SoundId, so zerocompression will work again - objectData.Sound = SoundId; - if (SoundId == UUID.Zero) + objectData.Sound = data.SoundId; + if (data.SoundId == UUID.Zero) { objectData.OwnerID = UUID.Zero; objectData.Gain = 0.0f; @@ -3640,39 +3570,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - objectData.OwnerID = ownerID; - objectData.Gain = (float)SoundGain; - objectData.Radius = (float)SoundRadius; - objectData.Flags = SoundFlags; + objectData.OwnerID = data.ownerID; + objectData.Gain = (float)data.SoundVolume; + objectData.Radius = (float)data.SoundRadius; + objectData.Flags = data.SoundFlags; } - byte[] pb = pos.GetBytes(); - Array.Copy(pb, 0, objectData.ObjectData, 0, pb.Length); + byte[] pb = data.pos.GetBytes(); + Buffer.BlockCopy(pb, 0, objectData.ObjectData, 0, pb.Length); - byte[] vel = velocity.GetBytes(); - Array.Copy(vel, 0, objectData.ObjectData, pb.Length, vel.Length); + byte[] vel = data.vel.GetBytes(); + Buffer.BlockCopy(vel, 0, objectData.ObjectData, pb.Length, vel.Length); byte[] rot = rotation.GetBytes(); - Array.Copy(rot, 0, objectData.ObjectData, 36, rot.Length); + Buffer.BlockCopy(rot, 0, objectData.ObjectData, 36, rot.Length); - byte[] rvel = rotational_velocity.GetBytes(); - Array.Copy(rvel, 0, objectData.ObjectData, 36 + rot.Length, rvel.Length); + byte[] rvel = data.rvel.GetBytes(); + Buffer.BlockCopy(rvel, 0, objectData.ObjectData, 36 + rot.Length, rvel.Length); - if (textureanim.Length > 0) + if (data.textureanim.Length > 0) { - objectData.TextureAnim = textureanim; + objectData.TextureAnim = data.textureanim; } - lock (m_primFullUpdates_.SyncRoot) - { - if (m_primFullUpdates_.Count == 0) - m_primFullUpdateTimer.Start(); - - m_primFullUpdates_.Enqueue(DateTime.Now.ToOADate(), objectData, localID); - - if (m_primFullUpdates_.Count >= m_primFullUpdatesPerPacket) - ProcessPrimFullUpdates(this, null); - } + lock (m_primFullUpdates.SyncRoot) + m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); } void HandleQueueEmpty(ThrottleOutPacketType queue) @@ -3682,6 +3604,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP case ThrottleOutPacketType.Texture: ProcessTextureRequests(); break; + case ThrottleOutPacketType.State: + int count = 0; + + lock (m_avatarTerseUpdates.SyncRoot) + count = m_avatarTerseUpdates.Count; + if (count > 0) + { + ProcessAvatarTerseUpdates(); + return; + } + + lock (m_primFullUpdates.SyncRoot) + count = m_primFullUpdates.Count; + if (count > 0) + { + ProcessPrimFullUpdates(); + return; + } + + lock (m_primTerseUpdates.SyncRoot) + count = m_primTerseUpdates.Count; + if (count > 0) + { + ProcessPrimTerseUpdates(); + return; + } + break; } } @@ -3691,18 +3640,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_imageManager.ProcessImageQueue(m_textureSendLimit); } - void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) + void ProcessPrimFullUpdates() { - lock (m_primFullUpdates_.SyncRoot) + lock (m_primFullUpdates.SyncRoot) { - if (m_primFullUpdates_.Count == 0 && m_primFullUpdateTimer.Enabled) - { - lock (m_primFullUpdateTimer) - m_primFullUpdateTimer.Stop(); - - return; - } - ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket( PacketType.ObjectUpdate); @@ -3712,7 +3653,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); - int max = m_primFullUpdates_.Count; + int max = m_primFullUpdates.Count; if (max > m_primFullUpdatesPerPacket) max = m_primFullUpdatesPerPacket; @@ -3727,12 +3668,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (count = 0 ; count < max ; count++) { int length = 0; - m_primFullUpdates_.Peek().ToBytes(blockbuffer, ref length); + m_primFullUpdates.Peek().ToBytes(blockbuffer, ref length); length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); if (size + length > Packet.MTU) break; size += length; - updates.Enqueue(m_primFullUpdates_.Dequeue()); + updates.Enqueue(m_primFullUpdates.Dequeue()); } outPacket.ObjectData = @@ -3743,53 +3684,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP outPacket.Header.Zerocoded = true; OutPacket(outPacket, ThrottleOutPacketType.State); - - if (m_primFullUpdates_.Count == 0 && m_primFullUpdateTimer.Enabled) - lock (m_primFullUpdateTimer) - m_primFullUpdateTimer.Stop(); } } /// /// /// - public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, - Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint) + //public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, + // Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint) + public void SendPrimTerseUpdate(SendPrimitiveTerseData data) { - if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD + if (data.priority == double.NaN) + { + m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); + return; + } + + Quaternion rotation = data.rotation; + + if (data.attachPoint > 30 && data.owner != AgentId) // Someone else's HUD return; if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) rotation = Quaternion.Identity; ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = - CreatePrimImprovedBlock(localID, position, rotation, - velocity, rotationalvelocity, state); - - lock (m_primTerseUpdates_.SyncRoot) - { - if (m_primTerseUpdates_.Count == 0) - m_primTerseUpdateTimer.Start(); - - m_primTerseUpdates_.Enqueue(DateTime.Now.ToOADate(), objectData, localID); + CreatePrimImprovedBlock(data.localID, data.position, rotation, + data.velocity, data.rotationalvelocity, data.state); - if (m_primTerseUpdates_.Count >= m_primTerseUpdatesPerPacket) - ProcessPrimTerseUpdates(this, null); - } + lock (m_primTerseUpdates.SyncRoot) + m_primTerseUpdates.Enqueue(data.priority, objectData, data.localID); } - void ProcessPrimTerseUpdates(object sender, ElapsedEventArgs e) + void ProcessPrimTerseUpdates() { - lock (m_primTerseUpdates_.SyncRoot) + lock (m_primTerseUpdates.SyncRoot) { - if (m_primTerseUpdates_.Count == 0) - { - lock (m_primTerseUpdateTimer) - m_primTerseUpdateTimer.Stop(); - - return; - } - ImprovedTerseObjectUpdatePacket outPacket = (ImprovedTerseObjectUpdatePacket) PacketPool.Instance.GetPacket( @@ -3800,7 +3730,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); - int max = m_primTerseUpdates_.Count; + int max = m_primTerseUpdates.Count; if (max > m_primTerseUpdatesPerPacket) max = m_primTerseUpdatesPerPacket; @@ -3815,12 +3745,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (count = 0 ; count < max ; count++) { int length = 0; - m_primTerseUpdates_.Peek().ToBytes(blockbuffer, ref length); + m_primTerseUpdates.Peek().ToBytes(blockbuffer, ref length); length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); if (size + length > Packet.MTU) break; size += length; - updates.Enqueue(m_primTerseUpdates_.Dequeue()); + updates.Enqueue(m_primTerseUpdates.Dequeue()); } outPacket.ObjectData = @@ -3833,26 +3763,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP outPacket.Header.Reliable = false; outPacket.Header.Zerocoded = true; OutPacket(outPacket, ThrottleOutPacketType.State); - - if (m_primTerseUpdates_.Count == 0) - lock (m_primTerseUpdateTimer) - m_primTerseUpdateTimer.Stop(); } } public void FlushPrimUpdates() { - while (m_primFullUpdates_.Count > 0) + while (m_primFullUpdates.Count > 0) { - ProcessPrimFullUpdates(this, null); + ProcessPrimFullUpdates(); } - while (m_primTerseUpdates_.Count > 0) + while (m_primTerseUpdates.Count > 0) { - ProcessPrimTerseUpdates(this, null); + ProcessPrimTerseUpdates(); } - while (m_avatarTerseUpdates_.Count > 0) + while (m_avatarTerseUpdates.Count > 0) { - ProcessAvatarTerseUpdates(this, null); + ProcessAvatarTerseUpdates(); } } -- cgit v1.1