/// <summary> /// Send a message directly to an Entity through this method. /// This function MUST be called only from QSGame, otherwise it will never mark the message properly for release /// and it will leak memory. /// </summary> /// <param name="message">Message to send</param> /// <returns>Returns true if message was handled</returns> public virtual bool ExecuteMessage(IMessage message) { switch (message.Type) { case MessageType.GetName: { MsgGetName msgGetName = message as MsgGetName; message.TypeCheck(msgGetName); msgGetName.Name = this.name; } break; case MessageType.GetParentID: { MsgGetParentID msgGetID = message as MsgGetParentID; message.TypeCheck(msgGetID); if (this.parentEntity != null) { msgGetID.ParentEntityID = this.parentEntity.UniqueID; } } break; case MessageType.SetPosition: { MsgSetPosition setPositionMsg = message as MsgSetPosition; message.TypeCheck(setPositionMsg); this.Position = setPositionMsg.Position; } break; case MessageType.ModifyPosition: { MsgModifyPosition modPosMsg = message as MsgModifyPosition; message.TypeCheck(modPosMsg); this.Position += modPosMsg.Position; } break; case MessageType.GetPosition: { MsgGetPosition getPosMsg = message as MsgGetPosition; message.TypeCheck(getPosMsg); getPosMsg.Position = this.position; } break; case MessageType.SetRotation: { MsgSetRotation setRotMsg = message as MsgSetRotation; message.TypeCheck(setRotMsg); this.Rotation = setRotMsg.Rotation; } break; case MessageType.ModifyRotation: { MsgModifyRotation modRotMsg = message as MsgModifyRotation; message.TypeCheck(modRotMsg); this.Rotation *= modRotMsg.Rotation; } break; case MessageType.GetRotation: { MsgGetRotation getRotMsg = message as MsgGetRotation; message.TypeCheck(getRotMsg); getRotMsg.Rotation = this.rotation; } break; case MessageType.GetVectorForward: { MsgGetVectorForward getVectorMsg = message as MsgGetVectorForward; message.TypeCheck(getVectorMsg); getVectorMsg.Forward = this.rotation.Forward; } break; case MessageType.GetVectorUp: { MsgGetVectorUp getVectorMsg = message as MsgGetVectorUp; message.TypeCheck(getVectorMsg); getVectorMsg.Up = this.rotation.Up; } break; case MessageType.GetVectorRight: { MsgGetVectorRight getVectorMsg = message as MsgGetVectorRight; message.TypeCheck(getVectorMsg); getVectorMsg.Right = this.rotation.Right; } break; case MessageType.LookAtPosition: { MsgLookAtPosition setPositionMsg = message as MsgLookAtPosition; message.TypeCheck(setPositionMsg); this.LookAt(setPositionMsg.Position); } break; case MessageType.Pitch: { MsgModifyPitch camPitchMsg = message as MsgModifyPitch; message.TypeCheck(camPitchMsg); Pitch(camPitchMsg.PitchAmount); } break; case MessageType.Yaw: { MsgModifyYaw camYawMsg = message as MsgModifyYaw; message.TypeCheck(camYawMsg); Yaw(camYawMsg.YawAmount); } break; case MessageType.YawWorldUp: { MsgModifyYawWorldUp camYawMsg = message as MsgModifyYawWorldUp; message.TypeCheck(camYawMsg); YawAroundWorldUp(camYawMsg.YawAmount); } break; case MessageType.SetParent: { MsgSetParent msgSetParent = message as MsgSetParent; message.TypeCheck(msgSetParent); SetParent(msgSetParent.ParentEntity); } break; case MessageType.RemoveChild: { MsgRemoveChild msgRemChild = message as MsgRemoveChild; message.TypeCheck(msgRemChild); RemoveChild(msgRemChild.Child); } break; case MessageType.ParentRemoved: { MsgParentRemoved msgParentRem = message as MsgParentRemoved; message.TypeCheck(msgParentRem); if (parentEntity == msgParentRem.Parent) { SetParent(null); } } break; case MessageType.ParentAdded: { MsgParentAdded msgParentAdded = message as MsgParentAdded; message.TypeCheck(msgParentAdded); SetParent(msgParentAdded.Parent); } break; case MessageType.ChildRemoved: { MsgChildRemoved msgChildRem = message as MsgChildRemoved; message.TypeCheck(msgChildRem); if (msgChildRem.Child != null) { this.children.Remove(msgChildRem.Data.UniqueID); } } break; case MessageType.ChildAdded: { MsgChildAdded msgChildAdd = message as MsgChildAdded; message.TypeCheck(msgChildAdd); if (msgChildAdd.Child != null && msgChildAdd.Child != this) { this.children.Add(msgChildAdd.Data.UniqueID, msgChildAdd.Child); } } break; default: return(SendMessageThroughComponents(message)); } // For messages handled directly by the Entity but aren't Request Protocol, // we still pass them to the Entity's components in case those components care. if (message.Protocol != MessageProtocol.Request) { return(SendMessageThroughComponents(message)); } return(true); }
/// <summary> /// Draws the debug scene /// </summary> /// <param name="batch">The <see cref="SpriteBatch"/> to use for 2D drawing.</param> /// <param name="background">The previous screen's output as a texture, if NeedBackgroundAsTexture is true.</param> /// <param name="gameTime">The <see cref="GameTime"/> structure for the current Game.Draw() cycle.</param> public void DrawScreen(SpriteBatch batch, Texture2D background, GameTime gameTime) { // No need to create the string for a closed window if (!this.guiScreen.IsOpen) { return; } // We don't want the window to drag if the cursor is invisible. this.guiScreen.EnableDragging = this.game.IsMouseVisible; if (!this.game.IsMouseVisible) { this.guiScreen.Title = "Stats - F3 to enable cursor"; } else { if (this.guiScreen.Minimized) { this.guiScreen.Title = "Stats - Double-click to Open"; } else { this.guiScreen.Title = "Stats - Double-click to Hide"; } } // Get the current camera's position MsgGetPosition msgGetPos = ObjectPool.Aquire <MsgGetPosition>(); msgGetPos.UniqueTarget = QSGame.SceneMgrRootEntityID; this.game.SendMessage(msgGetPos); MsgGetRotation msgGetRot = ObjectPool.Aquire <MsgGetRotation>(); msgGetRot.UniqueTarget = QSGame.SceneMgrRootEntityID; this.game.SendMessage(msgGetRot); MsgGetName msgName = ObjectPool.Aquire <MsgGetName>(); msgName.UniqueTarget = QSGame.SceneMgrRootEntityID; this.game.SendMessage(msgName); StringBuilder sb = new StringBuilder(); sb.AppendLine("-- On-screen --"); sb.AppendLine("Triangles: " + this.game.Graphics.TrianglesProcessedLastFrame + " -- Geometry chunks: " + this.game.Graphics.GeometryChunksRenderedLastFrame); sb.AppendLine("Particles: " + this.game.Graphics.ParticlesRenderedLastFrame); sb.AppendLine(); sb.AppendLine("Object Pool: "); sb.Append("Types: " + ObjectPool.free.Count); int count = 0; foreach (List <IPoolItem> list in ObjectPool.free.Values) { count += list.Count; } sb.Append(", free: " + count); count = 0; foreach (List <IPoolItem> list in ObjectPool.locked.Values) { count += list.Count; } sb.AppendLine(", locked: " + count); sb.AppendLine(); sb.AppendLine("Messages sent last frame: " + this.game.MessagesSentThisFrame); sb.AppendLine("Number of current messages: " + this.game.currentMessages.Count); sb.AppendLine("Number of queued messages: " + this.game.queuedMessages.Count); sb.AppendLine(" Queued messages:"); for (int i = this.game.queuedMessages.Count - 1; i >= 0; --i) { IMessage message = this.game.queuedMessages[i]; sb.AppendLine(string.Format(" {0} - {1}", message.Type, message.GetType().Name)); } sb.AppendLine(); sb.AppendLine(string.Format("Entities, total: {0}, active: {1}", this.game.SceneManager.Entities.Count, this.game.SceneManager.NumberOfActiveEntities)); sb.AppendLine(); sb.AppendLine("Entity acting as camera: " + msgName.Name); Vector3 camPos = msgGetPos.Position; sb.AppendLine(string.Format("Cam Pos - X: {0:0.00}, Y: {1:0.00}, Z: {2:0.00}", camPos.X, camPos.Y, camPos.Z)); Vector3 camFwd = msgGetRot.Rotation.Forward; sb.AppendLine(string.Format("Cam Fwd - X: {0:0.00}, Y: {1:0.00}, Z: {2:0.00}", camFwd.X, camFwd.Y, camFwd.Z)); MsgGetControlledEntity msgControlled = ObjectPool.Aquire <MsgGetControlledEntity>(); this.game.SendInterfaceMessage(msgControlled, InterfaceType.SceneManager); if (msgControlled.ControlledEntityID != QSGame.UniqueIDEmpty) { MsgGetName msgGetName = ObjectPool.Aquire <MsgGetName>(); msgGetName.UniqueTarget = msgControlled.ControlledEntityID; this.game.SendMessage(msgGetName); sb.AppendLine("Camera attached to: " + msgGetName.Name); } sb.AppendLine(); sb.AppendLine("Keys pressed: "); for (int i = this.keys.Count - 1; i >= 0; --i) { sb.Append(this.keys[i].ToString() + " "); } sb.AppendLine(); this.guiScreen.Label.Text = sb.ToString(); }