////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Callback Dispatch Comments: PWB: Callbacks to the controller from the JetterCommManager MUST be delgated to the WPF thread // that handles the UI for the _game_stage - otherwise the WPF game_stage objects are not accessable // the program will crash. So we use a pattern that bundles up the arguments and has // the WPF engine call a "dispatch method" with the arguments on the UI thread. // MSDN BeginInvoke exanple info: http://msdn.microsoft.com/en-us/library/ms741870.aspx // Also intresting: http://stackoverflow.com/questions/1207832/wpf-dispatcher-begininvoke-and-ui-background-threads /////////////////////////////////////////////////////////////////////// public void PilotRequest(string from_pilot, PilotCommand pilot_command) { // NOTE: See "Callback Dispatch Comments" for explanation of the dispatch pattern and why it is needed. // Bundle up the arguments. PilotRequest_DispatchDelegateArgs args = new PilotRequest_DispatchDelegateArgs(from_pilot, pilot_command); // Delegate the work such that the UI thread of the game_stage calls the XXX_Dispatch() method // to do the actual work. _game_stage.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new PilotRequest_DispatchDelegate(PilotRequest_Dispatch), this, new object[] { args }); }
private void PilotRequest_Dispatch(object sender, PilotRequest_DispatchDelegateArgs args) { string trace_msg = "Pilot request: from: " + args.from_pilot + " cmd: " + args.pilot_command.command.ToString(); Trace.WriteLine(trace_msg); PilotControllerInfo pilot_info = null; pilot_dictionary.TryGetValue(args.from_pilot, out pilot_info); if (pilot_info != null) { pilot_info.actor.Sprite.PilotRequest(args.pilot_command); } else { string msg = "!!! Controller could not find pilot: " + args.from_pilot; Trace.WriteLine(msg); } }