Reuse the same AgentUpdateArgs object for each AgentUpdate UDP packet (of which there are 10 a second) rather than constructing a new one every time.
We can do this because AgentUpdate packets are handled synchronously.0.7.4-extended
							parent
							
								
									73c2db9e8f
								
							
						
					
					
						commit
						8726748e22
					
				|  | @ -91,8 +91,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP | ||||||
|         public event ObjectDeselect OnObjectDetach; |         public event ObjectDeselect OnObjectDetach; | ||||||
|         public event ObjectDrop OnObjectDrop; |         public event ObjectDrop OnObjectDrop; | ||||||
|         public event Action<IClientAPI, bool> OnCompleteMovementToRegion; |         public event Action<IClientAPI, bool> OnCompleteMovementToRegion; | ||||||
|  | 
 | ||||||
|  |         /// <summary> | ||||||
|  |         /// Called when an AgentUpdate message is received and before OnAgentUpdate. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// Listeners must not retain a reference to AgentUpdateArgs since this object is reused for subsequent AgentUpdates. | ||||||
|  |         /// </remarks> | ||||||
|         public event UpdateAgent OnPreAgentUpdate; |         public event UpdateAgent OnPreAgentUpdate; | ||||||
|  | 
 | ||||||
|  |         /// <summary> | ||||||
|  |         /// Called when an AgentUpdate message is received and after OnPreAgentUpdate. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// Listeners must not retain a reference to AgentUpdateArgs since this object is reused for subsequent AgentUpdates. | ||||||
|  |         /// </remarks> | ||||||
|         public event UpdateAgent OnAgentUpdate; |         public event UpdateAgent OnAgentUpdate; | ||||||
|  | 
 | ||||||
|         public event AgentRequestSit OnAgentRequestSit; |         public event AgentRequestSit OnAgentRequestSit; | ||||||
|         public event AgentSit OnAgentSit; |         public event AgentSit OnAgentSit; | ||||||
|         public event AvatarPickerRequest OnAvatarPickerRequest; |         public event AvatarPickerRequest OnAvatarPickerRequest; | ||||||
|  | @ -346,7 +361,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | ||||||
|         private int m_moneyBalance; |         private int m_moneyBalance; | ||||||
|         private int m_animationSequenceNumber = 1; |         private int m_animationSequenceNumber = 1; | ||||||
|         private bool m_SendLogoutPacketWhenClosing = true; |         private bool m_SendLogoutPacketWhenClosing = true; | ||||||
|         private AgentUpdateArgs lastarg; | 
 | ||||||
|  |         /// <summary> | ||||||
|  |         /// We retain a single AgentUpdateArgs so that we can constantly reuse it rather than construct a new one for | ||||||
|  |         /// every single incoming AgentUpdate.  Every client sends 10 AgentUpdate UDP messages per second, even if it | ||||||
|  |         /// is doing absolutely nothing. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods | ||||||
|  |         /// cannot retain a reference to it outside of that method. | ||||||
|  |         /// </remarks> | ||||||
|  |         private AgentUpdateArgs m_lastAgentUpdateArgs; | ||||||
| 
 | 
 | ||||||
|         protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); |         protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); | ||||||
|         protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers |         protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers | ||||||
|  | @ -5197,7 +5222,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | ||||||
|         protected virtual void RegisterLocalPacketHandlers() |         protected virtual void RegisterLocalPacketHandlers() | ||||||
|         { |         { | ||||||
|             AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout); |             AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout); | ||||||
|  | 
 | ||||||
|  |             // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs | ||||||
|  |             // for each AgentUpdate packet. | ||||||
|             AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); |             AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); | ||||||
|  |              | ||||||
|             AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); |             AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); | ||||||
|             AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); |             AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); | ||||||
|             AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); |             AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); | ||||||
|  | @ -5428,73 +5457,71 @@ namespace OpenSim.Region.ClientStack.LindenUDP | ||||||
|         { |         { | ||||||
|             if (OnAgentUpdate != null) |             if (OnAgentUpdate != null) | ||||||
|             { |             { | ||||||
|                 bool update = false; |                 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet; | ||||||
|                 AgentUpdatePacket agenUpdate = (AgentUpdatePacket)packet; |  | ||||||
| 
 | 
 | ||||||
|                 #region Packet Session and User Check |                 #region Packet Session and User Check | ||||||
|                 if (agenUpdate.AgentData.SessionID != SessionId || agenUpdate.AgentData.AgentID != AgentId) |                 if (agentUpdate.AgentData.SessionID != SessionId || agentUpdate.AgentData.AgentID != AgentId) | ||||||
|                 { |                 { | ||||||
|                     PacketPool.Instance.ReturnPacket(packet); |                     PacketPool.Instance.ReturnPacket(packet); | ||||||
|                     return false; |                     return false; | ||||||
|                 } |                 } | ||||||
|                 #endregion |                 #endregion | ||||||
| 
 | 
 | ||||||
|                 AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData; |                 bool update = false; | ||||||
|  |                 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; | ||||||
| 
 | 
 | ||||||
|                 // We can only check when we have something to check |                 if (m_lastAgentUpdateArgs != null) | ||||||
|                 // against. |  | ||||||
| 
 |  | ||||||
|                 if (lastarg != null) |  | ||||||
|                 { |                 { | ||||||
|  |                     // These should be ordered from most-likely to | ||||||
|  |                     // least likely to change. I've made an initial | ||||||
|  |                     // guess at that. | ||||||
|                     update = |                     update = | ||||||
|                        ( |                        ( | ||||||
|                         (x.BodyRotation != lastarg.BodyRotation) || |                         (x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) || | ||||||
|                         (x.CameraAtAxis != lastarg.CameraAtAxis) || |                         (x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) || | ||||||
|                         (x.CameraCenter != lastarg.CameraCenter) || |                         (x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) || | ||||||
|                         (x.CameraLeftAxis != lastarg.CameraLeftAxis) || |                         (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || | ||||||
|                         (x.CameraUpAxis != lastarg.CameraUpAxis) || |                         (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || | ||||||
|                         (x.ControlFlags != lastarg.ControlFlags) || |                         (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || | ||||||
|                         (x.Far != lastarg.Far) || |                         (x.Far != m_lastAgentUpdateArgs.Far) || | ||||||
|                         (x.Flags != lastarg.Flags) || |                         (x.Flags != m_lastAgentUpdateArgs.Flags) || | ||||||
|                         (x.State != lastarg.State) || |                         (x.State != m_lastAgentUpdateArgs.State) || | ||||||
|                         (x.HeadRotation != lastarg.HeadRotation) || |                         (x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) || | ||||||
|                         (x.SessionID != lastarg.SessionID) || |                         (x.SessionID != m_lastAgentUpdateArgs.SessionID) || | ||||||
|                         (x.AgentID != lastarg.AgentID) |                         (x.AgentID != m_lastAgentUpdateArgs.AgentID) | ||||||
|                        ); |                        ); | ||||||
|                 } |                 } | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|  |                     m_lastAgentUpdateArgs = new AgentUpdateArgs(); | ||||||
|                     update = true; |                     update = true; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 // These should be ordered from most-likely to |  | ||||||
|                 // least likely to change. I've made an initial |  | ||||||
|                 // guess at that. |  | ||||||
| 
 |  | ||||||
|                 if (update) |                 if (update) | ||||||
|                 { |                 { | ||||||
| //                    m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name); | //                    m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name); | ||||||
| 
 | 
 | ||||||
|                     AgentUpdateArgs arg = new AgentUpdateArgs(); |                     m_lastAgentUpdateArgs.AgentID = x.AgentID; | ||||||
|                     arg.AgentID = x.AgentID; |                     m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation; | ||||||
|                     arg.BodyRotation = x.BodyRotation; |                     m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis; | ||||||
|                     arg.CameraAtAxis = x.CameraAtAxis; |                     m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter; | ||||||
|                     arg.CameraCenter = x.CameraCenter; |                     m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis; | ||||||
|                     arg.CameraLeftAxis = x.CameraLeftAxis; |                     m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis; | ||||||
|                     arg.CameraUpAxis = x.CameraUpAxis; |                     m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags; | ||||||
|                     arg.ControlFlags = x.ControlFlags; |                     m_lastAgentUpdateArgs.Far = x.Far; | ||||||
|                     arg.Far = x.Far; |                     m_lastAgentUpdateArgs.Flags = x.Flags; | ||||||
|                     arg.Flags = x.Flags; |                     m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation; | ||||||
|                     arg.HeadRotation = x.HeadRotation; |                     m_lastAgentUpdateArgs.SessionID = x.SessionID; | ||||||
|                     arg.SessionID = x.SessionID; |                     m_lastAgentUpdateArgs.State = x.State; | ||||||
|                     arg.State = x.State; | 
 | ||||||
|                     UpdateAgent handlerAgentUpdate = OnAgentUpdate; |                     UpdateAgent handlerAgentUpdate = OnAgentUpdate; | ||||||
|                     UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; |                     UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; | ||||||
|                     lastarg = arg; // save this set of arguments for nexttime | 
 | ||||||
|                     if (handlerPreAgentUpdate != null) |                     if (handlerPreAgentUpdate != null) | ||||||
|                         OnPreAgentUpdate(this, arg); |                         OnPreAgentUpdate(this, m_lastAgentUpdateArgs); | ||||||
|  | 
 | ||||||
|                     if (handlerAgentUpdate != null) |                     if (handlerAgentUpdate != null) | ||||||
|                         OnAgentUpdate(this, arg); |                         OnAgentUpdate(this, m_lastAgentUpdateArgs); | ||||||
| 
 | 
 | ||||||
|                     handlerAgentUpdate = null; |                     handlerAgentUpdate = null; | ||||||
|                     handlerPreAgentUpdate = null; |                     handlerPreAgentUpdate = null; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Justin Clark-Casey (justincc)
						Justin Clark-Casey (justincc)