OTX-Runtime for DotNet  
Sample Program

The Sample program demonstrates the main functionality of the OTX-Runtime API. It can be used as a reference for the expected runtime behavior of the API and the source code below is like a reference guide about the proper programming of the API.

Code Example

Code snippet of the OTX-Runtime API Sample Program.

7 using OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.OutputCustomImplementation;
8 using OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Setting;
9 using System;
10 using System.Collections.Generic;
11 using System.Diagnostics;
12 using System.Drawing;
13 using System.IO;
14 using System.Linq;
15 using System.Threading;
16 using System.Threading.Tasks;
17 using System.Windows.Forms;
19 
20 namespace OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample
21 {
22  public partial class SampleForm : Form
23  {
24  private const int VALUE_STRING_MAX_LENGTH = 1024;
25 
26  private UserSettings userSettings = UserSettings.Default;
27 
28  // TODO: handle multithreading
29  private List<IRuntimeContext> runtimeContexts = new List<IRuntimeContext>();
30  private Dictionary<IRuntimeContext, DateTime> runtimeContextsExecutionStartTime = new Dictionary<IRuntimeContext, DateTime>();
31 
32  private IProject project = null;
33  private IPlayerProject playerProject = null;
34  private IProcedure procedureToExecute = null;
35 
36  private TreeNode startupNode = null;
37 
38  private IRuntimeManager globalRuntimeManager = null;
39 
40  private HmiWindow hmiWindow;
41 
42  private DateTime lastTime = DateTime.Now;
43 
44  private DefaultCustomScreenImplementation customScreenImplementation;
45  private ContextVariableImplementation contextVariableImplementation;
46 
47  private StateVariableImplementation stateVariableImplementation;
48  private DefaultMeasureImplementation measureImplementation;
49  private DefaultExternalServiceProviderImplementation serviceProviderImplementation;
50 
51  private BasicScreenOutputImpl basicScreenOutputImpl;
52  private CustomScreenOutputImpl customScreenOutputImpl;
53  private LoggingOutputImpl loggingOutputImpl;
54  private ContextVariableOutputImpl contextVariableOutputImpl;
55 
56  private StateVariableOutputImpl stateVariableOutputImpl;
57  private MeasureOutputImpl measureOutputImpl;
58  private I18nOutputImpl i18NOutputImpl;
59  private ExternalServiceProviderOutputImpl serviceProviderOutputImpl;
60 
61  private SqlOutputImpl sqlOutputImpl;
62  private CommonDialogsOutputImpl commonDialogsOutputImpl;
63 
64  private SampleForm creatorForm;
65  private string title;
66  private string runtimeContextName;
67  private long procedureExecutionCount;
68  private long cyclicExecutionCount;
69 
70  private static string fileVersion;
71 
72  private static int defaultPollingTime = 500;
73  private static int defaultBatteryVoltageThreshold = 6000;
74  private bool useConnectionState = false;
75  private bool? KL15State = null;
76  private ExpectedState expectedConnectionState = ExpectedState.None;
77 
78  private bool isLoadding = false;
79 
80  private ushort defaultDiagPort = SampleConstants.DEFAULT_DM_PORT;
81  private ushort defaultRuntimePort = SampleConstants.DEFAULT_RT_PORT;
82  private string defaultDiagPipeName = SampleConstants.DEFAULT_DM_PIPE_NAME;
83  private string defaultRuntimePipeName = SampleConstants.DEFAULT_RT_PIPE_NAME;
84 
85  private readonly object printTextLock = new object();
86  private readonly object eventListenerLock = new object();
87 
88  private bool cyclicExecuteAsyncIsProcessing = false;
89  private System.Windows.Forms.Timer webServerTimer = new System.Windows.Forms.Timer();
90 
91  static SampleForm()
92  {
93  LicenseManager.SetLicenseKey(SampleConstants.LICENSE_KEY);
94  fileVersion = RuntimeConfig.Instance.Version;
95  }
96 
97  public SampleForm(string title = SampleConstants.MAIN_INSTANCE_NAME, SampleForm creatorForm = null)
98  {
99  this.title = title;
100  this.creatorForm = creatorForm;
101 
102  this.webServerTimer.Interval = 1000;
103  this.webServerTimer.Enabled = true;
104  this.webServerTimer.Tick += WebServerTimer_Tick;
105 
106  InitializeComponent();
107 
108  PrintText("Application started");
109  }
110 
111  private void SampleForm_Load(object sender, EventArgs e)
112  {
113  PrintText("Start Initialization...");
114 
115  CreateCustomImpl();
116  InitializeSampleDefaultValues();
117  this.UpdateWebServerButton();
118 
119  if (this.creatorForm != null)
120  {
121  this.checkBoxStartAllParents.Visible = true;
122  this.checkBoxStartAllParents.Checked = this.creatorForm.checkBoxStartAllParents.Checked;
123  }
124 
125  SetRuntimeContextName();
126  SetTitle(this.title);
127  SetLocation(this.creatorForm);
128 
129  this.toolTip1.SetToolTip(labelProcedureExecutionTimes, "Total procedure execution time.");
130  this.toolTip1.SetToolTip(textBoxTimeout, "Timeout for procedure execution in milliseconds. The default value 0 means without timeout.");
131  this.toolTip1.SetToolTip(checkBoxUseConnectionState, "Use expected connection state during procedure execution.");
132  this.toolTip1.SetToolTip(labelBatteryState, "State of the battery (KL 30)");
133  this.toolTip1.SetToolTip(checkBoxIgnition, "Expected ignition (KL 15) state during procedure execution");
134  this.toolTip1.SetToolTip(labelIgnitionState, "State of the ignition (KL 15)");
135  this.toolTip1.SetToolTip(buttonCheckBatteryIgnition, "Check current battery (KL30) and ignition (KL15) state.");
136  this.toolTip1.SetToolTip(textBoxPollingTime, "Time in milliseconds between the next check of the connection state during the procedure execution (Polling). The default value is 500 ms.");
137  this.toolTip1.SetToolTip(textBoxVoltageThreshold, "Voltage threshold in millivolt from which the battery voltage, see GetBatteryVoltage is enough for KL30 = On. The default value is 6000 mV.");
138 
139  PrintText("... Initialization finished.");
140  }
141 
142  private void SampleForm_Shown(object sender, EventArgs e)
143  {
144  this.cbFilePath.SelectionLength = 0;
145  }
146 
147  private void SetRuntimeContextName()
148  {
149  if (this.creatorForm != null && !String.IsNullOrEmpty(this.creatorForm.runtimeContextName))
150  {
151  System.Text.RegularExpressions.Match regExpMatch = System.Text.RegularExpressions.Regex.Match(this.creatorForm.runtimeContextName, @"\d*$");
152  int number;
153  if (int.TryParse(regExpMatch.Value, out number))
154  {
155  number++;
156  this.textBoxRuntimeContextName.Text = this.creatorForm.runtimeContextName.Substring(0, regExpMatch.Index) + number.ToString();
157  }
158  }
159  }
160 
161  private void SetTitle(string title)
162  {
163  if (String.IsNullOrWhiteSpace(title))
164  title = SampleConstants.MAIN_INSTANCE_NAME;
165 
166  bool runningAsAdmin = System.Security.Principal.WindowsIdentity.GetCurrent().Owner.IsWellKnown(System.Security.Principal.WellKnownSidType.BuiltinAdministratorsSid);
167 
168  this.Text = String.Format(
169  "emotive OTX-Runtime API for DotNet - Reference Application - Version {0} - {1} Bit - {2} - Thread-ID {3}{4}",
170  fileVersion,
171  Environment.Is64BitProcess ? "64" : "32",
172  title,
173  Thread.CurrentThread.ManagedThreadId,
174  runningAsAdmin ? " - Administrator" : string.Empty
175  );
176 
177  if (!String.IsNullOrEmpty(this.cbFilePath.Text))
178  this.Text = this.Text + " - " + Path.GetFileName(this.cbFilePath.Text);
179 
180  if (!String.IsNullOrEmpty(this.runtimeContextName))
181  this.Text = this.Text + " - " + this.runtimeContextName;
182  }
183 
184  private const int FORM_OFFSET = 25;
185 
186  private void SetLocation(SampleForm creatorForm)
187  {
188  if (creatorForm != null)
189  {
190  int xOffset = FORM_OFFSET;
191  int yOffset = FORM_OFFSET;
192 
193  if (creatorForm.creatorForm != null)
194  {
195  xOffset = creatorForm.Location.X - creatorForm.creatorForm.Location.X;
196  yOffset = creatorForm.Location.Y - creatorForm.creatorForm.Location.Y;
197  }
198 
199  this.Location = new Point(creatorForm.Location.X + xOffset, creatorForm.Location.Y + yOffset);
200  this.Size = creatorForm.Size;
201  }
202  }
203 
204  private void CreateCustomImpl()
205  {
206  CreateDefaultCustomImpl();
207  CreateOutputWindowCustomImpl();
208  }
209 
210  private void CreateDefaultCustomImpl()
211  {
212  PrintText("Create default custom implementation");
213 
214  customScreenImplementation = new DefaultCustomScreenImplementation();
215  customScreenImplementation.KeyDown += CustomScreenImplementation_KeyDown;
216 
217  contextVariableImplementation = new ContextVariableImplementation();
218  contextVariableImplementation.ContextVariableRead += ContextVariableRead;
219 
220  stateVariableImplementation = new StateVariableImplementation();
221  stateVariableImplementation.StateVariableValueChanged += StateVariableValueChanged;
222 
223  measureImplementation = new DefaultMeasureImplementation();
224  serviceProviderImplementation = new DefaultExternalServiceProviderImplementation();
225  }
226 
227  private void CreateOutputWindowCustomImpl()
228  {
229  PrintText("Create output window custom implementation");
230 
231  basicScreenOutputImpl = new BasicScreenOutputImpl();
232  customScreenOutputImpl = new CustomScreenOutputImpl();
233  loggingOutputImpl = new LoggingOutputImpl();
234  contextVariableOutputImpl = new ContextVariableOutputImpl();
235 
236  stateVariableOutputImpl = new StateVariableOutputImpl();
237  measureOutputImpl = new MeasureOutputImpl();
238  i18NOutputImpl = new I18nOutputImpl();
239  serviceProviderOutputImpl = new ExternalServiceProviderOutputImpl();
240 
241  sqlOutputImpl = new SqlOutputImpl();
242  commonDialogsOutputImpl = new CommonDialogsOutputImpl();
243 
244  basicScreenOutputImpl.LogEvent += PrintText;
245  customScreenOutputImpl.LogEvent += PrintText;
246  loggingOutputImpl.LogEvent += PrintText;
247  contextVariableOutputImpl.LogEvent += PrintText;
248 
249  stateVariableOutputImpl.LogEvent += PrintText;
250  measureOutputImpl.LogEvent += PrintText;
251  i18NOutputImpl.LogEvent += PrintText;
252  serviceProviderOutputImpl.LogEvent += PrintText;
253 
254  sqlOutputImpl.LogEvent += PrintText;
255  commonDialogsOutputImpl.LogEvent += PrintText;
256  }
257 
258  private void InitializeSampleDefaultValues()
259  {
260  PrintText("Initialize default values");
261 
262  this.comboBoxTraceLevel.Items.AddRange(Enum.GetNames(typeof(TraceLevels)));
263 
264  // Avoid changing order
265  treeViewOtxProject.ImageList = imageList1;
266 
267  textBoxRtPortPipe.Name = SampleConstants.RT_PORT_PIPE_TEXT_BOX_NAME;
268  textBoxDiagPortPipe.Name = SampleConstants.DM_PORT_PIPE_TEXT_BOX_NAME;
269 
270  LoadSetting();
271 
272  this.EnableConnectionState();
273  }
274 
275  private void LoadSetting()
276  {
277  SaveSettingUtil.Reload();
278  try
279  {
280  cbFilePath.Text = userSettings.Ptx_Ppx_Directory;
281  cbFilePath.Text = userSettings.Ptx_Ppx_Directory;
282  if (!String.IsNullOrEmpty(userSettings.Ptx_Ppx_DirectoryList))
283  {
284  this.cbFilePath.Items.AddRange(userSettings.Ptx_Ppx_DirectoryList.Split(';'));
285  }
286  AddComboBoxFileOrPath(this.cbFilePath);
287 
288  SetupTraceLevel();
289  SetupTraceFolder();
290  SetupTraceFileMaxCountAndSize();
291 
292  // Avoid changing order of this line
293  SetupDefaultPortAndPipeName();
294 
295  SetupCustomImplType();
296  SetupWindowSize();
297  SetupWindowLocation();
298 
299  checkBoxAsyncExecution.Checked = userSettings.Asynchron;
300  checkBoxCyclicExecution.Checked = userSettings.Cyclic;
301  checkBoxCyclicReload.Checked = userSettings.CyclicReload;
302  checkBoxNewRuntimeManager.Checked = userSettings.NewRunTimeManager;
303  checkBoxAdd2Output.Checked = userSettings.AddMessageToOutput;
304  checkBoxStartAllParents.Checked = userSettings.StartAllParents;
305 
306  SetupTimeOut();
307  checkBoxUseConnectionState.Checked = userSettings.ConnectionState;
308  checkBoxIgnition.CheckState = userSettings.Ignition == 1 ? CheckState.Checked : (userSettings.Ignition == 0 ? CheckState.Unchecked : CheckState.Indeterminate);
309  SetupPollingTime();
310  SetupVoltageThreshold();
311 
312  this.textBoxRuntimeContextName.Text = userSettings.RuntimeContextName.ToString();
313  }
314  catch (System.Exception e)
315  {
316  PrintText(e.Message);
317  userSettings.Reset();
318  }
319  }
320 
321  bool isPathChanging = false;
322  private void AddComboBoxFileOrPath(ComboBox comboBox)
323  {
324  if (comboBox != null && !isPathChanging)
325  {
326  isPathChanging = true;
327 
328  string path = comboBox.Text;
329 
330  if (Directory.Exists(path) || File.Exists(path))
331  {
332  while (comboBox.Items.Contains(path))
333  {
334  comboBox.Items.Remove(path);
335  }
336 
337  while (comboBox.Items.Contains(path.TrimEnd(new char[] { '/', '\\' })))
338  {
339  comboBox.Items.Remove(path.TrimEnd(new char[] { '/', '\\' }));
340  }
341 
342  path = path.TrimEnd(new char[] { '/', '\\' });
343 
344  comboBox.Items.Insert(0, path);
345  comboBox.Text = path;
346  comboBox.SelectAll();
347  }
348 
349  isPathChanging = false;
350  }
351  }
352 
353  private void SetupTraceFileMaxCountAndSize()
354  {
355  textBoxTraceFileMaxCount.Text = userSettings.TraceFileMaxCount.ToString();
356  textBoxTraceFileMaxSize.Text = userSettings.TraceFileMaxSize.ToString();
357  }
358 
359  private void SetupDefaultPortAndPipeName()
360  {
361  defaultDiagPort = userSettings.DiagManagerPort;
362  defaultRuntimePort = userSettings.RuntimePort;
363 
364  defaultDiagPipeName = userSettings.DiagManagerPipeName;
365  defaultRuntimePipeName = userSettings.RuntimePipeName;
366 
367  IpcTypes ipcTypes = IpcTypes.SOCKET;
368  Enum.TryParse<IpcTypes>(userSettings.IpcType, out ipcTypes);
369 
370  if (comboBoxIpcType.Items.Count == 0)
371  {
372  comboBoxIpcType.Items.Add(IpcTypes.SOCKET);
373  comboBoxIpcType.Items.Add(IpcTypes.PIPE);
374  }
375 
376  comboBoxIpcType.SelectedItem = ipcTypes;
377  }
378 
379  private void SetupTraceLevel()
380  {
381  RuntimeConfig.Instance.TraceLevel = userSettings.TraceLevels;
382  comboBoxTraceLevel.SelectedItem = RuntimeConfig.Instance.TraceLevel.ToString();
383  }
384 
385  private void SetupTraceFolder()
386  {
387  if (userSettings.TracingDirectory != string.Empty)
388  RuntimeConfig.Instance.TraceFolder = userSettings.TracingDirectory;
389 
390  textBoxTraceFolder.Text = RuntimeConfig.Instance.TraceFolder;
391  }
392 
393  private void SetupCustomImplType()
394  {
395  if (userSettings.CustomImplTypes == CustomImplTypes.OutputImpl)
396  {
397  radioButtonOuputWindow.Checked = true;
398  }
399  else if (userSettings.CustomImplTypes == CustomImplTypes.NoCustom)
400  {
401  radioButtonNoCustomImplementation.Checked = true;
402  }
403  else
404  {
405  radioButtonDefaultImplementation.Checked = true;
406  }
407  }
408 
409  private void SetupWindowSize()
410  {
411  int width = userSettings.WindowWidth;
412  int height = userSettings.WindowHeight;
413  this.Size = new Size(width, height);
414  }
415 
416  private void SetupWindowLocation()
417  {
418  int locationX = userSettings.WindowLocationX;
419  int locationY = userSettings.WindowLocationY;
420  Point location = new Point(locationX, locationY);
421 
422  if (CheckFormIsInBound(location))
423  {
424  this.Location = location;
425  return;
426  }
427 
428  this.CenterToScreen();
429  }
430 
431  private bool CheckFormIsInBound(Point location)
432  {
433  try
434  {
435  Screen formContainScreens = Screen.AllScreens.Where(screen => screen.Bounds.Contains(location) == true).FirstOrDefault();
436 
437  return formContainScreens != null;
438  }
439  catch (System.Exception)
440  {
441  return false;
442  }
443  }
444 
445  private void SetupTimeOut()
446  {
447  string timeOutString = userSettings.TimeOut.ToString();
448  this.textBoxTimeout.Text = timeOutString;
449  }
450 
451  private void SetupPollingTime()
452  {
453  string pollingTimeString = userSettings.PollingTime.ToString();
454  this.textBoxPollingTime.Text = pollingTimeString;
455  }
456 
457  private void SetupVoltageThreshold()
458  {
459  string voltageThreshold = userSettings.VoltageThreshold.ToString();
460  this.textBoxVoltageThreshold.Text = voltageThreshold;
461  }
462 
463  private void comboBoxIpcType_SelectedValueChanged(object sender, EventArgs e)
464  {
465  // Avoid RuntimeManager creation on DiagManager's port changed in this method
466  textBoxDiagPortPipe.TextChanged -= textBoxPortPipe_TextChanged;
467  var ipcType = (IpcTypes)comboBoxIpcType.SelectedItem;
468 
469  switch (ipcType)
470  {
471  case IpcTypes.SOCKET:
472 
473  portPipeLabel.Text = "Runner / DiagManager Ports";
474 
475  textBoxDiagPortPipe.Text = defaultDiagPort.ToString();
476  textBoxDiagPortPipe.TextChanged += textBoxPortPipe_TextChanged;
477 
478  textBoxRtPortPipe.Text = defaultRuntimePort.ToString();
479  break;
480 
481  case IpcTypes.PIPE:
482 
483  portPipeLabel.Text = "Runner / DiagManager Pipes";
484 
485  textBoxDiagPortPipe.Text = defaultDiagPipeName;
486  textBoxDiagPortPipe.TextChanged += textBoxPortPipe_TextChanged;
487 
488  textBoxRtPortPipe.Text = defaultRuntimePipeName;
489  break;
490 
491  default:
492  break;
493  }
494  }
495 
496  private void textBoxPortPipe_TextChanged(object sender, EventArgs e)
497  {
498  PrintText("Create RuntimeManager...");
499 
500  try
501  {
502  this.globalRuntimeManager = CreateRuntimeManager();
503  }
504  catch (System.Exception ex)
505  {
506  switch ((sender as TextBox).Name)
507  {
508  case SampleConstants.RT_PORT_PIPE_TEXT_BOX_NAME:
509 
510  PrintText(String.Format("Invalid Otx Runtime {0}", IpcPortPipeString()));
511  break;
512 
513  case SampleConstants.DM_PORT_PIPE_TEXT_BOX_NAME:
514 
515  PrintText(String.Format("Invalid Diag Manager {0}", IpcPortPipeString()));
516  break;
517 
518  default:
519  break;
520  }
521 
522  PrintException(ex);
523  PrintText("No RuntimeManager created");
524  }
525 
526  if (this.globalRuntimeManager == null)
527  {
528  PrintText("RuntimeManager is null.");
529  }
530  }
531 
532  private IRuntimeManager CreateRuntimeManager()
533  {
534  IRuntimeManager runtimeManager = null;
535  try
536  {
537  string ipcType = "";
538  switch ((IpcTypes)comboBoxIpcType.SelectedItem)
539  {
540  case IpcTypes.SOCKET:
541 
542  runtimeManager = CreateSocketRuntimeManager();
543  ipcType = "Socket";
544  break;
545 
546  case IpcTypes.PIPE:
547 
548  runtimeManager = CreatePipeRuntimeManager();
549  ipcType = "Pipe";
550  break;
551  }
552 
553  PrintText($"... {ipcType} RuntimeManager created (MinBinVersion: {RuntimeConfig.Instance.MinBinVersion})");
554 
555  InitializeRuntimeEvents(runtimeManager);
556  SetCustomImplementation(runtimeManager);
557  }
558  catch (InvalidLicenseException ex)
559  {
560  PrintException(ex);
561  PrintText("... No RuntimeManager created.");
562 
563  return runtimeManager;
564  }
565 
566  return runtimeManager;
567  }
568 
569  private string IpcPortPipeString()
570  {
571  switch ((IpcTypes)comboBoxIpcType.SelectedItem)
572  {
573  case IpcTypes.SOCKET:
574  return SampleConstants.PORT_STRING;
575  case IpcTypes.PIPE:
576  return SampleConstants.PIPE_STRING;
577  default:
578  // Should not reach here
579  return string.Empty;
580  }
581  }
582 
583  private IRuntimeManager CreateSocketRuntimeManager()
584  {
585  ushort rtPort = Convert.ToUInt16(textBoxRtPortPipe.Text);
586 
587  if (NoDiag())
588  {
589  return RuntimeManagerFactory.CreateSocketRuntimeManager(rtPort);
590  }
591  else
592  {
593  ushort diagPort = Convert.ToUInt16(textBoxDiagPortPipe.Text);
594  return RuntimeManagerFactory.CreateSocketRuntimeManager(rtPort, diagPort);
595  }
596  }
597 
598  private IRuntimeManager CreatePipeRuntimeManager()
599  {
600  if (NoDiag())
601  {
602  return RuntimeManagerFactory.CreatePipeRuntimeManager(textBoxRtPortPipe.Text);
603  }
604  else
605  {
606  return RuntimeManagerFactory.CreatePipeRuntimeManager(textBoxRtPortPipe.Text, textBoxDiagPortPipe.Text);
607  }
608  }
609 
610  private bool NoDiag()
611  {
612  return String.IsNullOrWhiteSpace(textBoxDiagPortPipe.Text);
613  }
614 
615  private void InitializeRuntimeEvents(IRuntimeManager runtimeManager)
616  {
617  if (runtimeManager == null)
618  return;
619 
620  runtimeManager.ProcedurePending -= ProcedurePending;
621  runtimeManager.ProcedureStarted -= ProcedureStarted;
622  runtimeManager.ProcedurePaused -= ProcedurePaused;
623  runtimeManager.ProcedureContinued -= ProcedureContinued;
624  runtimeManager.ProcedureFinished -= ProcedureFinished;
625  runtimeManager.ProcedureAborted -= ProcedureAborted;
626  runtimeManager.ProcedureStopped -= ProcedureStopped;
627  runtimeManager.ProcedureTimeout -= ProcedureTimeout;
628  runtimeManager.DiagConnectionStateChanged -= DiagConnectionStateChanged;
629  runtimeManager.InOutParameterValueChanged -= InOutParameterValueChanged;
630 
631  runtimeManager.ProcedurePending += ProcedurePending;
632  runtimeManager.ProcedureStarted += ProcedureStarted;
633  runtimeManager.ProcedurePaused += ProcedurePaused;
634  runtimeManager.ProcedureContinued += ProcedureContinued;
635  runtimeManager.ProcedureFinished += ProcedureFinished;
636  runtimeManager.ProcedureAborted += ProcedureAborted;
637  runtimeManager.ProcedureStopped += ProcedureStopped;
638  runtimeManager.ProcedureTimeout += ProcedureTimeout;
639  runtimeManager.DiagConnectionStateChanged += DiagConnectionStateChanged;
640  runtimeManager.InOutParameterValueChanged += InOutParameterValueChanged;
641 
642  PrintText("Initialization of runtime events finished");
643  }
644 
645  private void radioButtonCustomImpl_CheckedChanged(object sender = null, System.EventArgs e = null)
646  {
647  if (this.globalRuntimeManager == null)
648  return;
649 
650  if (sender != null && (sender as RadioButton).Checked == false)
651  return;
652 
653  this.SetCustomImplementation(this.globalRuntimeManager);
654  }
655 
656  private void SetCustomImplementation(IRuntimeManager runtimeManager)
657  {
658  if (runtimeManager == null)
659  return;
660 
661  var currentCustomImpl = GetCurrentCustomImpl();
662 
663  switch (currentCustomImpl)
664  {
665  case CustomImplTypes.OutputImpl:
666 
667  SetOutputWindowImplementation(runtimeManager);
668  break;
669 
670  case CustomImplTypes.DefaultCustomImpl:
671 
672  SetDefaultCustomImplementation(runtimeManager);
673  break;
674 
675  case CustomImplTypes.NoCustom:
676 
677  RemoveCustomImplementation(runtimeManager);
678  break;
679 
680  default:
681  break;
682  }
683 
684  if (currentCustomImpl != CustomImplTypes.None)
685  {
686  PrintText("Set up custom implementation finished");
687  }
688  }
689 
690  private CustomImplTypes GetCurrentCustomImpl()
691  {
692  if (radioButtonOuputWindow.Checked)
693  return CustomImplTypes.OutputImpl;
694  else if (radioButtonDefaultImplementation.Checked)
695  return CustomImplTypes.DefaultCustomImpl;
696  else if (radioButtonNoCustomImplementation.Checked)
697  return CustomImplTypes.NoCustom;
698 
699  return CustomImplTypes.None;
700  }
701 
702  private void SetOutputWindowImplementation(IRuntimeManager runtimeManager)
703  {
704  if (runtimeManager == null)
705  return;
706 
707  runtimeManager.SetCustomImplementation(basicScreenOutputImpl);
708  runtimeManager.SetCustomImplementation(customScreenOutputImpl);
709  runtimeManager.SetCustomImplementation(loggingOutputImpl);
710  runtimeManager.SetCustomImplementation(contextVariableOutputImpl);
711 
712  runtimeManager.SetCustomImplementation(stateVariableOutputImpl);
713  runtimeManager.SetCustomImplementation(measureOutputImpl);
714  runtimeManager.SetCustomImplementation(i18NOutputImpl);
715  runtimeManager.SetCustomImplementation(serviceProviderOutputImpl);
716 
717  runtimeManager.SetCustomImplementation((ISqlImplementation)null); // TODO: create?
718  runtimeManager.SetCustomImplementation(commonDialogsOutputImpl);
719  }
720 
721  private void SetDefaultCustomImplementation(IRuntimeManager runtimeManager)
722  {
723  if (runtimeManager == null)
724  return;
725 
726  runtimeManager.SetCustomImplementation((IBasicScreenImplementation)null); // TODO: create?
727  runtimeManager.SetCustomImplementation(customScreenImplementation);
728  runtimeManager.SetCustomImplementation((ILoggingImplementation)null); // TODO: create?
729  runtimeManager.SetCustomImplementation(contextVariableImplementation);
730 
731  runtimeManager.SetCustomImplementation(stateVariableImplementation);
732  runtimeManager.SetCustomImplementation(measureImplementation);
733  runtimeManager.SetCustomImplementation((Ii18nImplementation)null); // TODO: create?
734  runtimeManager.SetCustomImplementation(serviceProviderImplementation);
735 
736  runtimeManager.SetCustomImplementation(sqlOutputImpl);
737  runtimeManager.SetCustomImplementation((ICommonDialogsImplementation)null); // TODO: create?
738  }
739 
740  private void RemoveCustomImplementation(IRuntimeManager runtimeManager)
741  {
742  if (runtimeManager == null)
743  return;
744 
745  runtimeManager.SetCustomImplementation((IBasicScreenImplementation)null);
746  runtimeManager.SetCustomImplementation((ICustomScreenImplementation)null);
747  runtimeManager.SetCustomImplementation((ILoggingImplementation)null);
748  runtimeManager.SetCustomImplementation((IContextVariableImplementation)null);
749 
750  runtimeManager.SetCustomImplementation((IStateVariableImplementation)null);
751  runtimeManager.SetCustomImplementation((IMeasureImplementation)null);
752  runtimeManager.SetCustomImplementation((Ii18nImplementation)null);
753  runtimeManager.SetCustomImplementation((IExternalServiceProviderImplementation)null);
754 
755  runtimeManager.SetCustomImplementation((ISqlImplementation)null);
756  runtimeManager.SetCustomImplementation((ICommonDialogsImplementation)null);
757  }
758 
759  private void ProcedurePending(IRuntimeContext context)
760  {
761  if (InvokeRequired)
762  {
763  Invoke(new MethodInvoker(delegate ()
764  {
765  ProcedurePending(context);
766  }));
767  return;
768  }
769 
770  lock (eventListenerLock)
771  {
772  this.PrintText(string.Format("Event ProcedurePending occurred - {0} - ExecutionState = {1}", context.Procedure.FullName, context.ExecutionState.ToString()));
773  UpdateExecutionState(context);
774  ShowConnectionStateMessage(context);
775  }
776  }
777 
778  private void ProcedureStarted(IRuntimeContext context)
779  {
780  if (InvokeRequired)
781  {
782  Invoke(new MethodInvoker(delegate ()
783  {
784  ProcedureStarted(context);
785  }));
786  return;
787  }
788 
789  lock (eventListenerLock)
790  {
791  this.PrintText(string.Format("Event ProcedureStarted occurred - {0} - ExecutionState = {1} - RuntimeId = {2} - ProcessId = {3}", context.Procedure.FullName, context.ExecutionState.ToString(), context.RuntimeId, context.ProcessId));
792  UpdateExecutionState(context);
793  }
794  }
795 
796  private void ProcedurePaused(IRuntimeContext context, ExecutionStateChangeReason reason)
797  {
798  if (InvokeRequired)
799  {
800  Invoke(new MethodInvoker(delegate ()
801  {
802  ProcedurePaused(context, reason);
803  }));
804  return;
805  }
806 
807  lock (eventListenerLock)
808  {
809  this.PrintText(string.Format("Event ProcedurePaused occurred - {0} - ExecutionState = {1} - ExecutionStateChangeReason = {2}", context.Procedure.FullName, context.ExecutionState.ToString(), reason.ToString()));
810  UpdateExecutionState(context);
811  if (reason == ExecutionStateChangeReason.UnexpectedDiagConnectionState)
812  {
813  ShowConnectionStateMessage(context);
814  }
815  }
816  }
817 
818  private void ProcedureContinued(IRuntimeContext context)
819  {
820  if (InvokeRequired)
821  {
822  Invoke(new MethodInvoker(delegate ()
823  {
824  ProcedureContinued(context);
825  }));
826  return;
827  }
828 
829  lock (eventListenerLock)
830  {
831  this.PrintText(string.Format("Event ProcedureContinued occurred - {0} - ExecutionState = {1}", context.Procedure.FullName, context.ExecutionState.ToString()));
832  UpdateExecutionState(context);
833  }
834  }
835 
836  private void ProcedureStopped(IRuntimeContext context)
837  {
838  if (InvokeRequired)
839  {
840  Invoke(new MethodInvoker(delegate ()
841  {
842  ProcedureStopped(context);
843  }));
844  return;
845  }
846 
847  lock (eventListenerLock)
848  {
849  this.PrintText(string.Format("Event ProcedureStopped occurred - {0} - ExecutionState = {1}", context.Procedure.FullName, context.ExecutionState.ToString()));
850  UpdateExecutionState(context);
851  }
852  }
853 
854  private void ProcedureTimeout(IRuntimeContext context)
855  {
856  if (InvokeRequired)
857  {
858  Invoke(new MethodInvoker(delegate ()
859  {
860  ProcedureTimeout(context);
861  }));
862  return;
863  }
864 
865  lock (eventListenerLock)
866  {
867  cyclicExecuteAsyncIsProcessing = false;
868  this.PrintText(string.Format("Event ProcedureTimeout occurred - {0} - ExecutionState = {1}", context.Procedure.FullName, context.ExecutionState.ToString()));
869  UpdateExecutionState(context);
870  }
871  }
872 
873  private void DiagConnectionStateChanged(ClampState batteryState, ClampState ignitionState)
874  {
875  if (InvokeRequired)
876  {
877  Invoke(new MethodInvoker(delegate ()
878  {
879  DiagConnectionStateChanged(batteryState, ignitionState);
880  }));
881  return;
882  }
883 
884  lock (eventListenerLock)
885  {
886  this.PrintText(string.Format("Event DiagConnectionStateChanged occurred - BatteryState = {0}, IgnitionState = {1}", batteryState.ToString(), ignitionState.ToString()));
887  System.Media.SystemSounds.Beep.Play();
888 
889  SetBatteryIgnitionState(batteryState, ignitionState);
890  }
891  }
892 
893  // TODO: refactor. handle multithread?
894  private void ProcedureFinished(IRuntimeContext context)
895  {
896  if (InvokeRequired)
897  {
898  Invoke(new MethodInvoker(delegate ()
899  {
900  ProcedureFinished(context);
901  }));
902  return;
903  }
904 
905  lock (eventListenerLock)
906  {
907  IProcedureParameter procedureParameter;
908  string procedureName = context.Procedure.FullName;
909  string parameterOuput;
910 
911  for (int i = 0; i < context.Procedure.Parameters.Count(); i++)
912  {
913  procedureParameter = context.Procedure.Parameters.ElementAt(i);
914  parameterOuput = "Parameter Changed - " + procedureParameter.Name + "(" + procedureParameter.DataType + ") = ";
915 
916  if (procedureParameter.Value != null)
917  {
918  parameterOuput += ShortenedValueString(procedureParameter);
919  }
920  else
921  {
922  parameterOuput += null;
923  }
924 
925  this.PrintText(parameterOuput);
926  }
927 
928  UpdateGridviewParameter(context.Procedure);
929 
930  this.PrintText(string.Format("ProcedureFinished({0}) ExecutionState({1}) - Execution duration {2} - Running time {3} - Used memory {4})",
931  context.Procedure.FullName,
932  context.ExecutionState.ToString(),
933  (DateTime.Now - this.runtimeContextsExecutionStartTime[context]).ToString("mm':'ss','fff"),
934  TimeSpan.FromMilliseconds(context.ExecutionTime).ToString("mm':'ss','fff"),
935  string.Format("{0:0,0} kB", context.ProcessMemory / 1024))
936  );
937 
938  UpdateExecutionState(context);
939 
940  cyclicExecuteAsyncIsProcessing = false;
941  }
942  }
943 
944  private void ProcedureAborted(IRuntimeContext context)
945  {
946  if (InvokeRequired)
947  {
948  Invoke(new MethodInvoker(delegate ()
949  {
950  ProcedureAborted(context);
951  }));
952  return;
953  }
954 
955  this.PrintText(string.Format("ProcedureAborted({0}) ExecutionState({1})", context.Procedure.FullName, context.ExecutionState.ToString()));
956 
957  if (context.HasRuntimeException)
958  {
959  PrintException(context.RuntimeException, "Reason: API ");
960  }
961 
962  if (context.HasOtxException)
963  {
964  PrintException(context.OtxException, "Reason: OTX ");
965  }
966  cyclicExecuteAsyncIsProcessing = false;
967  UpdateExecutionState(context);
968  }
969 
970  private void UpdateExecutionState(IRuntimeContext context)
971  {
972  if (context != null)
973  {
974  switch (context.ExecutionState)
975  {
976  case ExecutionState.Running:
977 
978  this.procedureExecutionCount++;
979 
980  AddRuntimeContext(context);
981  DisplayProcedureExecutionState(context);
982 
983  this.buttonExecuteMain.Enabled = checkBoxAsyncExecution.Checked;
984  this.buttonExecuteSelectedProcedure.Enabled = checkBoxAsyncExecution.Checked;
985 
986  UpdateExecutionStateButtons(true);
987  UpdatePauseButton(true);
988 
989  break;
990 
991  case ExecutionState.Paused:
992 
993  this.procedureExecutionCount--;
994  DisplayProcedureExecutionState(context);
995  UpdatePauseButton(false);
996 
997  break;
998 
999  case ExecutionState.Pending:
1000 
1001  DisplayProcedureExecutionState(context);
1002  UpdateExecutionStateButtons(true);
1003  UpdatePauseButton(true, false);
1004 
1005  break;
1006 
1007  case ExecutionState.Finished:
1008 
1009  this.procedureExecutionCount--;
1010 
1011  RemoveRuntimeContext(context);
1012  DisplayProcedureExecutionState(context);
1013 
1014  this.buttonExecuteMain.Enabled = !checkBoxCyclicExecution.Checked;
1015  this.buttonExecuteSelectedProcedure.Enabled = !checkBoxCyclicExecution.Checked;
1016 
1017  UpdateExecutionStateButtons(false);
1018  UpdatePauseButton(true, false);
1019 
1020  this.labelBatteryState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconBattery16;
1021  this.labelIgnitionState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconIgnition16;
1022 
1023  break;
1024 
1025  case ExecutionState.Stopped:
1026 
1027  this.procedureExecutionCount--;
1028 
1029  RemoveRuntimeContext(context);
1030  DisplayProcedureExecutionState(context);
1031 
1032  this.buttonExecuteMain.Enabled = true;
1033  this.buttonExecuteSelectedProcedure.Enabled = true;
1034 
1035  UpdateExecutionStateButtons(false);
1036  UpdatePauseButton(true, false);
1037 
1038  this.labelBatteryState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconBattery16;
1039  this.labelIgnitionState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconIgnition16;
1040 
1041  break;
1042 
1043  case ExecutionState.Aborted:
1044 
1045  this.procedureExecutionCount--;
1046 
1047  RemoveRuntimeContext(context);
1048  DisplayProcedureExecutionState(context);
1049 
1050  this.buttonExecuteMain.Enabled = true;
1051  this.buttonExecuteSelectedProcedure.Enabled = true;
1052 
1053  UpdateExecutionStateButtons(false);
1054  UpdatePauseButton(true, false);
1055 
1056  this.labelBatteryState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconBattery16;
1057  this.labelIgnitionState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconIgnition16;
1058 
1059  break;
1060  case ExecutionState.Timeout:
1061 
1062  System.Media.SystemSounds.Hand.Play();
1063 
1064  this.procedureExecutionCount--;
1065 
1066  RemoveRuntimeContext(context);
1067  DisplayProcedureExecutionState(context);
1068 
1069  this.buttonExecuteMain.Enabled = true;
1070  this.buttonExecuteSelectedProcedure.Enabled = true;
1071 
1072  UpdateExecutionStateButtons(false);
1073  UpdatePauseButton(true, false);
1074 
1075  this.labelBatteryState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconBattery16;
1076  this.labelIgnitionState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconIgnition16;
1077 
1078  break;
1079  }
1080 
1081  StartStopUpdateGuiTimer();
1082  }
1083  }
1084 
1085  private void StartStopUpdateGuiTimer()
1086  {
1087  if (this.procedureExecutionCount <= 0)
1088  {
1089  this.updateGuiTimer.Enabled = false;
1090  this.labelSeparator1.Visible = false;
1091  this.labelProcedureExecutionTimes.Visible = false;
1092  }
1093  else if (!this.updateGuiTimer.Enabled)
1094  {
1095  this.updateGuiTimer.Enabled = true;
1096  }
1097  }
1098 
1099  private void updateGuiTimer_Tick(object sender, EventArgs e)
1100  {
1101  DisplayProcedureExecutionTimes();
1102  }
1103 
1104  private void DisplayProcedureExecutionTimes()
1105  {
1106  string text = string.Empty;
1107 
1108  if (this.runtimeContextsExecutionStartTime.Count > 0)
1109  {
1110  foreach (var item in this.runtimeContextsExecutionStartTime)
1111  {
1112  var duration = DateTime.Now - item.Value;
1113  text += string.Format("{0}: {1} | ", item.Key.Procedure.Name, duration.ToString("mm':'ss"));
1114  }
1115  text = text.TrimEnd(new char[] { ' ', '|' });
1116  }
1117 
1118  this.labelProcedureExecutionTimes.Text = text;
1119  this.labelSeparator1.Visible = true;
1120  this.labelProcedureExecutionTimes.Visible = true;
1121  }
1122 
1123  private void InOutParameterValueChanged(IRuntimeContext context, IProcedureInOutParameter parameter)
1124  {
1125  if (InvokeRequired)
1126  {
1127  Invoke(new MethodInvoker(delegate ()
1128  {
1129  InOutParameterValueChanged(context, parameter);
1130  }));
1131  return;
1132  }
1133 
1134  lock (eventListenerLock)
1135  {
1136  try
1137  {
1138  string valueStr = ShortenedValueString(parameter);
1139  string message = String.Format("Parameter '{0}' new value = {1}", parameter.Name, valueStr);
1140  PrintText(message);
1141  UpdateGridviewParameter(parameter);
1142  }
1143  catch (InvalidCastException ex)
1144  {
1145  PrintText(ex.Message);
1146  }
1147  }
1148  }
1149 
1150  private static string ShortenedValueString(IProcedureParameter parameter)
1151  {
1152  var valueStr = ValueConverter.Value2String(parameter.Value);
1153  if (valueStr.Length > VALUE_STRING_MAX_LENGTH)
1154  return valueStr.Substring(0, VALUE_STRING_MAX_LENGTH) + "...";
1155 
1156  return valueStr;
1157  }
1158 
1159  private void UpdatePauseButton(bool pauseAvailable, bool enabled = true)
1160  {
1161  this.buttonPause.Enabled = enabled;
1162  this.buttonPause.Checked = !pauseAvailable;
1163  this.buttonPause.Image = pauseAvailable
1164  ? global::OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.Pause
1165  : global::OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.Continue;
1166  }
1167 
1168  private void UpdateExecutionStateButtons(bool wasExecuted)
1169  {
1170  if (this.useConnectionState)
1171  {
1172  this.labelTimeout.Enabled = !wasExecuted;
1173  this.textBoxTimeout.Enabled = !wasExecuted;
1174  this.checkBoxUseConnectionState.Enabled = !wasExecuted;
1175  this.labelExpectedState.Enabled = !wasExecuted;
1176  this.checkBoxIgnition.Enabled = !wasExecuted;
1177  this.labelPollingTime.Enabled = !wasExecuted;
1178  this.textBoxPollingTime.Enabled = !wasExecuted;
1179  this.labelVoltageThreshold.Enabled = !wasExecuted;
1180  this.textBoxVoltageThreshold.Enabled = !wasExecuted;
1181  }
1182 
1183  if (wasExecuted)
1184  {
1185  if (checkBoxAsyncExecution.Checked == false)
1186  {
1187  this.buttonExecuteMain.Enabled = false;
1188  this.buttonExecuteSelectedProcedure.Enabled = false;
1189  }
1190 
1191  this.buttonStop.Enabled = true;
1192  }
1193  else
1194  {
1195  if (project != null && project.MainProcedure != null)
1196  {
1197  this.buttonExecuteMain.Enabled = true;
1198  }
1199 
1200  this.buttonExecuteSelectedProcedure.Enabled = true;
1201 
1202  this.buttonStop.Enabled = false;
1203  }
1204  }
1205 
1206  private void DisplayProcedureExecutionState(IRuntimeContext context, string errorMessage = "")
1207  {
1208  if (string.IsNullOrEmpty(errorMessage))
1209  {
1210  this.labelIconProcedureExecutionState.Image = global::OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.Info16;
1211 
1212  if (this.procedureExecutionCount <= 0)
1213  {
1214  this.procedureExecutionCount = 0;
1215  if (context.ExecutionState == ExecutionState.Paused)
1216  {
1217  this.labelProcedureExecutionState.Text = "Execution is paused, click \"Continue\"...";
1218  }
1219  else
1220  {
1221  this.labelProcedureExecutionState.Text = "Select a procedure and click \"Start\"...";
1222  }
1223  }
1224  else if (this.procedureExecutionCount == 1)
1225  {
1226  this.labelProcedureExecutionState.Text = "1 Procedure is running";
1227  }
1228  else
1229  {
1230  this.labelProcedureExecutionState.Text = string.Format("{0} Procedures are running", this.procedureExecutionCount);
1231  }
1232  }
1233  else
1234  {
1235  this.labelIconProcedureExecutionState.Image = global::OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.Error16;
1236  this.labelProcedureExecutionState.Text = errorMessage;
1237  }
1238  }
1239  private void SyncWithParent(object parentControl, object control = null, bool newThread = false)
1240  {
1241  if (parentControl != null)
1242  {
1243  if (this.creatorForm != null && this.checkBoxStartAllParents.Checked)
1244  {
1245  if (parentControl is Button)
1246  {
1247  if (newThread)
1248  {
1249  ThreadPool.QueueUserWorkItem(state => ParentButtonClick(parentControl as Button));
1250  }
1251  else
1252  {
1253  ParentButtonClick(parentControl as Button);
1254  }
1255  }
1256  else if (parentControl is TextBox && control != null)
1257  {
1258  string text = (control as TextBox).Text;
1259  if (newThread)
1260  {
1261  ThreadPool.QueueUserWorkItem(state => ParentTextBoxSetText(parentControl as TextBox, text));
1262  }
1263  else
1264  {
1265  ParentTextBoxSetText(parentControl as TextBox, text);
1266  }
1267  }
1268  else if (parentControl is CheckBox && control != null)
1269  {
1270  CheckState checkState = (control as CheckBox).CheckState;
1271  if (newThread)
1272  {
1273  ThreadPool.QueueUserWorkItem(state => ParentCheckBoxSetCheckState(parentControl as CheckBox, checkState));
1274  }
1275  else
1276  {
1277  ParentCheckBoxSetCheckState(parentControl as CheckBox, checkState);
1278  }
1279  }
1280  else if (parentControl is ComboBox && control != null)
1281  {
1282  int index = (control as ComboBox).SelectedIndex;
1283  if (newThread)
1284  {
1285  ThreadPool.QueueUserWorkItem(state => ParentComboBoxSetIndex(parentControl as ComboBox, index));
1286  }
1287  else
1288  {
1289  ParentComboBoxSetIndex(parentControl as ComboBox, index);
1290  }
1291  }
1292  else if (parentControl is NumericUpDown && control != null)
1293  {
1294  int value = decimal.ToInt32((control as NumericUpDown).Value);
1295  if (newThread)
1296  ThreadPool.QueueUserWorkItem(state => ParentNumericUpDownSetValue(parentControl as NumericUpDown, value));
1297  else
1298  ParentNumericUpDownSetValue(parentControl as NumericUpDown, value);
1299  }
1300  }
1301  }
1302  }
1303 
1304  private void ParentButtonClick(Button button)
1305  {
1306  if (button.InvokeRequired)
1307  {
1308  this.creatorForm.Invoke(new Action(() => button.PerformClick()));
1309  }
1310  else
1311  {
1312  button.PerformClick();
1313  }
1314  }
1315 
1316  private void ParentTextBoxSetText(TextBox textBox, string text)
1317  {
1318  if (textBox.InvokeRequired)
1319  {
1320  this.creatorForm.Invoke(new Action(() => textBox.Text = text));
1321  }
1322  else
1323  {
1324  textBox.Text = text;
1325  }
1326  }
1327 
1328  private void ParentCheckBoxSetCheckState(CheckBox checkBox, CheckState checkState)
1329  {
1330  if (checkBox.InvokeRequired)
1331  {
1332  this.creatorForm.Invoke(new Action(() => checkBox.CheckState = checkState));
1333  }
1334  else
1335  {
1336  checkBox.CheckState = checkState;
1337  }
1338  }
1339 
1340  private void ParentComboBoxSetIndex(ComboBox comboBox, int index)
1341  {
1342  if (comboBox.InvokeRequired)
1343  {
1344  this.creatorForm.Invoke(new Action(() => comboBox.SelectedIndex = index));
1345  }
1346  else
1347  {
1348  comboBox.SelectedIndex = index;
1349  }
1350  }
1351 
1352  private void buttonBrowseTraceFolder_Click(object sender, EventArgs e)
1353  {
1354  folderBrowserDialog1.SelectedPath = this.textBoxTraceFolder.Text;
1355  folderBrowserDialog1.ShowNewFolderButton = true;
1356 
1357  DialogResult result = folderBrowserDialog1.ShowDialog();
1358  if (result == DialogResult.OK)
1359  {
1360  this.textBoxTraceFolder.Text = folderBrowserDialog1.SelectedPath;
1361  }
1362  }
1363 
1364  private void buttonOpenTraceFolder_Click(object sender, EventArgs e)
1365  {
1366  string path = this.textBoxTraceFolder.Text;
1367  if (Directory.Exists(path))
1368  {
1369  Process.Start(path);
1370  }
1371  }
1372 
1373  // This will not automatically update GUI if it is modified internally
1374  private void textBoxTraceFolder_TextChanged(object sender, EventArgs e)
1375  {
1376  if (this.globalRuntimeManager == null)
1377  return;
1378 
1379  string path = this.textBoxTraceFolder.Text;
1380 
1381  if (path != RuntimeConfig.Instance.TraceFolder)
1382  {
1383  if (Directory.Exists(path))
1384  {
1385  RuntimeConfig.Instance.TraceFolder = textBoxTraceFolder.Text;
1386  this.buttonOpenTraceFolder.Enabled = true;
1387 
1388  PrintText("Set trace folder to " + RuntimeConfig.Instance.TraceFolder);
1389  }
1390  else
1391  {
1392  this.buttonOpenTraceFolder.Enabled = false;
1393  }
1394  }
1395  else
1396  {
1397  this.buttonOpenTraceFolder.Enabled = true;
1398  }
1399 
1400  SyncWithParent(this.creatorForm?.textBoxTraceFolder, this.textBoxTraceFolder);
1401  }
1402 
1403  // This will not automatically update GUI if it is modified internally
1404  private void comboBoxTraceLevel_SelectedValueChanged(object sender, EventArgs e)
1405  {
1406  if (this.globalRuntimeManager == null)
1407  return;
1408 
1409  var traceLevel = (TraceLevels)comboBoxTraceLevel.SelectedIndex;
1410  if (traceLevel == RuntimeConfig.Instance.TraceLevel)
1411  return;
1412 
1413  RuntimeConfig.Instance.TraceLevel = traceLevel;
1414  PrintText("Updated trace level");
1415  }
1416 
1417  private void buttonBrowseFile_Click(object sender, EventArgs e)
1418  {
1419  DialogResult result = openFileDialog1.ShowDialog();
1420  if (result == DialogResult.OK)
1421  {
1422  cbFilePath.Text = openFileDialog1.FileName;
1423 
1424  this.buttonReload.PerformClick();
1425  }
1426  }
1427 
1428  private void cbFilePath_TextChanged(object sender, EventArgs e)
1429  {
1430  AddComboBoxFileOrPath(cbFilePath);
1431 
1432  if (String.IsNullOrWhiteSpace(cbFilePath.Text) || !File.Exists(cbFilePath.Text.Trim()))
1433  {
1434  buttonReload.Enabled = false;
1435  }
1436  else
1437  {
1438  buttonReload.Enabled = true;
1439  }
1440 
1441  SyncWithParent(this.creatorForm?.cbFilePath, this.cbFilePath);
1442  }
1443 
1444  private void cbFilePath_SelectedValueChanged(object sender, EventArgs e)
1445  {
1446  if (String.IsNullOrWhiteSpace(cbFilePath.Text) || !File.Exists(cbFilePath.Text.Trim()))
1447  {
1448  buttonReload.Enabled = false;
1449  }
1450  else
1451  {
1452  buttonReload.Enabled = true;
1453  this.buttonReload.PerformClick();
1454  }
1455 
1456  SyncWithParent(this.creatorForm?.cbFilePath, this.cbFilePath);
1457  }
1458 
1459  private void buttonReload_Click(object sender, EventArgs e)
1460  {
1461  this.LoadContextFile(this.globalRuntimeManager);
1462 
1463  SyncWithParent(this.creatorForm?.buttonReload);
1464  }
1465 
1466  private void LoadContextFile(IRuntimeManager runtimeManager)
1467  {
1468  PrintText("Load '" + cbFilePath.Text + "'...");
1469 
1470  if (runtimeManager == null)
1471  {
1472  PrintText("... No RuntimeManager exists!");
1473  return;
1474  }
1475 
1476  if (String.IsNullOrWhiteSpace(cbFilePath.Text.Trim()))
1477  {
1478  PrintText("... wrong file name.");
1479  return;
1480  }
1481 
1482  SetTitle(this.title);
1483 
1484  try
1485  {
1486  // TODO: move these 3 set up away
1487  this.isLoadding = true;
1488  this.playerProject = null;
1489  this.project = null;
1490  this.contextVariableImplementation.ResetAllValues();
1491  this.stateVariableImplementation.ResetAllValues();
1492  ClearSampleGUI();
1493 
1494  if (Path.GetExtension(cbFilePath.Text.Trim()).Contains("ptx"))
1495  {
1496  this.project = LoadPtx(runtimeManager);
1497 
1498  if (this.project != null) // TODO: might be obsolete in the future
1499  {
1500  PrintText("... Project '" + project.Name + "' successfully loaded.");
1501 
1502  ClearCustomImplemetationCaches();
1503 
1504  this.LoadPackage(this.project);
1505 
1506  ReadSettings(this.project.Settings);
1507 
1508  this.isLoadding = false;
1509  return;
1510  }
1511  }
1512  else if (Path.GetExtension(cbFilePath.Text.Trim()).Contains("ppx"))
1513  {
1514  this.playerProject = LoadPpx(runtimeManager);
1515 
1516  if (this.playerProject != null) // TODO: might be obsolete in the future
1517  {
1518  ClearCustomImplemetationCaches();
1519 
1520  PrintText("... Player '" + playerProject.Name + "' successfully loaded.");
1521 
1522  foreach (IProject item in this.playerProject.Projects)
1523  {
1524  project = item; // TODO: what is this?
1525  this.LoadPackage(item);
1526  }
1527 
1528  ReadSettings(this.playerProject.Settings);
1529 
1530  this.isLoadding = false;
1531  return;
1532  }
1533  }
1534  }
1535  catch (System.Exception ex)
1536  {
1537  PrintException(ex);
1538  }
1539 
1540  this.isLoadding = false;
1541  }
1542 
1543  private void ClearSampleGUI()
1544  {
1545  this.treeViewOtxProject.Nodes.Clear();
1546  this.gridViewParameter.Rows.Clear();
1547  this.gridViewContext.Rows.Clear();
1548  this.gridViewState.Rows.Clear();
1549  this.gridViewSettings.Rows.Clear();
1550  }
1551 
1552  private void ClearCustomImplemetationCaches()
1553  {
1554  if (this.contextVariableImplementation != null)
1555  this.contextVariableImplementation.ResetAllValues();
1556 
1557  if (this.contextVariableOutputImpl != null)
1558  this.contextVariableOutputImpl.ResetAllValues();
1559 
1560  if (this.stateVariableImplementation != null)
1561  this.stateVariableImplementation.ResetAllValues();
1562 
1563  //TODO: if (this.stateVariableOutputImpl != null)
1564  }
1565 
1566  // TODO: refactor
1567  private IProject LoadPtx(IRuntimeManager runtimeManager)
1568  {
1569  IProject project = null;
1570 
1571  if (runtimeManager.IsProtected(cbFilePath.Text))
1572  {
1573  project = runtimeManager.LoadPtx(cbFilePath.Text, txtPassword.Text.Trim());
1574  }
1575  else
1576  {
1577  project = runtimeManager.LoadPtx(cbFilePath.Text);
1578  }
1579 
1580  if (project.MainProcedure != null)
1581  {
1582  buttonExecuteMain.Enabled = true;
1583  }
1584 
1585  return project;
1586  }
1587 
1588  // TODO: refactor
1589  private IPlayerProject LoadPpx(IRuntimeManager runtimeManager)
1590  {
1591  IPlayerProject playerProject = null;
1592 
1593  if (runtimeManager.IsProtected(cbFilePath.Text))
1594  {
1595  playerProject = runtimeManager.LoadPpx(cbFilePath.Text, txtPassword.Text.Trim());
1596  }
1597  else
1598  {
1599  playerProject = runtimeManager.LoadPpx(cbFilePath.Text);
1600  }
1601 
1602  return playerProject;
1603  }
1604 
1605  // TODO: refactor
1606  private void LoadPackage(IProject project)
1607  {
1608  PrintText("Browse project...");
1609 
1610  IPackage[] packages = project.Packages;
1611  if (packages == null)
1612  {
1613  IDocument document = project.StartupDocument;
1614  this.treeViewOtxProject.Nodes.Add(CreateDocumentNode(document));
1615  }
1616  else
1617  {
1618  string treeNodeText = project.Name;
1619  if (!String.IsNullOrWhiteSpace(project.Version))
1620  treeNodeText = String.Format("{0} ({1})", treeNodeText, project.Version);
1621 
1622  TreeNode root = new TreeNode(treeNodeText);
1623  root.ImageKey = root.SelectedImageKey = "ODFProject.bmp"; // TODO: move
1624  foreach (IPackage pack in packages)
1625  {
1626  root.Nodes.Add(this.CreatePackageNode(pack));
1627  }
1628 
1629  this.treeViewOtxProject.Nodes.Add(root);
1630  }
1631 
1632  this.treeViewOtxProject.Enabled = this.gridViewParameter.Enabled = true;
1633  this.treeViewOtxProject.ExpandAll();
1634  this.treeViewOtxProject.SelectedNode = startupNode;
1635  this.treeViewOtxProject.Focus();
1636 
1637  PrintText("... project browsing finished.");
1638  }
1639 
1640  // TODO: refactor
1641  private TreeNode CreateDocumentNode(IDocument doc)
1642  {
1643  TreeNode documentNode = new TreeNode(doc.Name);
1644  documentNode.Tag = doc;
1645  documentNode.ImageKey = documentNode.SelectedImageKey = "DocumentOTX16.bmp";
1646  if (doc.IsStartup)
1647  {
1648  documentNode.Text += " (StartUp)";
1649  }
1650 
1651  foreach (IProcedure p in doc.Procedures)
1652  {
1653  TreeNode procedureNode = CreateProcedureNode(p);
1654  documentNode.Nodes.Add(procedureNode);
1655  if (doc.IsStartup && p.Name == "main")
1656  {
1657  startupNode = procedureNode;
1658  buttonExecuteMain.Enabled = true;
1659  }
1660  else if (startupNode == null)
1661  {
1662  startupNode = procedureNode;
1663  }
1664  }
1665 
1666  return documentNode;
1667  }
1668 
1669  // TODO: refactor
1670  private TreeNode CreateProcedureNode(IProcedure procedure)
1671  {
1672  if (checkBoxCyclicReload.Checked &&
1673  procedureToExecute != null &&
1674  procedureToExecute.FullName == procedure.FullName)
1675  {
1676  procedureToExecute = procedure;
1677  }
1678 
1679  TreeNode procedureNode = new TreeNode(procedure.Name);
1680  procedureNode.ImageKey = procedureNode.SelectedImageKey = "Procedure.bmp"; // TODO: move
1681  procedureNode.Tag = procedure;
1682  return procedureNode;
1683  }
1684 
1685  // TODO: refactor
1686  private TreeNode CreatePackageNode(IPackage pack)
1687  {
1688  TreeNode packageNode = new TreeNode(pack.Name);
1689  packageNode.Tag = pack;
1690  packageNode.ImageKey = packageNode.SelectedImageKey = "Package.bmp"; // TODO: move
1691 
1692  List<IDocument> documents = pack.Documents.ToList();
1693  foreach (IDocument doc in documents)
1694  {
1695  packageNode.Nodes.Add(CreateDocumentNode(doc));
1696  }
1697 
1698  foreach (IPackage package in pack.Packages)
1699  {
1700  packageNode.Nodes.Add(this.CreatePackageNode(package));
1701  }
1702 
1703  return packageNode;
1704  }
1705 
1706  // Commit new value for gridView's data source (only apply for DataGridViewCheckBoxCell and DataGridViewComboBoxCell)
1707  private void gridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
1708  {
1709  DataGridView gridView = sender as DataGridView;
1710  if (!this.isLoadding && gridView != null &&
1711  e.RowIndex >= 0 && e.ColumnIndex == 2 &&
1712  (
1713  gridView.Rows[e.RowIndex].Cells[2] is DataGridViewCheckBoxCell ||
1714  gridView.Rows[e.RowIndex].Cells[2] is DataGridViewComboBoxCell
1715  )
1716  )
1717  {
1718  // Force a validation to set the value after CheckBox click
1719  this.Validate(false);
1720  }
1721  }
1722 
1723  // Convert parameter's value into valid string then display it on gridview
1724  void gridViewParameter_CellValidated(object sender, System.Windows.Forms.DataGridViewCellEventArgs e)
1725  {
1726  DataGridView gridView = sender as DataGridView;
1727  if (!this.isLoadding && gridView != null && e.RowIndex >= 0 && e.ColumnIndex == 2)
1728  {
1729  IProcedureParameter parameter = gridView.Rows[e.RowIndex].Tag as IProcedureParameter;
1730  if (parameter.Value != null)
1731  {
1732  gridView.Rows[e.RowIndex].Cells[2].Value = ValueConverter.Value2String(parameter.Value);
1733  }
1734  }
1735  }
1736 
1737  // Trigger if the "value" cell is changed, convert new string into new value,
1738  // then set into corresponding parameter (only apply for IProcedureInParameter and IProcedureInOutParameter)
1739  void gridViewParameter_CellValidating(object sender, System.Windows.Forms.DataGridViewCellValidatingEventArgs e)
1740  {
1741  DataGridView gridView = sender as DataGridView;
1742  if (!this.isLoadding && gridView != null && e.RowIndex >= 0 &&
1743  e.ColumnIndex == 2 &&
1744  !gridView.Rows[e.RowIndex].ReadOnly &&
1745  e.FormattedValue != null)
1746  {
1747  IProcedureParameter parameter = gridView.Rows[e.RowIndex].Tag as IProcedureParameter;
1748  object value = null;
1749 
1750  try
1751  {
1752  value = ValueConverter.String2Value(e.FormattedValue.ToString(), parameter.DataType);
1753  }
1754  catch (System.Exception ex)
1755  {
1756  //string errorMsg = ex.GetType().FullName;
1757  //errorMsg += Environment.NewLine;
1758  //errorMsg += ex.Message;
1759  //gridView.Rows[e.RowIndex].Cells[1].ErrorText = errorMsg;
1760  PrintException(ex);
1761  // e.Cancel = true;
1762  return;
1763  }
1764 
1765  if (value == null)
1766  {
1767  System.Media.SystemSounds.Exclamation.Play();
1768  }
1769  else
1770  {
1771  gridView.Rows[e.RowIndex].Cells[1].ErrorText = string.Empty;
1772  if (parameter is IProcedureInParameter)
1773  (parameter as IProcedureInParameter).Value = value;
1774  else if (parameter is IProcedureInOutParameter)
1775  (parameter as IProcedureInOutParameter).Value = value;
1776  }
1777  }
1778  }
1779 
1780  //private void GridViewParameter_CellEndEdit(object sender, System.Windows.Forms.DataGridViewCellEventArgs e)
1781  //{
1782  // DataGridView gridView = sender as DataGridView;
1783  // gridView.Rows[e.RowIndex].Cells[1].ErrorText = string.Empty;
1784  //}
1785 
1786  void gridViewContextVariable_CellValidated(object sender, System.Windows.Forms.DataGridViewCellEventArgs e)
1787  {
1788  DataGridView gridView = sender as DataGridView;
1789  if (!this.isLoadding && gridView != null &&
1790  e.RowIndex >= 0 &&
1791  e.ColumnIndex == 2)
1792  {
1793  IContextVariable context = gridView.Rows[e.RowIndex].Tag as IContextVariable;
1794  if (gridView.Rows[e.RowIndex].Cells[2].Tag != null)
1795  {
1796  gridView.Rows[e.RowIndex].Cells[2].Value = ValueConverter.Value2String(gridView.Rows[e.RowIndex].Cells[2].Tag);
1797  }
1798  }
1799  }
1800 
1801  // TODO: refactor. consider update to use together with Parameter validating?
1802  void gridViewContextVariable_CellValidating(object sender, System.Windows.Forms.DataGridViewCellValidatingEventArgs e)
1803  {
1804  DataGridView gridView = sender as DataGridView;
1805  if (!this.isLoadding && gridView != null &&
1806  e.RowIndex >= 0 &&
1807  e.ColumnIndex == 2 &&
1808  !gridView.Rows[e.RowIndex].ReadOnly &&
1809  e.FormattedValue != null)
1810  {
1811  IContextVariable context = gridView.Rows[e.RowIndex].Tag as IContextVariable;
1812  object value = null;
1813 
1814  try
1815  {
1816  value = ValueConverter.String2Value(e.FormattedValue.ToString(), context.DataType);
1817  }
1818  catch (System.Exception ex)
1819  {
1820  //string errorMsg = ex.GetType().FullName;
1821  //errorMsg += Environment.NewLine;
1822  //errorMsg += ex.Message;
1823  //gridView.Rows[e.RowIndex].Cells[1].ErrorText = errorMsg;
1824  PrintException(ex);
1825  // e.Cancel = true;
1826  return;
1827  }
1828 
1829  if (value == null)
1830  {
1831  System.Media.SystemSounds.Exclamation.Play();
1832  }
1833  else
1834  {
1835  //we will save value with fullName of context, if not the bug of #10798 occurs.
1836  //Because the name of context variable in imported document may have the same name.
1837  string fullNameContextVariable = context.Document.FullName + '.' + context.Name;
1838  this.contextVariableImplementation.SetValue(fullNameContextVariable, value);
1839  this.contextVariableOutputImpl.SetValue(fullNameContextVariable, value);
1840  gridView.Rows[e.RowIndex].Cells[2].Tag = value;//used at gridViewContextVariable_CellValidated
1841  gridView.Rows[e.RowIndex].Cells[1].ErrorText = string.Empty; //refresh error text
1842  }
1843  }
1844  }
1845 
1846  //private void gridViewContextVariable_CellEndEdit(object sender, System.Windows.Forms.DataGridViewCellEventArgs e)
1847  //{
1848  // DataGridView gridView = sender as DataGridView;
1849  // gridView.Rows[e.RowIndex].Cells[1].ErrorText = string.Empty;
1850  //}
1851 
1852  private void treeViewOtxProject_AfterSelect(object sender, TreeViewEventArgs e)
1853  {
1854  TreeNode node = e.Node;
1855  if (node != null)
1856  {
1857  // TODO: move to different method
1858  this.gridViewParameter.Rows.Clear();
1859  this.gridViewContext.Rows.Clear();
1860  this.gridViewState.Rows.Clear();
1861 
1862  if (node.Tag is IProcedure)
1863  {
1864  IProcedure procedure = node.Tag as IProcedure;
1865  ClearCustomImplemetationCaches();
1866  UpdateGridview(procedure);
1867 
1868  buttonExecuteSelectedProcedure.Enabled = true;
1869  this.project = GetProject(procedure); // TODO: why update this???
1870  return;
1871  }
1872  }
1873 
1874  buttonExecuteSelectedProcedure.Enabled = false;
1875  }
1876 
1877  // TODO: refactor
1878  private IProject GetProject(IProcedure procedure)
1879  {
1880  if (procedure != null)
1881  {
1882  IPackage package = procedure.Document.Package;
1883  if (package != null)
1884  {
1885  while (package.Parent != null)
1886  {
1887  package = package.Parent;
1888  }
1889 
1890  return package.Project;
1891  }
1892  }
1893  return null;
1894  }
1895 
1896  private void treeViewOtxProject_DrawNode(object sender, DrawTreeNodeEventArgs e)
1897  {
1898  e.DrawDefault = true;
1899  }
1900 
1901  // TODO: refactor
1902  private void buttonReadSettings_Click(object sender, EventArgs e)
1903  {
1904  Dictionary<string, string> settings = null;
1905  if (this.playerProject != null)
1906  {
1907  settings = this.playerProject.Settings;
1908  }
1909  else if (this.project != null)
1910  {
1911  settings = this.project.Settings;
1912  }
1913  ReadSettings(settings);
1914  }
1915 
1916  private void ReadSettings(Dictionary<string, string> settings)
1917  {
1918  if (settings != null)
1919  {
1920  PrintText("Read settings");
1921 
1922  gridViewSettings.Rows.Clear();
1923 
1924  foreach (KeyValuePair<string, string> setting in settings)
1925  {
1926  object[] values = new object[] { setting.Key, setting.Value };
1927  this.gridViewSettings.Rows.Add(values);
1928  }
1929  }
1930  }
1931 
1932  // TODO: refactor
1933  private void buttonWriteSettings_Click(object sender, EventArgs e)
1934  {
1935  string nameSetting;
1936  string valueSetting;
1937  int selectedSettingPosition = 0;
1938  Dictionary<string, string> newSettings = new Dictionary<string, string>();
1939 
1940  if (this.gridViewSettings.SelectedRows.Count != 0)
1941  {
1942  selectedSettingPosition = this.gridViewSettings.SelectedRows[0].Index;
1943  }
1944 
1945  try
1946  {
1947  if (project != null || playerProject != null)
1948  {
1949  foreach (DataGridViewRow row in this.gridViewSettings.Rows)
1950  {
1951  nameSetting = row.Cells[this.dataGridViewTextBoxColumnSettingName.Name].Value.ToString();
1952  valueSetting = row.Cells[this.dataGridViewTextBoxColumnSettingValue.Name].Value?.ToString();
1953 
1954  newSettings.Add(nameSetting, valueSetting);
1955  }
1956 
1957  if (playerProject != null)
1958  {
1959  playerProject.Settings = newSettings;
1960  ReadSettings(playerProject.Settings); //Refresh gridViewSettings
1961  }
1962  else
1963  {
1964  project.Settings = newSettings;
1965  ReadSettings(project.Settings); //Refresh gridViewSettings
1966  }
1967  //focus on previous selected row
1968  this.gridViewSettings.Rows[selectedSettingPosition].Selected = true;
1969  this.gridViewSettings.Rows[selectedSettingPosition].Cells[1].Selected = true;
1970 
1971  PrintText("Write settings finished");
1972  }
1973  }
1974  catch (System.Exception ex)
1975  {
1976  PrintException(ex);
1977  }
1978  }
1979 
1980  private void checkBoxCyclicExecution_CheckedChanged(object sender, EventArgs e)
1981  {
1982  this.checkBoxCyclicReload.Enabled = this.checkBoxNewRuntimeManager.Enabled = this.checkBoxCyclicExecution.Checked;
1983 
1984  if (!this.checkBoxCyclicExecution.Checked)
1985  {
1986  this.checkBoxCyclicReload.Checked = this.checkBoxNewRuntimeManager.Checked = false;
1987  }
1988 
1989  SyncWithParent(this.creatorForm?.checkBoxCyclicExecution, this.checkBoxCyclicExecution);
1990  }
1991 
1992  private void checkBoxAsyncExecution_CheckedChanged(object sender, EventArgs e)
1993  {
1994  SyncWithParent(this.creatorForm?.checkBoxAsyncExecution, this.checkBoxAsyncExecution);
1995  }
1996 
1997  private void checkBoxNewRuntimeManager_CheckedChanged(object sender, EventArgs e)
1998  {
1999  if (this.checkBoxNewRuntimeManager.Checked)
2000  {
2001  this.checkBoxCyclicReload.Checked = true;
2002  }
2003 
2004  SyncWithParent(this.creatorForm?.checkBoxNewRuntimeManager, this.checkBoxNewRuntimeManager);
2005  }
2006 
2007  private void checkBoxCyclicReload_CheckedChanged(object sender, EventArgs e)
2008  {
2009  SyncWithParent(this.creatorForm?.checkBoxCyclicReload, this.checkBoxCyclicReload);
2010  }
2011 
2012  // TODO: refactor
2013  private void buttonExecuteSelectedProcedure_Click(object sender, EventArgs e)
2014  {
2015  try
2016  {
2017  if (treeViewOtxProject.SelectedNode != null && treeViewOtxProject.SelectedNode.Tag is IProcedure)
2018  {
2019  IDocument document = treeViewOtxProject.SelectedNode.Parent.Tag as IDocument;
2020  List<string> listItemsReviewed = new List<string>();
2021 
2022  this.procedureToExecute = treeViewOtxProject.SelectedNode.Tag as IProcedure;
2023  this.ExecuteProcedure();
2024  }
2025  else
2026  {
2027  PrintText("Please select Procedure to execute");
2028  }
2029 
2030  }
2031  catch (System.Exception ex)
2032  {
2033  PrintException(ex);
2034  }
2035 
2036  SyncWithParent(this.creatorForm?.buttonExecuteSelectedProcedure, null, true);
2037  }
2038 
2039 
2040  // TODO: refactor
2041  private void buttonExecuteMain_Click(object sender, EventArgs e)
2042  {
2043  try
2044  {
2045  treeViewOtxProject.SelectedNode = startupNode;
2046  this.procedureToExecute = project.MainProcedure;
2047  this.ExecuteProcedure();
2048  }
2049  catch (System.Exception ex)
2050  {
2051  PrintException(ex);
2052  }
2053 
2054  SyncWithParent(this.creatorForm?.buttonExecuteMain, null, true);
2055  }
2056 
2057  // TODO: refactor
2058  private async void ExecuteProcedure()
2059  {
2060  PrintText("Start procedure execution...");
2061 
2062  if (checkBoxAsyncExecution.Checked == false)
2063  {
2064  this.buttonExecuteMain.Enabled = false;
2065  this.buttonExecuteSelectedProcedure.Enabled = false;
2066  }
2067 
2068  try
2069  {
2070  if (this.globalRuntimeManager != null && procedureToExecute != null)
2071  {
2072  this.buttonStop.Enabled = true;
2073 
2074  CheckBatteryIgnitionState(this.globalRuntimeManager);
2075 
2076  if (checkBoxCyclicExecution.Checked)
2077  {
2078  ThreadPool.QueueUserWorkItem(state => DoCyclic());
2079  }
2080  else
2081  {
2082  //OtxDiagManager.OtxDiagApi.License.LicenseManager.SetLicenseKey(SampleConstants.LICENSE_KEY);
2083  if (checkBoxAsyncExecution.Checked)
2084  {
2085  this.globalRuntimeManager.ExecuteAsync(textBoxRuntimeContextName.Text.Trim(), procedureToExecute, this.expectedConnectionState, (ulong)Convert.ToInt32(this.textBoxTimeout.Text));
2086  }
2087  else
2088  {
2089  await Task.Run(() => this.globalRuntimeManager.Execute(textBoxRuntimeContextName.Text.Trim(), procedureToExecute, this.expectedConnectionState, (ulong)Convert.ToInt32(this.textBoxTimeout.Text)));
2090  }
2091  }
2092  }
2093  }
2094  catch (System.Exception ex)
2095  {
2096  PrintException(ex);
2097 
2098  UpdateButtonStateAfterThrowException();
2099  }
2100  }
2101 
2102  private void UpdateButtonStateAfterThrowException()
2103  {
2104  this.buttonExecuteMain.Enabled = !checkBoxCyclicExecution.Checked;
2105  this.buttonExecuteSelectedProcedure.Enabled = !checkBoxCyclicExecution.Checked;
2106 
2107  UpdateExecutionStateButtons(false);
2108  UpdatePauseButton(true, false);
2109 
2110  this.labelBatteryState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconBattery16;
2111  this.labelIgnitionState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconIgnition16;
2112  }
2113 
2114  // TODO: refactor
2115  private void DoCyclic()
2116  {
2117  DateTime startTime = DateTime.Now;
2118 
2119  int cyclic = 0;
2120  try
2121  {
2122  while (checkBoxCyclicExecution.Checked)
2123  {
2124  IRuntimeManager runtimeManager = null;
2125  IRuntimeContext runtimeContext = null;
2126 
2127  cyclic++;
2128  this.cyclicExecutionCount++;
2129 
2130  if (this.checkBoxNewRuntimeManager.Checked)
2131  {
2132  runtimeManager = CreateRuntimeManager();
2133  }
2134  else
2135  {
2136  runtimeManager = this.globalRuntimeManager;
2137  }
2138 
2139  CheckCyclicReloadOrNewRuntimeManager(runtimeManager);
2140 
2141  cyclicExecuteAsyncIsProcessing = true;
2142  CheckBatteryIgnitionState(this.globalRuntimeManager);
2143 
2144  if (this.checkBoxAsyncExecution.Checked)
2145  {
2146  runtimeContext = runtimeManager.ExecuteAsync(textBoxRuntimeContextName.Text.Trim(), procedureToExecute, this.expectedConnectionState, (ulong)Convert.ToInt32(this.textBoxTimeout.Text));
2147  if (runtimeContext != null)
2148  {
2149  //Let it break for a little bit to avoid freezing the GUI
2150  Application.DoEvents();
2151  Thread.Sleep(50);
2152  }
2153  }
2154  else
2155  {
2156  runtimeContext = runtimeManager.Execute(textBoxRuntimeContextName.Text.Trim(), procedureToExecute, this.expectedConnectionState, (ulong)Convert.ToInt32(this.textBoxTimeout.Text));
2157  }
2158 
2159  if (runtimeContext.ExecutionState == ExecutionState.Stopped)
2160  {
2161  this.cyclicExecutionCount = 0;
2162  break;
2163  }
2164  }
2165  }
2166  catch (System.Exception ex)
2167  {
2168  PrintException(ex);
2169 
2170  UpdateButtonStateAfterThrowException();
2171  }
2172 
2173  //TODO: Do we need to load this again?
2174  Invoke(new MethodInvoker(delegate ()
2175  {
2176  if (this.checkBoxNewRuntimeManager.Checked)
2177  {
2178  LoadContextFile(this.globalRuntimeManager);
2179  }
2180  }));
2181 
2182  PrintText("Cyclic execution finished");
2183 
2184  var duration = DateTime.Now - startTime;
2185  string text = String.Format("Execution Statistics: Duration {0} (hh:mm:ss) with {1} cycles and {2:0} ms per cycle", duration.ToString(@"hh\:mm\:ss"), cyclic, duration.TotalMilliseconds / cyclic);
2186 
2187  this.cyclicExecutionCount -= cyclic;
2188  if (this.cyclicExecutionCount < 0)
2189  {
2190  this.cyclicExecutionCount = 0;
2191  }
2192 
2193  if (this.checkBoxAdd2Output.Checked)
2194  {
2195  PrintText(text);
2196  }
2197  else
2198  {
2199  MessageBox.Show(text);
2200  }
2201  }
2202 
2203  private void CheckCyclicReloadOrNewRuntimeManager(IRuntimeManager runtimeMgr)
2204  {
2205  Invoke(new MethodInvoker(delegate ()
2206  {
2207  if (this.checkBoxCyclicReload.Checked || this.checkBoxNewRuntimeManager.Checked)
2208  {
2209  // OR while (!(runtimeContext.IsFinished || runtimeContext.IsStopped))
2210  while (cyclicExecuteAsyncIsProcessing)
2211  {
2212  //detail in #10461
2213  Application.DoEvents();
2214  Thread.Sleep(50);
2215  }
2216  LoadContextFile(runtimeMgr);
2217  }
2218 
2219  if (this.checkBoxCyclicExecution.Checked)
2220  {
2221  this.checkBoxCyclicExecution.Text = "Cyclic (" + this.cyclicExecutionCount + ")";
2222  }
2223  else
2224  {
2225  this.checkBoxCyclicExecution.Text = "Cyclic";
2226  }
2227  }));
2228  }
2229 
2230  // TODO: refactor
2231  private void buttonStop_Click(object sender, EventArgs e)
2232  {
2233  if (this.globalRuntimeManager != null)
2234  {
2235  PrintText(String.Format("Try to stop all running procedures..."));
2236  this.globalRuntimeManager.StopAll();
2237  this.procedureExecutionCount = 0;
2238  }
2239 
2240  // To make sure that cyclic execution will stop in some cases
2241  this.checkBoxCyclicExecution.Checked = false;
2242 
2243  SyncWithParent(this.creatorForm?.buttonStop);
2244  }
2245 
2246  private void PrintException(System.Exception ex, string additionalText = "")
2247  {
2248  PrintText(String.Format("!!! {2}{0}: {1}", ex.GetType().Name, ex.Message, additionalText));
2249  System.Media.SystemSounds.Hand.Play();
2250  }
2251 
2252  private void PrintText(string text)
2253  {
2254  if (InvokeRequired)
2255  {
2256  this.Invoke(new Action(() => PrintText(text)));
2257  return;
2258  }
2259 
2260  if (!this.checkBoxAdd2Output.Checked)
2261  {
2262  return;
2263  }
2264 
2265  // TODO: handle multithreading?
2266  lock (printTextLock)
2267  {
2268  if (this.listBoxOuput.Items.Count >= 10000)
2269  {
2270  buttonClearOutput_Click(null, null);
2271  }
2272 
2273  string prefixString = GetTimeAndDurationStringSinceLastTimeAndUpdateLastTime();
2274  string itemToAdd = prefixString + text + "\t\t";
2275 
2276  this.listBoxOuput.Items.Add(itemToAdd);
2277  this.listBoxOuput.SelectedItems.Clear();
2278  this.listBoxOuput.TopIndex = listBoxOuput.Items.Count - 1;
2279 
2280  if (this.listBoxOuput.Items.Count >= 7500)
2281  {
2282  this.labelOutputOverflow.Visible = true;
2283  }
2284 
2285  // If many procedures are running simultaneously,
2286  // Stop button or other controls cannot receive events. This code allows controls to receive events.
2287  Application.DoEvents();
2288  }
2289  }
2290 
2291  private string GetTimeAndDurationStringSinceLastTimeAndUpdateLastTime()
2292  {
2293  DateTime now = DateTime.Now;
2294  var duration = now - this.lastTime;
2295 
2296  this.lastTime = now;
2297 
2298  string timeDurationString = String.Format("{0:HH:mm:ss.fff} {1,6:#,##0} ms ", now, duration.TotalMilliseconds);
2299  return timeDurationString;
2300  }
2301 
2302  private void buttonCopyRow_Click(object sender, EventArgs e)
2303  {
2304  if (this.listBoxOuput.SelectedItems != null)
2305  {
2306  string text = string.Empty;
2307  foreach (string row in this.listBoxOuput.SelectedItems)
2308  {
2309  text += row.Trim('\t') + "\n";
2310  }
2311 
2312  Clipboard.SetText(text);
2313  }
2314  }
2315 
2316  private void buttonClearOutput_Click(object sender, EventArgs e)
2317  {
2318  this.listBoxOuput.Items.Clear();
2319  this.labelOutputOverflow.Visible = false;
2320  this.buttonCopyRow.Enabled = false;
2321  }
2322 
2323  // TODO: refactor
2324  private void UpdateGridview(IProcedure procedure)
2325  {
2326  if (procedure == null ||
2327  procedure.Parameters == null)
2328  {
2329  return;
2330  }
2331 
2332  UpdateGridviewParameter(procedure);
2333 
2334  IDocument document = procedure.Document;
2335  if (document != null)
2336  {
2337  List<string> listItemsReviewed = new List<string>();
2338  UpdateGridViewContextVariable(document, false, listItemsReviewed);
2339 
2340  listItemsReviewed.Clear();
2341  UpdateGridViewStateVariable(document, false, listItemsReviewed);
2342  }
2343  }
2344 
2345  private void UpdateGridviewParameter(IProcedure procedure)
2346  {
2347  foreach (IProcedureParameter param in procedure.Parameters)
2348  {
2349  UpdateGridviewParameter(param);
2350  }
2351  }
2352 
2353  // TODO: refactor
2354  private void UpdateGridviewParameter(IProcedureParameter parameter)
2355  {
2356  if (parameter == null)
2357  {
2358  return;
2359  }
2360 
2361  bool bValueWasSet = false;
2362 
2363  // Update existing value
2364  string collumnName = dataGridViewTextBoxColumnName.Name;
2365  string collumnValue = dataGridViewTextBoxColumnValue.Name;
2366  foreach (DataGridViewRow row in this.gridViewParameter.Rows)
2367  {
2368  if (row.Cells[collumnName].Value.Equals(parameter.Name))
2369  {
2370  try
2371  {
2372  if (parameter.Value != null)
2373  {
2374  row.Cells[collumnValue].Value = ValueConverter.Value2String(parameter.Value);
2375  }
2376  }
2377  catch (System.Exception ex)
2378  {
2379  row.Cells[collumnValue].ErrorText = ex.Message;
2380  }
2381 
2382  bValueWasSet = true;
2383  break;
2384  }
2385  }
2386 
2387  // Add value if not exist
2388  if (!bValueWasSet)
2389  {
2390  object[] values = new object[] { parameter.Name, parameter.DataType };
2391  int index = this.gridViewParameter.Rows.Add(values);
2392 
2393  this.gridViewParameter.Rows[index].Tag = parameter;
2394 
2395  this.gridViewParameter.Rows[index].ReadOnly = parameter is IProcedureOutParameter || parameter.InitValue == null;
2396 
2397  if (parameter.DataType.Equals("Boolean"))
2398  {
2399  gridViewParameter.Rows[index].Cells[collumnValue] = new DataGridViewCheckBoxCell();
2400  DataGridViewCheckBoxCell cell = gridViewParameter.Rows[index].Cells[collumnValue] as DataGridViewCheckBoxCell;
2401  cell.Value = ValueConverter.Value2String(parameter.Value);
2402  }
2403  else
2404  {
2405  try
2406  {
2407  if (parameter.Value != null)
2408  {
2409  gridViewParameter.Rows[index].Cells[collumnValue].Value = ValueConverter.Value2String(parameter.Value);
2410  }
2411  }
2412  catch (System.Exception ex)
2413  {
2414  gridViewParameter.Rows[index].Cells[collumnValue].ErrorText = ex.Message;
2415  }
2416  }
2417  }
2418  }
2419 
2420  // TODO: refactor
2421  private void UpdateGridViewContextVariable(IDocument document, bool withPrefix, List<string> listItemsReviewed)
2422  {
2423  string @namespace = string.Concat(document.Package.Name, ".", document.Name);
2424  if (listItemsReviewed.Contains(@namespace))
2425  {
2426  return;
2427  }
2428 
2429  listItemsReviewed.Add(@namespace);
2430  foreach (IContextVariable contextVariable in document.ContextVariables)
2431  {
2432  if (contextVariable == null)
2433  {
2434  return;
2435  }
2436 
2437  bool bValueWasSet = false;
2438 
2439  // Update existing value
2440  foreach (DataGridViewRow row in this.gridViewContext.Rows)
2441  {
2442  if (row.Cells[this.dataGridViewTextBoxColumnContextName.Name].Value != null && row.Cells[this.dataGridViewTextBoxColumnContextName.Name].Value.Equals(withPrefix ? (document.Package.FullName + "." + document.Name + "." + contextVariable.Name) : contextVariable.Name))
2443  {
2444  if (radioButtonDefaultImplementation.Checked)
2445  {
2446  object contextVariableValue = this.contextVariableImplementation.GetValue(null, contextVariable, null);
2447  row.Cells[this.dataGridViewTextBoxColumnContextValue.Name].Value = contextVariableValue != null ? ValueConverter.Value2String(contextVariableValue) : null;
2448  }
2449  else
2450  {
2451  row.Cells[this.dataGridViewTextBoxColumnContextValue.Name].Value = contextVariable.InitValue != null ? ValueConverter.Value2String(contextVariable.InitValue) : null;
2452  }
2453 
2454  bValueWasSet = true;
2455  break;
2456  }
2457  }
2458 
2459  // Add value if not exist
2460  if (!bValueWasSet)
2461  {
2462  object[] values = null;
2463  values = new object[] { withPrefix ? (document.Package.FullName + "." + document.Name + "." + contextVariable.Name) : contextVariable.Name, contextVariable.DataType };
2464  int index = this.gridViewContext.Rows.Add(values);
2465 
2466  object contextVariableValue = contextVariable.InitValue;
2467 
2468  this.gridViewContext.Rows[index].Tag = contextVariable;
2469  this.gridViewContext.Rows[index].ReadOnly = contextVariable.InitValue == null;
2470  this.gridViewContext.Rows[index].Cells[2].Tag = contextVariable.InitValue;
2471  if (contextVariable.DataType.Equals("Boolean"))
2472  {
2473  gridViewContext.Rows[index].Cells[dataGridViewTextBoxColumnContextValue.Name] = new DataGridViewCheckBoxCell();
2474  DataGridViewCheckBoxCell cell = gridViewContext.Rows[index].Cells[dataGridViewTextBoxColumnContextValue.Name] as DataGridViewCheckBoxCell;
2475  cell.Value = ValueConverter.Value2String(contextVariableValue);
2476  }
2477  else
2478  {
2479  try
2480  {
2481  if (contextVariableValue != null)
2482  {
2483  gridViewContext.Rows[index].Cells[dataGridViewTextBoxColumnContextValue.Name].Value = ValueConverter.Value2String(contextVariableValue);
2484  }
2485  else
2486  {
2487  gridViewContext.Rows[index].Cells[dataGridViewTextBoxColumnContextValue.Name].Value = null;
2488  }
2489  }
2490  catch (System.Exception ex)
2491  {
2492  gridViewContext.Rows[index].Cells[dataGridViewTextBoxColumnContextValue.Name].ErrorText = ex.Message;
2493  }
2494  }
2495  }
2496  }
2497 
2498  try
2499  {
2500  foreach (IDocument importDoc in document.Imports)
2501  {
2502  UpdateGridViewContextVariable(importDoc, true, listItemsReviewed);
2503  }
2504  }
2505  catch (System.Exception ex)
2506  {
2507  PrintException(ex);
2508  }
2509  }
2510 
2511  // TODO: refactor this
2512  private void StateVariableValueChanged(IStateVariable stateVariable, object value)
2513  {
2514  if (this.InvokeRequired)
2515  {
2516  this.Invoke(new Action(() => StateVariableValueChanged(stateVariable, value)));
2517  return;
2518  }
2519 
2520  string mappingStr = String.Format("[MappedTo: {0}{1}]",
2521  stateVariable.MappingName,
2522  (stateVariable.MappingIndex > -1 ? "[" + stateVariable.MappingIndex + "]" : String.Empty));
2523  string strValue = "null";
2524  try
2525  {
2526  strValue = ValueConverter.Value2String(value);
2527  }
2528  catch
2529  {
2530  }
2531 
2532  string outputLog = String.Format("StateVariableChanged({0} {1}.{2}{3} = {4})",
2533  stateVariable.DataType,
2534  stateVariable.Document.FullName,
2535  stateVariable.Name,
2536  mappingStr,
2537  strValue);
2538  PrintText(outputLog);
2539  UpdateGridViewStateVariable(stateVariable);
2540  }
2541 
2542  private void ContextVariableRead(IContextVariable contextVariable, object value)
2543  {
2544  if (this.InvokeRequired)
2545  {
2546  this.Invoke(new Action(() => ContextVariableRead(contextVariable, value)));
2547  return;
2548  }
2549 
2550  string mappingStr = String.Format("[MappedTo: {0}{1}]",
2551  contextVariable.MappingName,
2552  (contextVariable.MappingIndex > -1 ? "[" + contextVariable.MappingIndex + "]" : String.Empty));
2553  string strValue = "null";
2554  try
2555  {
2556  strValue = ValueConverter.Value2String(value);
2557  }
2558  catch
2559  {
2560  }
2561  string outputLog = String.Format("ContextVariableRead({0} {1}.{2}{3} = {4})",
2562  contextVariable.DataType,
2563  contextVariable.Document.FullName,
2564  contextVariable.Name,
2565  mappingStr,
2566  strValue);
2567 
2568  PrintText(outputLog);
2569  }
2570 
2571  private void UpdateGridViewStateVariable(IDocument document, bool withPrefix, List<string> listItemsReviewed)
2572  {
2573  string @namespace = string.Concat(document.Package.Name, ".", document.Name);
2574  if (listItemsReviewed.Contains(@namespace))
2575  {
2576  return;
2577  }
2578 
2579  listItemsReviewed.Add(@namespace);
2580  foreach (IStateVariable stateVariable in document.StateVariables)
2581  {
2582  object[] values = null;
2583  values = new object[] { withPrefix ? (document.Package.FullName + "." + document.Name + "." + stateVariable.Name) : stateVariable.Name, stateVariable.DataType };
2584  int index = this.gridViewState.Rows.Add(values);
2585 
2586  this.gridViewState.Rows[index].Tag = stateVariable;
2587 
2588  if (stateVariable.DataType.Equals("Boolean"))
2589  {
2590  gridViewState.Rows[index].Cells[dataGridViewTextBoxColumnStateValue.Name] = new DataGridViewCheckBoxCell();
2591  DataGridViewCheckBoxCell cell = gridViewState.Rows[index].Cells[dataGridViewTextBoxColumnStateValue.Name] as DataGridViewCheckBoxCell;
2592  cell.Value = ValueConverter.Value2String(stateVariable.InitValue);
2593  }
2594  else
2595  {
2596  try
2597  {
2598  if (stateVariable.InitValue != null)
2599  {
2600  gridViewState.Rows[index].Cells[dataGridViewTextBoxColumnStateValue.Name].Value = ValueConverter.Value2String(stateVariable.InitValue);
2601  }
2602  }
2603  catch (System.Exception ex)
2604  {
2605  gridViewState.Rows[index].Cells[dataGridViewTextBoxColumnStateValue.Name].ErrorText = ex.Message;
2606  }
2607  }
2608  }
2609 
2610  try
2611  {
2612  foreach (IDocument importDoc in document.Imports)
2613  {
2614  UpdateGridViewStateVariable(importDoc, true, listItemsReviewed);
2615  }
2616  }
2617  catch (System.Exception ex)
2618  {
2619  PrintException(ex);
2620  }
2621  }
2622 
2623 
2624  // TODO: refactor
2625  private void UpdateGridViewStateVariable(IStateVariable stateVar)
2626  {
2627  if (stateVar == null)
2628  {
2629  return;
2630  }
2631 
2632  // Update existing value
2633  foreach (DataGridViewRow row in this.gridViewState.Rows)
2634  {
2635  if (row.Cells[this.dataGridViewTextBoxColumnStateName.Name].Value != null && row.Tag == stateVar)
2636  {
2637  object stateVariableValue = null;
2638 
2639  if (radioButtonDefaultImplementation.Checked)
2640  stateVariableValue = this.stateVariableImplementation.GetValue(stateVar);
2641  else
2642  stateVariableValue = stateVar.InitValue;
2643 
2644  if (stateVariableValue != null)
2645  {
2646  try
2647  {
2648  if (stateVariableValue != null)
2649  {
2650  row.Cells[this.dataGridViewTextBoxColumnStateValue.Name].Value = ValueConverter.Value2String(stateVariableValue);
2651  }
2652  }
2653  catch (System.Exception ex)
2654  {
2655  row.Cells[this.dataGridViewTextBoxColumnStateValue.Name].ErrorText = ex.Message;
2656  }
2657  }
2658  else
2659  row.Cells[this.dataGridViewTextBoxColumnStateValue.Name].Value = null;
2660  break;
2661  }
2662  }
2663 
2664  Application.DoEvents();
2665  }
2666 
2667  private void buttonNewInstance_Click(object sender, EventArgs e)
2668  {
2669  Form form = new SampleForm(SampleConstants.CHILD_INSTANCE_NAME, this);
2670  form.Show();
2671  }
2672 
2673  private void buttonNewInstanceNewThread_Click(object sender, EventArgs e)
2674  {
2675  Thread thread = new Thread(new ThreadStart(NewInstanceInThread));
2676  thread.SetApartmentState(ApartmentState.STA);
2677  thread.Start();
2678  }
2679 
2680  private void NewInstanceInThread()
2681  {
2682  Application.Run(new SampleForm(SampleConstants.CHILD_INSTANCE_NAME, this));
2683  }
2684 
2685  private void buttonHmi_Click(object sender, EventArgs e)
2686  {
2687  if (this.buttonHmi.Checked)
2688  {
2689  hmiWindow = new HmiWindow();
2690  hmiWindow.FormClosing += HmiWindow_FormClosing;
2691  hmiWindow.SizeChanged += HmiWindow_SizeChanged;
2692  hmiWindow.Activated += HmiWindow_Activated;
2693  hmiWindow.Show();
2694 
2695  hmiWindow.Size = new Size(userSettings.HmiWindowWidth, userSettings.HmiWindowHeight);
2696  hmiWindow.Location = new Point(this.Location.X + this.Size.Width, this.Location.Y);
2697  if (this.creatorForm != null && this.creatorForm.hmiWindow != null)
2698  {
2699  this.hmiWindow.Size = this.creatorForm.hmiWindow.Size;
2700  }
2701 
2702  hmiWindow.BringToFront();
2703 
2704  customScreenImplementation.HmiScreenContainer = this.hmiWindow.HmiControl;
2705  }
2706  else if (this.hmiWindow != null)
2707  {
2708  this.hmiWindow.Close();
2709  }
2710 
2711  SyncWithParent(this.creatorForm?.buttonHmi, this.buttonHmi);
2712  }
2713 
2714  private void HmiWindow_FormClosing(object sender, FormClosingEventArgs e)
2715  {
2716  customScreenImplementation.HmiScreenContainer = null;
2717  this.hmiWindow = null;
2718 
2719  this.buttonHmi.Checked = false;
2720  }
2721 
2722  private void HmiWindow_Activated(object sender, EventArgs e)
2723  {
2724  if (customScreenImplementation != null)
2725  {
2726  customScreenImplementation.ActivateHmiScreen();
2727  }
2728  }
2729 
2730  private void HmiWindow_SizeChanged(object sender, EventArgs e)
2731  {
2732  userSettings.HmiWindowWidth = this.hmiWindow.Width;
2733  userSettings.HmiWindowHeight = this.hmiWindow.Height;
2734 
2735  if (customScreenImplementation != null)
2736  {
2737  customScreenImplementation.RefreshHmiScreen();
2738  }
2739  }
2740 
2741  private void CustomScreenImplementation_KeyDown(Runtime.Api.Custom.KeyEventArgs e)
2742  {
2743  string key = "Unknown";
2744  if (e is WpfKeyEventArgs)
2745  {
2746  WpfKeyEventArgs wpfArgs = e as WpfKeyEventArgs;
2747  key = wpfArgs.Key.ToString();
2748  if (wpfArgs.ModifierKey == System.Windows.Input.ModifierKeys.Alt &&
2749  wpfArgs.Key == System.Windows.Input.Key.F4)
2750  {
2751  hmiWindow?.Close();
2752  }
2753  else if (wpfArgs.Key == System.Windows.Input.Key.F10 || wpfArgs.Key == System.Windows.Input.Key.LeftAlt || wpfArgs.Key == System.Windows.Input.Key.RightAlt)
2754  {
2755  e.Handled = true;
2756  }
2757  }
2758  else if (e is FormKeyEventArgs)
2759  {
2760  FormKeyEventArgs formArgs = e as FormKeyEventArgs;
2761  if (formArgs.ModifierKey == Keys.Alt &&
2762  formArgs.Key == Keys.F4)
2763  {
2764  hmiWindow?.Close();
2765  }
2766  else if (formArgs.Key == Keys.F10 || formArgs.Key == Keys.Alt)
2767  {
2768  e.Handled = true;
2769  }
2770  key = formArgs.Key.ToString();
2771  }
2772 
2773  this.PrintText("CustomScreenImplementation_KeyDown(" + key + ")");
2774  }
2775 
2776  // TODO: refactor
2777  private void SampleForm_FormClosing(object sender, FormClosingEventArgs e)
2778  {
2779  // Remove Event
2780  if (this.globalRuntimeManager != null)
2781  {
2782  this.globalRuntimeManager.StopAll();
2783  this.globalRuntimeManager.ProcedurePending -= ProcedurePending;
2784  this.globalRuntimeManager.ProcedureStarted -= ProcedureStarted;
2785  this.globalRuntimeManager.ProcedurePaused -= ProcedurePaused;
2786  this.globalRuntimeManager.ProcedureContinued -= ProcedureContinued;
2787  this.globalRuntimeManager.ProcedureFinished -= ProcedureFinished;
2788  this.globalRuntimeManager.ProcedureStopped -= ProcedureStopped;
2789  this.globalRuntimeManager.ProcedureAborted -= ProcedureAborted;
2790  this.globalRuntimeManager.InOutParameterValueChanged -= InOutParameterValueChanged;
2791  }
2792 
2793  this.stateVariableImplementation.StateVariableValueChanged -= StateVariableValueChanged;
2794 
2795  basicScreenOutputImpl.LogEvent -= PrintText;
2796  customScreenOutputImpl.LogEvent -= PrintText;
2797  loggingOutputImpl.LogEvent -= PrintText;
2798  contextVariableOutputImpl.LogEvent -= PrintText;
2799 
2800  stateVariableOutputImpl.LogEvent -= PrintText;
2801  measureOutputImpl.LogEvent -= PrintText;
2802  i18NOutputImpl.LogEvent -= PrintText;
2803  serviceProviderOutputImpl.LogEvent -= PrintText;
2804 
2805  sqlOutputImpl.LogEvent -= PrintText;
2806  commonDialogsOutputImpl.LogEvent -= PrintText;
2807 
2808  SaveSettings();
2809  }
2810 
2811  private void SaveSettings()
2812  {
2813  if (this.creatorForm == null)
2814  {
2815  // Only main form
2816  userSettings.Ptx_Ppx_Directory = cbFilePath.Text.Trim();
2817  userSettings.Ptx_Ppx_DirectoryList = string.Join(";", this.cbFilePath.Items.Cast<Object>().Select(item => item.ToString()).ToArray());
2818 
2819  userSettings.TraceFileMaxCount = Convert.ToInt32(this.textBoxTraceFileMaxCount.Text.Trim());
2820  userSettings.TraceFileMaxSize = Convert.ToInt32(this.textBoxTraceFileMaxSize.Text.Trim());
2821  userSettings.TraceLevels = RuntimeConfig.Instance.TraceLevel;
2822  userSettings.TracingDirectory = textBoxTraceFolder.Text.Trim();
2823 
2824  userSettings.WindowWidth = this.Size.Width;
2825  userSettings.WindowHeight = this.Size.Height;
2826  userSettings.WindowLocationX = this.Location.X;
2827  userSettings.WindowLocationY = this.Location.Y;
2828  userSettings.CustomImplTypes = GetCurrentCustomImpl();
2829  SaveSocketPortOrPipeName();
2830 
2831  userSettings.Asynchron = checkBoxAsyncExecution.Checked;
2832  userSettings.Cyclic = checkBoxCyclicExecution.Checked;
2833  userSettings.CyclicReload = checkBoxCyclicReload.Checked;
2834  userSettings.NewRunTimeManager = checkBoxNewRuntimeManager.Checked;
2835  userSettings.AddMessageToOutput = checkBoxAdd2Output.Checked;
2836  userSettings.StartAllParents = checkBoxStartAllParents.Checked;
2837 
2838  userSettings.TimeOut = (ulong)Convert.ToInt32(this.textBoxTimeout.Text.Trim());
2839  userSettings.ConnectionState = checkBoxUseConnectionState.Checked;
2840  userSettings.Ignition = checkBoxIgnition.CheckState == CheckState.Checked ? 1 : (checkBoxIgnition.CheckState == CheckState.Unchecked ? 0 : -1);
2841  userSettings.PollingTime = Convert.ToInt32(this.textBoxPollingTime.Text.Trim());
2842  userSettings.VoltageThreshold = Convert.ToInt32(this.textBoxVoltageThreshold.Text.Trim());
2843 
2844  userSettings.RuntimeContextName = this.textBoxRuntimeContextName.Text.Trim();
2845 
2846  SaveSettingUtil.Save();
2847  }
2848  }
2849 
2850  private void SaveSocketPortOrPipeName()
2851  {
2852  var ipcType = (IpcTypes)comboBoxIpcType.SelectedItem;
2853 
2854  switch (ipcType)
2855  {
2856  case IpcTypes.SOCKET:
2857  {
2858  try
2859  {
2860  userSettings.DiagManagerPort = Convert.ToUInt16(textBoxDiagPortPipe.Text.Trim());
2861  userSettings.RuntimePort = Convert.ToUInt16(textBoxRtPortPipe.Text.Trim());
2862  userSettings.IpcType = IpcTypes.SOCKET.ToString();
2863  }
2864  catch (System.Exception)
2865  {
2866  userSettings.DiagManagerPort = SampleConstants.DEFAULT_DM_PORT;
2867  userSettings.RuntimePort = SampleConstants.DEFAULT_RT_PORT;
2868  }
2869  break;
2870  }
2871 
2872  case IpcTypes.PIPE:
2873  {
2874  string diagManagerPipeName = textBoxDiagPortPipe.Text.Trim();
2875  string runtimePipeName = textBoxRtPortPipe.Text.Trim();
2876 
2877  userSettings.DiagManagerPipeName = (diagManagerPipeName != string.Empty) ? diagManagerPipeName : SampleConstants.DEFAULT_DM_PIPE_NAME;
2878  userSettings.RuntimePipeName = (runtimePipeName != string.Empty) ? runtimePipeName : SampleConstants.DEFAULT_RT_PIPE_NAME;
2879  userSettings.IpcType = IpcTypes.PIPE.ToString();
2880  break;
2881  }
2882 
2883  default:
2884  break;
2885  }
2886  }
2887 
2888  private void textBoxRuntimeContextName_TextChanged(object sender, EventArgs e)
2889  {
2890  this.runtimeContextName = this.textBoxRuntimeContextName.Text = this.textBoxRuntimeContextName.Text.Trim();
2891  SetTitle(this.title);
2892  }
2893 
2894  private void listBoxOuput_SelectedIndexChanged(object sender, EventArgs e)
2895  {
2896  this.buttonCopyRow.Enabled = this.listBoxOuput.SelectedItems.Count > 0;
2897  }
2898 
2899  private void buttonPause_Click(object sender, EventArgs e)
2900  {
2901  lock (this.runtimeContexts)
2902  {
2903  if (this.buttonPause.Checked)
2904  {
2905  foreach (IRuntimeContext runtimeContext in this.runtimeContexts)
2906  {
2907  if (runtimeContext.ExecutionState == ExecutionState.Running)
2908  {
2909  runtimeContext.Pause();
2910  }
2911  }
2912  }
2913  else
2914  {
2915  foreach (IRuntimeContext runtimeContext in this.runtimeContexts)
2916  {
2917  if (runtimeContext.ExecutionState == ExecutionState.Paused)
2918  {
2919  runtimeContext.Continue();
2920  }
2921  }
2922  }
2923  }
2924 
2925  SyncWithParent(this.creatorForm?.buttonPause, this.buttonPause);
2926  }
2927 
2928  private void AddRuntimeContext(IRuntimeContext context)
2929  {
2930  lock (this.runtimeContexts)
2931  {
2932  if (!this.runtimeContexts.Contains(context))
2933  {
2934  this.runtimeContexts.Add(context);
2935  }
2936 
2937  if (!runtimeContextsExecutionStartTime.ContainsKey(context))
2938  {
2939  runtimeContextsExecutionStartTime.Add(context, DateTime.Now);
2940  }
2941  }
2942  }
2943 
2944  private void RemoveRuntimeContext(IRuntimeContext context)
2945  {
2946  lock (this.runtimeContexts)
2947  {
2948  if (this.runtimeContexts.Contains(context))
2949  {
2950  this.runtimeContexts.Remove(context);
2951  }
2952 
2953  if (runtimeContextsExecutionStartTime.ContainsKey(context))
2954  {
2955  runtimeContextsExecutionStartTime.Remove(context);
2956  }
2957  }
2958  }
2959 
2960  private bool IsPauseEnabled()
2961  {
2962  lock (this.runtimeContexts)
2963  {
2964  foreach (IRuntimeContext runtimeContext in this.runtimeContexts)
2965  {
2966  if (runtimeContext.ExecutionState == ExecutionState.Running)
2967  {
2968  return true;
2969  }
2970  }
2971 
2972  return false;
2973  }
2974  }
2975 
2976  private bool IsContinueEnable()
2977  {
2978  lock (this.runtimeContexts)
2979  {
2980  foreach (IRuntimeContext runtimeContext in this.runtimeContexts)
2981  {
2982  if (runtimeContext.ExecutionState == ExecutionState.Paused)
2983  {
2984  return true;
2985  }
2986  }
2987 
2988  return false;
2989  }
2990  }
2991 
2992  private void SetExpectedState()
2993  {
2994  if (this.useConnectionState)
2995  {
2996  if (this.KL15State == null)
2997  {
2998  this.expectedConnectionState = ExpectedState.BatteryOn;
2999  }
3000  else if (this.KL15State.Value)
3001  {
3002  this.expectedConnectionState = ExpectedState.IgnitionOn;
3003  }
3004  else
3005  {
3006  this.expectedConnectionState = ExpectedState.IgnitionOff;
3007  }
3008  }
3009  else
3010  {
3011  this.expectedConnectionState = ExpectedState.None;
3012  }
3013  }
3014 
3015  private void checkBoxUseConnectionState_CheckedChanged(object sender, EventArgs e)
3016  {
3017  this.useConnectionState = this.checkBoxUseConnectionState.Checked;
3018  this.EnableConnectionState();
3019  this.SetExpectedState();
3020 
3021  this.labelBatteryState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconBattery16;
3022  this.labelIgnitionState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconIgnition16;
3023 
3024  SyncWithParent(this.creatorForm?.checkBoxUseConnectionState, this.checkBoxUseConnectionState);
3025  }
3026 
3027  private void CheckBoxKL15_CheckStateChanged(object sender, System.EventArgs e)
3028  {
3029  switch (this.checkBoxIgnition.CheckState)
3030  {
3031  case CheckState.Checked:
3032  this.KL15State = true;
3033  break;
3034  case CheckState.Unchecked:
3035  this.KL15State = false;
3036  break;
3037  default:
3038  this.KL15State = null;
3039  break;
3040  }
3041 
3042  this.SetExpectedState();
3043 
3044  SyncWithParent(this.creatorForm?.checkBoxIgnition, this.checkBoxIgnition);
3045  }
3046 
3047  private void EnableConnectionState()
3048  {
3049  this.labelExpectedState.Enabled = this.useConnectionState;
3050  this.labelBatteryState.Enabled = this.useConnectionState;
3051  this.checkBoxIgnition.Enabled = this.useConnectionState;
3052  this.labelPollingTime.Enabled = this.useConnectionState;
3053  this.textBoxPollingTime.Enabled = this.useConnectionState;
3054  this.labelVoltageThreshold.Enabled = this.useConnectionState;
3055  this.textBoxVoltageThreshold.Enabled = this.useConnectionState;
3056  this.buttonCheckBatteryIgnition.Enabled = this.useConnectionState;
3057  }
3058 
3059  private void buttonCheckBatteryIgnition_Click(object sender, EventArgs e)
3060  {
3061  CheckBatteryIgnitionState(this.globalRuntimeManager);
3062 
3063  SyncWithParent(this.creatorForm?.buttonCheckBatteryIgnition, this.buttonCheckBatteryIgnition);
3064  }
3065 
3066  private void textBoxPollingTime_TextChanged(object sender, EventArgs e)
3067  {
3068  try
3069  {
3070  if (Convert.ToInt32(this.textBoxPollingTime.Text) <= 0)
3071  {
3072  this.textBoxPollingTime.Text = defaultPollingTime.ToString();
3073  }
3074  }
3075  catch
3076  {
3077  this.textBoxPollingTime.Text = defaultPollingTime.ToString();
3078  }
3079 
3080  SyncWithParent(this.creatorForm?.textBoxPollingTime, this.textBoxPollingTime);
3081  }
3082 
3083  private void textBoxBatteryVoltageThreshold_TextChanged(object sender, EventArgs e)
3084  {
3085  try
3086  {
3087  if (Convert.ToInt32(this.textBoxVoltageThreshold.Text) <= 0)
3088  {
3089  this.textBoxVoltageThreshold.Text = defaultBatteryVoltageThreshold.ToString();
3090  }
3091  }
3092  catch
3093  {
3094  this.textBoxVoltageThreshold.Text = defaultBatteryVoltageThreshold.ToString();
3095  }
3096 
3097  SyncWithParent(this.creatorForm?.textBoxVoltageThreshold, this.textBoxVoltageThreshold);
3098  }
3099 
3100  private void CheckBatteryIgnitionState(IRuntimeManager runtimeManager)
3101  {
3102  if (this.useConnectionState)
3103  {
3104  runtimeManager.DiagConnectionState.PollingTime = Convert.ToInt32(this.textBoxPollingTime.Text);
3105  runtimeManager.DiagConnectionState.BatteryVoltageThreshold = Convert.ToInt32(this.textBoxVoltageThreshold.Text);
3106  ClampState batteryState = runtimeManager.DiagConnectionState.BatteryState;
3107  ClampState ignitionState = runtimeManager.DiagConnectionState.IgnitionState;
3108 
3109  SetBatteryIgnitionState(batteryState, ignitionState);
3110 
3111  PrintText("Check DiagConnection State - BatteryState = " + batteryState.ToString() + ", IgnitionState = " + ignitionState.ToString());
3112  }
3113  }
3114 
3115  private void SetBatteryIgnitionState(ClampState batteryState, ClampState ignitionState)
3116  {
3117  switch (batteryState)
3118  {
3119  case ClampState.NotAvailable:
3120  this.labelBatteryState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconBatteryNotAvailable16;
3121  break;
3122  case ClampState.Off:
3123  this.labelBatteryState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconBatteryOff16;
3124  break;
3125  case ClampState.On:
3126  this.labelBatteryState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconBatteryOn16;
3127  break;
3128  }
3129 
3130  switch (ignitionState)
3131  {
3132  case ClampState.NotAvailable:
3133  this.labelIgnitionState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconIgnitionNotAvailable16;
3134  break;
3135  case ClampState.Off:
3136  this.labelIgnitionState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconIgnitionOff16;
3137  break;
3138  case ClampState.On:
3139  this.labelIgnitionState.Image = OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.IconIgnitionOn16;
3140  break;
3141  }
3142  }
3143 
3144  private void ShowConnectionStateMessage(IRuntimeContext runtimeContext)
3145  {
3146  if (runtimeContext != null)
3147  {
3148  System.Media.SystemSounds.Beep.Play();
3149 
3150  switch (this.expectedConnectionState)
3151  {
3152  case ExpectedState.BatteryOn:
3153  this.PrintText("----------------------------------------------------------------------------------------------------------------------------------------------");
3154  this.PrintText("-- Not expected connection state: Either it is not possible to communicate with the VCI or the battery is not connected. Please connect it! --");
3155  this.PrintText("----------------------------------------------------------------------------------------------------------------------------------------------");
3156  break;
3157  case ExpectedState.IgnitionOff:
3158  this.PrintText("------------------------------------------------------------------------------------");
3159  this.PrintText("-- Not expected connection state: The ignition must be OFF. Please switch it OFF! --");
3160  this.PrintText("------------------------------------------------------------------------------------");
3161  break;
3162  case ExpectedState.IgnitionOn:
3163  this.PrintText("----------------------------------------------------------------------------------");
3164  this.PrintText("-- Not expected connection state: The ignition must be ON. Please switch it ON! --");
3165  this.PrintText("----------------------------------------------------------------------------------");
3166  break;
3167  default:
3168  break;
3169  }
3170  }
3171  }
3172 
3173  private void checkBoxAdd2Output_CheckedChanged(object sender, EventArgs e)
3174  {
3175  SyncWithParent(this.creatorForm?.checkBoxAdd2Output, this.checkBoxAdd2Output);
3176  }
3177 
3178  private void ParentNumericUpDownSetValue(NumericUpDown numericUpDown, int value)
3179  {
3180  var action = new Action(() => numericUpDown.Value = value);
3181  if (numericUpDown.InvokeRequired)
3182  this.creatorForm.Invoke(action);
3183  else
3184  action.Invoke();
3185  }
3186 
3187  private void comboBoxTraceLevel_SelectedIndexChanged(object sender, EventArgs e)
3188  {
3189  SyncWithParent(this.creatorForm?.comboBoxTraceLevel, this.comboBoxTraceLevel);
3190  }
3191  private void txtPassword_TextChanged(object sender, EventArgs e)
3192  {
3193  SyncWithParent(this.creatorForm?.txtPassword, this.txtPassword);
3194  }
3195 
3196  private void textBoxTimeout_TextChanged(object sender, EventArgs e)
3197  {
3198  SyncWithParent(this.creatorForm?.textBoxTimeout, this.textBoxTimeout);
3199  }
3200 
3201  private void textBoxTraceFileMaxSize_TextChanged(object sender, EventArgs e)
3202  {
3203  if (globalRuntimeManager == null)
3204  return;
3205 
3206  PrintText("Set TraceFileMaxSize to " + this.textBoxTraceFileMaxSize.Text);
3207 
3208  try
3209  {
3210  RuntimeConfig.Instance.TraceFileMaxSize = Convert.ToInt32(this.textBoxTraceFileMaxSize.Text);
3211  SyncWithParent(this.creatorForm?.textBoxTraceFileMaxSize, this.textBoxTraceFileMaxSize);
3212  }
3213 
3214  catch (System.Exception ex)
3215  {
3216  PrintException(ex);
3217  this.textBoxTraceFileMaxSize.Text = RuntimeConfig.Instance.TraceFileMaxSize.ToString();
3218  }
3219  }
3220 
3221  private void textBoxTraceFileMaxCount_TextChanged(object sender, EventArgs e)
3222  {
3223  if (globalRuntimeManager == null)
3224  return;
3225 
3226  PrintText("Set TraceFileMaxCount to " + this.textBoxTraceFileMaxCount.Text);
3227 
3228  try
3229  {
3230  RuntimeConfig.Instance.TraceFileMaxCount = Convert.ToInt32(this.textBoxTraceFileMaxCount.Text);
3231  SyncWithParent(this.creatorForm?.textBoxTraceFileMaxCount, this.textBoxTraceFileMaxCount);
3232  }
3233  catch (System.Exception ex)
3234  {
3235  PrintException(ex);
3236  this.textBoxTraceFileMaxCount.Text = RuntimeConfig.Instance.TraceFileMaxCount.ToString();
3237  }
3238  }
3239 
3240  private void WebServerTimer_Tick(object sender, EventArgs e)
3241  {
3242  this.UpdateWebServerButton();
3243  }
3244 
3245  int isStartWebSever = -1;
3246  private void UpdateWebServerButton()
3247  {
3248  if (this.InvokeRequired)
3249  {
3250  this.Invoke(new Action(() => UpdateWebServerButton()));
3251  return;
3252  }
3253 
3254  if (customScreenImplementation == null)
3255  {
3256  this.buttonStartStopWebServer.Enabled = false;
3257  return;
3258  }
3259 
3260  this.buttonStartStopWebServer.Enabled = true;
3261  if (DefaultCustomScreenImplementation.IsStartedHtmlWebserver()) // Has Start WebServer
3262  {
3263  if (isStartWebSever == 1)
3264  {
3265  return;
3266  }
3267 
3268  this.buttonStartStopWebServer.Image = global::OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.StopWebServer;
3269  isStartWebSever = 1;
3270  }
3271  else
3272  {
3273  if (isStartWebSever == 0)
3274  {
3275  return;
3276  }
3277 
3278  this.buttonStartStopWebServer.Image = global::OpenTestSystem.Otx.Runtime2.Api.DotNet.Sample.Properties.Resources.StartWebServer;
3279  isStartWebSever = 0;
3280  }
3281  }
3282 
3283  private void buttonStartStopWebServer_Click(object sender, EventArgs e)
3284  {
3285  if (this.InvokeRequired)
3286  {
3287  this.Invoke(new Action(() => buttonStartStopWebServer_Click(sender, e)));
3288  return;
3289  }
3290 
3291  if (customScreenImplementation == null)
3292  {
3293  return;
3294  }
3295 
3296  if (!DefaultCustomScreenImplementation.IsStartedHtmlWebserver()) // No Start WebServer
3297  {
3298  customScreenImplementation.StartHtmlWebServer();
3299  }
3300  else
3301  {
3302  customScreenImplementation.StopHtmlWebServer();
3303  }
3304  }
3305  }
3306 }
Namespace containing all interfaces for custom implementations
Definition: IBasicScreenImplementation.cs:7
Namespace which contains all supported data types
Definition: BlackBox.cs:5
Namespace containing exceptions
Definition: ConnectionStateException.cs:7
Namespace containing all objects related to licensing
Definition: IpcLicenseCheckerBase.cs:10
Namespace for browsing at OTX data structure.
Definition: IContextVariable.cs:5
Namespace containing main entries: IProject and IPlayerProject.
Definition: IPlayerProject.cs:5
Namespace containing the programming interface for browsing and execution of OTX procedures in own ap...
Definition: ApiConstants.cs:5
ExecutionStateChangeReason
Reason, why a procedure execution state was changed, e.g. Paused or Running
Definition: ExecutionStateChangeReason.cs:13
TraceLevels
Enumeration of TraceLevels.
Definition: TraceLevels.cs:8
ClampState
Contains the state of a clamp
Definition: ClampState.cs:13
ExecutionState
Contains the state of the runtime context.
Definition: ExecutionState.cs:7
ExpectedState
Contains the expected state of the diagnostic connection
Definition: ExpectedState.cs:13
Namespace containing all objects for browsing and execution of OTX procedures
Definition: ApiConstants.cs:5
Namespace containing all objects which are standardized according to ISO 13209 (OTX)
Namespace containing all objects related to testing inside automotive industry