/// <summary> /// Raises and handles the <see cref="Window.ContentRendered"/> event.</summary> /// <param name="args"> /// An <see cref="EventArgs"/> object containing event data.</param> /// <remarks><para> /// <b>OnContentRendered</b> raises the <see cref="Window.ContentRendered"/> event by /// calling the base class implementation of <see cref="Window.OnContentRendered"/>. /// </para><para> /// <b>OnContentRendered</b> then handles the <see cref="Window.ContentRendered"/> event by /// starting a background thread that attempts to open the XML scenario or session /// description file supplied to the constructor. The background thread will raise the <see /// cref="TaskEvents.TaskComplete"/> event when the operation has completed. /// </para></remarks> protected override void OnContentRendered(EventArgs args) { base.OnContentRendered(args); // show activity message on status bar MainWindow.Instance.StatusMessage.Push(this._openScenario ? Global.Strings.StatusScenarioStarting : Global.Strings.StatusGameOpening); // set progress bar range StatusProgress.Minimum = 0; StatusProgress.Maximum = (this._openScenario ? 13 : 16); // attach task events to dialog methods this._threadEvents = new TaskEvents(Dispatcher); this._threadEvents.TaskMessage += ((sender, e) => StatusInfo.Text = e.Value); this._threadEvents.TaskProgress += ((sender, e) => StatusProgress.Value += e.Value); this._threadEvents.TaskComplete += ((sender, e) => { this._thread.Join(500); this._thread = null; Close(); }); // create and start background thread this._thread = new Thread(new ThreadStart(ThreadMain)); this._thread.IsBackground = true; this._thread.Name = "CreateSession"; this._thread.Start(); }
private IEnumerable <string> CheckTaskEvents(string solutionDirectory, TaskEvents taskEvents) { var errors = new List <string>(); var preMessages = taskEvents.Messages .SkipWhile(m => !Equals(m.Message, "Adaptation: DefinitionLibrary.Assembly.AllAttribute")) .TakeWhile(m => !Equals(m.Message, "------------")) .ToList(); errors.AddRange(preMessages.AssertContains(1, @"|Simple string|")); errors.AddRange(preMessages.AssertContains(1, @"|AnyCPU|")); errors.AddRange(preMessages.AssertContains(1, $@"|{solutionDirectory}UsageLibrary\|")); errors.AddRange(preMessages.AssertContains(2, $@"|{solutionDirectory}packages\Newtonsoft.Json.10.0.3\|")); errors.AddRange(preMessages.AssertContains(1, @"|Newtonsoft.Json|")); errors.AddRange(preMessages.AssertContains(1, @"|10.0.3.0|")); errors.AddRange(preMessages.AssertContains(1, @"|10.0|")); errors.AddRange(preMessages.AssertContains(1, "|{env}|")); errors.AddRange(preMessages.AssertContains(1, "|{nuget.Newtonsoft}|")); errors.AddRange(preMessages.AssertContains(2, "|" + Environment.GetFolderPath(Environment.SpecialFolder.Windows) + "|")); var preWarnings = taskEvents.Warnings; errors.AddRange(preWarnings.AssertContains(1, "{boo.Platform:2df}")); errors.AddRange(preWarnings.AssertContains(1, "Package 'Newtonsoft' not found")); errors.AddRange(preWarnings.AssertContains(1, "Illegal environment variable")); errors.AddRange(preWarnings.AssertContains(1, "Invalid time option")); errors.AddRange(preWarnings.AssertContains(1, "Invalid uid option")); errors.AddRange(preWarnings.AssertContains(1, "Invalid SpecialFolder option")); errors.AddRange(preWarnings.AssertContains(1, "Not supported 'notexisted' folder")); Assert.AreEqual(7, preWarnings.Count); errors.AddRange(taskEvents.Errors.AssertEmpty()); errors.AddRange(taskEvents.Custom.AssertEmpty()); return(errors); }
/// <summary> /// Returns state after starting. /// </summary> /// <returns></returns> public TaskEventState Start() { if (!Current.Start()) { // if we cannot start, that means it is running or completed switch (Current.State) { case TaskEventState.TaskEventNew: // illegal, should have been able to start from the Start method Console.WriteLine("[ERROR] illegal, should have been able to start from the Start method"); break; case TaskEventState.TaskEventRunning: // illegal Console.WriteLine("[ERROR] illegal, should not try starting a task that was already running"); break; case TaskEventState.TaskEventComplete: // make new, and start it TaskEvents.Add(new TaskEvent()); Current.Start(); break; } } return(Current.State); }
void btnTask_Click(object sender, EventArgs e) { if (sender == btnTasks[0]) { #if (!XBOX) UserInterfaceManager.Cursor = Skin.Cursors["Busy"].Cursor; #endif btnTasks[0].Enabled = false; TaskDialog tmp = new TaskDialog(); tmp.Closing += WindowClosing; tmp.Closed += WindowClosed; Thread.Sleep(2000); // Sleep to demonstrate animated busy cursor tmp.Show(); #if (!XBOX) UserInterfaceManager.Cursor = Skin.Cursors["Default"].Cursor; #endif } else if (sender == btnTasks[1]) { btnTasks[1].Enabled = false; TaskControls tmp = new TaskControls(); tmp.Closing += WindowClosing; tmp.Closed += WindowClosed; tmp.ShowModal(); } else if (sender == btnTasks[2]) { btnTasks[2].Enabled = false; TaskAutoScroll tmp = new TaskAutoScroll(); tmp.Closing += WindowClosing; tmp.Closed += WindowClosed; tmp.Show(); } else if (sender == btnTasks[3]) { btnTasks[3].Enabled = false; Window tmp = (Window)Layout.Load("Window"); tmp.Closing += WindowClosing; tmp.Closed += WindowClosed; //tmp.SearchChildControlByName("btnOk").Click += Central_Click; tmp.Show(); } else if (sender == btnTasks[4]) { btnTasks[4].Enabled = false; TaskEvents tmp = new TaskEvents(); tmp.Closing += WindowClosing; tmp.Closed += WindowClosed; tmp.Show(); } }
/// <summary> /// Silently replays all commands in the original command history up to the specified full /// turn and active faction indices.</summary> /// <param name="turn"> /// The index of the full turn where replay should stop.</param> /// <param name="faction"> /// The index of the faction whose activation during the specified <paramref name="turn"/> /// should stop the replay.</param> /// <param name="events"> /// An optional <see cref="TaskEvents"/> object used for progress display.</param> /// <returns> /// <c>true</c> if all commands in the specified range were successfully replayed, and if /// more commands remain in the original command history; otherwise, <c>false</c>.</returns> /// <remarks><para> /// <b>SilentReplay</b> is called by <see cref="Skip"/> to skip over part of an ongoing /// interactive replay. /// </para><para> /// <b>SilentReplay</b> shows a dialog and returns <c>false</c> when an <see /// cref="InvalidCommandException"/> occurs during command replay.</para></remarks> private bool SilentReplay(int turn, int faction, TaskEvents events) { string progressMessage = Global.Strings.StatusReplayCommandsCount; WorldState worldState = Session.Instance.WorldState; ExecutionContext context = new ExecutionContext(worldState, null, null); IList <Command> commands = this._originalWorldState.History.Commands; /* * We only replay up to the next-to-last command because * there is nothing left to resume after the last command, * and the caller will invoke Stop anyway at this point. */ while (this._commandIndex < commands.Count - 1) { // show running count every 0.5 seconds if (events != null && events.RestartTimer(500L)) { events.OnTaskMessage(this, progressMessage, this._commandIndex + 1, commands.Count); } // fetch next command and increment counter Command command = commands[this._commandIndex++]; try { // attempt to validate & execute command command.Validate(worldState); command.Execute(context); } catch (InvalidCommandException e) { ShowCommandError(e); return(false); } // check if specified turn reached if (command is EndTurnCommand && worldState.CurrentTurn >= turn) { // succeed if specified faction dead or active if (faction >= worldState.Factions.Count || worldState.ActiveFactionIndex >= faction) { return(true); } } } return(false); // no commands left }
public static void executeTask(ITask task, Control controlToHostTask, TaskEvents.TaskEvent_StatusChanged onTaskStatusChange) { if (controlToHostTask != null && controlToHostTask.InvokeRequired) controlToHostTask.Invoke(new EventHandler(delegate { executeTask(task, controlToHostTask, onTaskStatusChange); })); else { task.onTaskStatusChange += onTaskStatusChange; var taskControl = new ascx_Task(new TaskThread(task)); if (controlToHostTask != null) controlToHostTask.Controls.Add(taskControl); taskControl.startTask(); } }
public static void executeTask(ITask task, Control controlToHostTask, TaskEvents.TaskEvent_ResultsObject onTaskExecutionCompletion) { if (controlToHostTask != null && controlToHostTask.InvokeRequired) controlToHostTask.Invoke(new EventHandler(delegate { executeTask(task, controlToHostTask, onTaskExecutionCompletion); })); else { task.onTaskExecutionCompletion += onTaskExecutionCompletion; var taskControl = new ascx_Task(new TaskThread(task)); if (controlToHostTask != null) controlToHostTask.Controls.Add(taskControl); taskControl.startTask(); } }
private void ConnectHooks() { // get events component instance (component) sdeClientEvents = TaskEvents.Instance; var producerConfig = new ProducerConfig { BootstrapServers = serviceUrl }; // Create producers this.taskProducer = new ProducerBuilder <Ignore, SDETaskProto>(producerConfig) .SetValueSerializer(new ProtobufSerializer <SDETaskProto>()) .Build(); this.taskNoteProducer = new ProducerBuilder <Ignore, SDETaskNoteProto>(producerConfig) .SetValueSerializer(new ProtobufSerializer <SDETaskNoteProto>()) .Build(); // register callback when events are triggered sdeClientEvents.onTaskCreateHook += OnTaskCreateHook; sdeClientEvents.onTaskUpdateHook += OnTaskUpdateHook; sdeClientEvents.onTaskCreateHook += OnTaskCreateHook; }
public static void executeTask(ITask task, TaskEvents.TaskEvent_ResultsObject onTaskExecutionCompletion) { executeTask(task, null, onTaskExecutionCompletion); }
public static void executeTask(ITask task, TaskEvents.TaskEvent_StatusChanged onTaskStatusChange) { executeTask(task, null, onTaskStatusChange); }
/// <summary> /// Replays commands starting at the specified full turn and active faction indices. /// </summary> /// <param name="turn"> /// The index of the full turn at which to start interactive replay.</param> /// <param name="faction"> /// The index of the faction whose activation during the specified <paramref name="turn"/> /// should start interactive replay.</param> /// <exception cref="ArgumentOutOfRangeException"><para> /// <paramref name="turn"/> is greater than the <see cref="WorldState.CurrentTurn"/> of the /// current <see cref="Session.WorldState"/>. /// </para><para>-or-</para><para> /// <paramref name="faction"/> is less than zero.</para></exception> /// <exception cref="PropertyValueException"> /// The current session <see cref="Session.State"/> is neither <see /// cref="SessionState.Closed"/>, <see cref="SessionState.Computer"/>, nor <see /// cref="SessionState.Human"/>.</exception> /// <remarks><para> /// <b>Start</b> sets the session <see cref="Session.State"/> to <see /// cref="SessionState.Replay"/> and <see cref="CurrentState"/> to <see /// cref="ReplayState.Play"/>, skips ahead to the specified <paramref name="turn"/> and /// <paramref name="faction"/> indices, and then begins an interactive replay of all /// remaining commands stored in the session's <see cref="WorldState.History"/>. /// </para><para> /// <b>Start</b> shows an informational message and returns immediately if there are no /// commands to replay. /// </para><para> /// If the specified <paramref name="turn"/> is negative, <b>Start</b> shows a <see /// cref="Dialog.ChangeTurn"/> dialog, allowing the user to enter the turn at which to start /// interactive replay. /// </para><para> /// If the specified <paramref name="faction"/> is greater than the number of surviving /// factions at any point while skipping ahead, interactive replay will begin with the first /// active faction during the specified <paramref name="turn"/>.</para></remarks> public void Start(int turn, int faction) { CheckStartState(); Session session = Session.Instance; WorldState world = session.WorldState; if (turn > world.CurrentTurn) { ThrowHelper.ThrowArgumentOutOfRangeExceptionWithFormat( "turn", turn, Tektosyne.Strings.ArgumentGreaterValue, "CurrentTurn"); } if (faction < 0) { ThrowHelper.ThrowArgumentOutOfRangeException( "faction", faction, Tektosyne.Strings.ArgumentNegative); } // show message and quit if no commands to replay if (world.History.Commands.Count == 0) { MessageBox.Show(MainWindow.Instance, Global.Strings.DialogReplayNone, Global.Strings.TitleReplay, MessageBoxButton.OK, MessageBoxImage.Information); return; } if (turn < 0) { // ask user to specify starting turn var dialog = new Dialog.ChangeTurn( world.CurrentTurn, Global.Strings.TitleReplayFromTurn); dialog.Owner = MainWindow.Instance; if (dialog.ShowDialog() != true) { return; } // get turn entered by user turn = dialog.Turn; Debug.Assert(turn >= 0); Debug.Assert(turn <= world.CurrentTurn); } // save current session data this._originalWorldState = session.WorldState; this._originalSelected = Session.MapView.SelectedSite; this._originalState = Session.State; // switch session to Replay state Session.State = SessionState.Replay; // show replay control message... MainWindow.Instance.StatusMessage.Push(Global.Strings.StatusReplay); // ...but wait for new world state MainWindow.Instance.BeginWait(Global.Strings.StatusReplayCommands); MainWindow.Instance.StatusMessage.Push(); TaskEvents events = new TaskEvents(Application.Current.Dispatcher); events.TaskMessage += ((sender, args) => MainWindow.Instance.StatusMessage.Text = args.Value); try { // create world state from scenario WorldState worldState = new WorldState(); worldState.Initialize(events); // copy original turn count worldState.History.CopyFullTurns(this._originalWorldState.History); session.WorldState = worldState; } finally { MainWindow.Instance.StatusMessage.Pop(); MainWindow.Instance.EndWait(); } AsyncAction.Run(delegate { // skip to specified turn & faction this._commandIndex = 0; if (turn > 0 || faction > 0) { Skip(turn, faction); } // set default map view to new world state AsyncAction.Invoke(() => Session.MapView.WorldState = session.WorldState); // show active faction's home if not skipped if (this._commandIndex == 0) { ShowFaction(session.WorldState.ActiveFaction); } // enter Play state CurrentState = ReplayState.Play; PlayCommands(); }); }
/// <summary> /// Skips ahead to the specified full turn and active faction indices.</summary> /// <param name="turn"> /// The index of the full turn at which to resume interactive replay.</param> /// <param name="faction"> /// The index of the faction whose activation during the specified <paramref name="turn"/> /// should resume interactive replay.</param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="faction"/> is less than zero.</exception> /// <exception cref="PropertyValueException"> /// The current session <see cref="Session.State"/> is not <see /// cref="SessionState.Replay"/>.</exception> /// <remarks><para> /// <b>Skip</b> performs one of the following actions, depending on the specified <paramref /// name="turn"/> index: /// </para><list type="table"><listheader> /// <term><paramref name="turn"/></term><description>Action</description> /// </listheader><item> /// <term>Less than zero</term> /// <description>Silently execute history commands until the next <see /// cref="EndTurnCommand"/> was executed.</description> /// </item><item> /// <term>Less than or equal to the index of the currently replayed turn</term> /// <description>Do nothing.</description> /// </item><item> /// <term>Less than the maximum turn index in the current game</term> /// <description>Silently execute history commands until the index of the currently replayed /// turn equals <paramref name="turn"/>.</description> /// </item><item> /// <term>Greater than the maximum turn index in the current game</term> /// <description>Call <see cref="Stop"/>.</description> /// </item></list><para> /// If the specified <paramref name="faction"/> index is less than the number of surviving /// <see cref="WorldState.Factions"/> when interactive replay would normally resume, /// <b>Skip</b> continues to silently execute history commands until the faction with the /// specified index has been activated. Otherwise, the <paramref name="faction"/> parameter /// is ignored. /// </para><para> /// <b>Skip</b> also sets the <see cref="CurrentState"/> to <see cref="ReplayState.Skip"/> /// during execution, then back to <see cref="ReplayState.Play"/> when finished. <b>Skip</b> /// calls <see cref="Stop"/> instead if an error occurred, or if the command history is /// already exhausted.</para></remarks> private void Skip(int turn, int faction) { if (Session.State != SessionState.Replay) { ThrowHelper.ThrowPropertyValueExceptionWithFormat("Session.State", Session.State, Tektosyne.Strings.PropertyNotValue, SessionState.Replay); } if (faction < 0) { ThrowHelper.ThrowArgumentOutOfRangeException( "faction", faction, Tektosyne.Strings.ArgumentNegative); } WorldState world = Session.Instance.WorldState; // reset faction to zero if already dead if (faction >= world.Factions.Count) { faction = 0; } // do nothing if specified turn & faction reached if ((turn >= 0 && turn < world.CurrentTurn) || (turn == world.CurrentTurn && world.ActiveFactionIndex >= faction)) { return; } // stop immediately if unreachable turn specified if (turn > this._originalWorldState.CurrentTurn) { Stop(); return; } // enter Skip state CurrentState = ReplayState.Skip; // clear pending command, if any this._command = null; // suspend interactive replay AsyncAction.Invoke(delegate { MainWindow.Instance.BeginWait(Global.Strings.StatusReplayCommands); MainWindow.Instance.StatusMessage.Push(); }); TaskEvents events = new TaskEvents(Application.Current.Dispatcher); events.TaskMessage += ((sender, args) => MainWindow.Instance.StatusMessage.Text = args.Value); try { // skip forward to specified turn & faction bool resume = SilentReplay(turn, faction, events); if (resume) { // show active faction's home site ShowFaction(world.ActiveFaction); // update map view if replay visible if (world == Session.MapView.WorldState) { AsyncAction.Invoke(Session.MapView.Redraw); } // enter Play state CurrentState = ReplayState.Play; return; } } finally { AsyncAction.Invoke(delegate { MainWindow.Instance.StatusMessage.Pop(); MainWindow.Instance.EndWait(); }); } Stop(); // end of history or error }
public Hooks() { sdeClientEvents = TaskEvents.Instance; }