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 ObjectDrop OnObjectDrop; | ||||
|         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; | ||||
| 
 | ||||
|         /// <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 AgentRequestSit OnAgentRequestSit; | ||||
|         public event AgentSit OnAgentSit; | ||||
|         public event AvatarPickerRequest OnAvatarPickerRequest; | ||||
|  | @ -346,7 +361,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         private int m_moneyBalance; | ||||
|         private int m_animationSequenceNumber = 1; | ||||
|         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<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() | ||||
|         { | ||||
|             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.ViewerEffect, HandleViewerEffect, false); | ||||
|             AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); | ||||
|             AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); | ||||
|  | @ -5428,73 +5457,71 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         { | ||||
|             if (OnAgentUpdate != null) | ||||
|             { | ||||
|                 bool update = false; | ||||
|                 AgentUpdatePacket agenUpdate = (AgentUpdatePacket)packet; | ||||
|                 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet; | ||||
| 
 | ||||
|                 #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); | ||||
|                     return false; | ||||
|                 } | ||||
|                 #endregion | ||||
| 
 | ||||
|                 AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData; | ||||
|                 bool update = false; | ||||
|                 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; | ||||
| 
 | ||||
|                 // We can only check when we have something to check | ||||
|                 // against. | ||||
| 
 | ||||
|                 if (lastarg != null) | ||||
|                 if (m_lastAgentUpdateArgs != null) | ||||
|                 { | ||||
|                     // These should be ordered from most-likely to | ||||
|                     // least likely to change. I've made an initial | ||||
|                     // guess at that. | ||||
|                     update = | ||||
|                        ( | ||||
|                         (x.BodyRotation != lastarg.BodyRotation) || | ||||
|                         (x.CameraAtAxis != lastarg.CameraAtAxis) || | ||||
|                         (x.CameraCenter != lastarg.CameraCenter) || | ||||
|                         (x.CameraLeftAxis != lastarg.CameraLeftAxis) || | ||||
|                         (x.CameraUpAxis != lastarg.CameraUpAxis) || | ||||
|                         (x.ControlFlags != lastarg.ControlFlags) || | ||||
|                         (x.Far != lastarg.Far) || | ||||
|                         (x.Flags != lastarg.Flags) || | ||||
|                         (x.State != lastarg.State) || | ||||
|                         (x.HeadRotation != lastarg.HeadRotation) || | ||||
|                         (x.SessionID != lastarg.SessionID) || | ||||
|                         (x.AgentID != lastarg.AgentID) | ||||
|                         (x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) || | ||||
|                         (x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) || | ||||
|                         (x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) || | ||||
|                         (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || | ||||
|                         (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || | ||||
|                         (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || | ||||
|                         (x.Far != m_lastAgentUpdateArgs.Far) || | ||||
|                         (x.Flags != m_lastAgentUpdateArgs.Flags) || | ||||
|                         (x.State != m_lastAgentUpdateArgs.State) || | ||||
|                         (x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) || | ||||
|                         (x.SessionID != m_lastAgentUpdateArgs.SessionID) || | ||||
|                         (x.AgentID != m_lastAgentUpdateArgs.AgentID) | ||||
|                        ); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     m_lastAgentUpdateArgs = new AgentUpdateArgs(); | ||||
|                     update = true; | ||||
|                 } | ||||
| 
 | ||||
|                 // These should be ordered from most-likely to | ||||
|                 // least likely to change. I've made an initial | ||||
|                 // guess at that. | ||||
| 
 | ||||
|                 if (update) | ||||
|                 { | ||||
| //                    m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name); | ||||
| 
 | ||||
|                     AgentUpdateArgs arg = new AgentUpdateArgs(); | ||||
|                     arg.AgentID = x.AgentID; | ||||
|                     arg.BodyRotation = x.BodyRotation; | ||||
|                     arg.CameraAtAxis = x.CameraAtAxis; | ||||
|                     arg.CameraCenter = x.CameraCenter; | ||||
|                     arg.CameraLeftAxis = x.CameraLeftAxis; | ||||
|                     arg.CameraUpAxis = x.CameraUpAxis; | ||||
|                     arg.ControlFlags = x.ControlFlags; | ||||
|                     arg.Far = x.Far; | ||||
|                     arg.Flags = x.Flags; | ||||
|                     arg.HeadRotation = x.HeadRotation; | ||||
|                     arg.SessionID = x.SessionID; | ||||
|                     arg.State = x.State; | ||||
|                     m_lastAgentUpdateArgs.AgentID = x.AgentID; | ||||
|                     m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation; | ||||
|                     m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis; | ||||
|                     m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter; | ||||
|                     m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis; | ||||
|                     m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis; | ||||
|                     m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags; | ||||
|                     m_lastAgentUpdateArgs.Far = x.Far; | ||||
|                     m_lastAgentUpdateArgs.Flags = x.Flags; | ||||
|                     m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation; | ||||
|                     m_lastAgentUpdateArgs.SessionID = x.SessionID; | ||||
|                     m_lastAgentUpdateArgs.State = x.State; | ||||
| 
 | ||||
|                     UpdateAgent handlerAgentUpdate = OnAgentUpdate; | ||||
|                     UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; | ||||
|                     lastarg = arg; // save this set of arguments for nexttime | ||||
| 
 | ||||
|                     if (handlerPreAgentUpdate != null) | ||||
|                         OnPreAgentUpdate(this, arg); | ||||
|                         OnPreAgentUpdate(this, m_lastAgentUpdateArgs); | ||||
| 
 | ||||
|                     if (handlerAgentUpdate != null) | ||||
|                         OnAgentUpdate(this, arg); | ||||
|                         OnAgentUpdate(this, m_lastAgentUpdateArgs); | ||||
| 
 | ||||
|                     handlerAgentUpdate = null; | ||||
|                     handlerPreAgentUpdate = null; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Justin Clark-Casey (justincc)
						Justin Clark-Casey (justincc)