passing events from GameEntities to GameWindow 



The common problem is that GameEntities like Dynamic are visible to GameWindow so accesing Dynamics from GameWindow is no problem.

However if you want to access GameWindow from Dynamic that is not so easy. GameWindow is not in any namespace that Dynamic object can even see.

You would want to access GameWindow for many reasons like opening a menu if a Dynamic or Unit dies.

I made a small tutorial where you create events in Dynamic and make ActionGameWindow as the listener for those events. This way every time you fire an event in dynamic ActionGameWindow receives it and can do what ever you like like open new menus or show messageboxes.

For the record I never tested this ;) but at least it compiles ok...


So lets say I want to display a MessageBox every time a Dynamic object dies. I fire the event from Dynamic.OnDie() so every class inherited from dynamic should have this feature too. This includes pretty much every object.

First I create the Event, EventArgs and a delegate which describes what parameters the event handler must be able to take

This is cut from my Dynamic.cs





public class Dynamic : MapObject
{

public static event MessageEventHandler MessageEvent; //the event itself. Made it static so I can hook to it without any Dynamic
public EventArgs e = null; //any parameters I wish to pass with the event
public delegate void MessageEventHandler(Dynamic m, EventArgs e); //what the handler shoud look like

/// <summary>
/// //////////// derived eventargs for message event///////////////////////////
/// </summary>

public class MessageEventArgs : EventArgs
{
//my own event args class

public string message;
}



[FieldSerialize( FieldSerializeSerializationTypes.World )]
float life;

...
...
...



Now I make changes to my ActionGameWindow.cs so mu GameWindow will listen and receive the events from Dynamics.

Actual changes are marked with italic if they are inside existing code



protected override void OnAttach()
{
base.OnAttach();


//register event handler for dynamics
RegisterHandlerMethodsForDynamics();

//To load the HUD screen
hudControl = ControlDeclarationManager.Instance.CreateControl( "Gui\\ActionHUD.gui" );
//Attach the HUD screen to the this window
Controls.Add( hudControl );



2 new methods inside ActionGameWindow.cs



void RegisterHandlerMethodsForDynamics()
{
//register this ActionGameWindow as the listener for Dynamic.MessageEvent

Dynamic.MessageEvent += new Dynamic.MessageEventHandler(MessageEventHandler);

/* what you would add here is all the other handlers for different events like

Dynamic.ChangeMapEvent += new Dynamic.MapChangeEventHandler(ChangeMapEventHandler);


*/
}

void MessageEventHandler(Dynamic m, EventArgs e)
{
// m is the Dynamic that fired the event
// e has anything that dynamic might want to tell me like the text I should show in MessageBox

EControl messagebox = new MessageBoxWindow(((Dynamic.MessageEventArgs)e).message, "Message", null);

//smack the message on my screen

Controls.Add(messagebox);

}



Last thing to do is to fire the event from Dynamic.OnDie()



protected virtual void OnDie( MapObject prejudicial )
{
//disable contacts
if( PhysicsModel != null )
{
foreach( Body body in PhysicsModel.Bodies )
{
foreach( Shape shape in body.Shapes )
shape.ContactGroup = (int)ContactGroup.NoContact;
}
}

//firing the MessageEvent



//make new args

MessageEventArgs mesgArgs = new MessageEventArgs();

//if the killing was done by an actual MapObject fire the event. Otherwise forget it

if (prejudicial != null)
{
mesgArgs.message = this.Type.Name + " was killed by " + prejudicial.Type.Name;

if(MessageEvent != null) // there must be a listener
{
MessageEvent(this, mesgArgs);
}
}



}



Now every time a Dynamic dies a window should pop up.


PS. tested and it works....to some extent....if you don't want to close the messagebox anyway :)

-wellu