4using System.Collections.Generic;
5using System.ComponentModel;
6using System.Diagnostics.CodeAnalysis;
7using System.Drawing.Design;
10using System.Threading.Tasks;
11using System.Windows.Forms;
15#pragma warning disable 169
36 [SuppressMessage(
"ReSharper",
"MemberCanBePrivate.Global")]
37 [SuppressMessage(
"ReSharper",
"UnusedMember.Global")]
46 INotifyPropertyChanged,
55 #region private variables
59 #endregion private variables
69 internal static readonly List<MockDevice> Instances =
new List<MockDevice>();
73 Instances.Remove(
this);
101 $
"Making a {composition.Volume} mL frappuccino with cream type \"{composition.Cream}\"{(composition.DeCaffeinated ? ", decaffeinated.
" : "")}.");
109 DebugOutput?.Invoke($
"Dummy method of {Name} was called.");
140 #region INeedAConnection
151 #endregion INeedAConnection
153 #region Custom methods and properties
164 $
"The following message was shown addressing the mock device {Name}:\r\n{messageText}",
166 MessageBoxButtons.OK);
167 DebugOutput?.Invoke($
"Finished showing the message {messageText}");
189 #endregion Custom methods and properties
191 #region IProvideStatusMessages
195 #endregion IProvideStatusMessages
197 #region IHaveDebugOutput
201 #endregion IHaveDebugOutput
203 #region INotifyPropertyChanged
211 if (myHandler !=
null)
219 #endregion INotifyPropertyChanged
221 #region IAbortSchedules
242 RestartRemainingJobs =
false
258 throw new OperationCanceledException(
"Aborted");
262 #endregion IAbortSchedules
264 #region Implementation of IHaveMachineParameters<CoffeMakerParams>
271 SetStatusMessage?.Invoke($
"Applying parameters: '{Parameters}' and {(!waitUntilSetpointIsReached ? "not
" : "")} waiting for setpoint.");
272 if (waitUntilSetpointIsReached)
274 return Task.Delay(TimeSpan.FromSeconds(10),canToken);
276 return Task.CompletedTask;
279 #endregion Implementation of IHaveMachineParameters<CoffeMakerParams>
283 WaitHandle.WaitAny(
new[] {
mPauseEnded.WaitHandle, mAborted.WaitHandle });
287 #region Implementation of ICanInterrupt
292 private readonly ManualResetEventSlim
mPauseEnded =
new ManualResetEventSlim(
true);
294 private readonly ManualResetEventSlim
mAborted =
new ManualResetEventSlim(
false);
321 #endregion Implementation of ICanInterrupt
326 public Func<StopRunArgs, Task>
StopRun {
get;
set; }
328 #region Schedule state events
352 DebugOutput?.Invoke($
"Schedule {e.PlanerName} ({e.PlanerID}) state {e.State}, abort reason {(string.IsNullOrEmpty(e.AbortReason) ? "N/A
" : e.AbortReason)}");
358 DebugOutput?.Invoke(
"Starting error handling interaction");
363 DebugOutput?.Invoke(
"Ending error handling interaction");
378 }
while (errArgs.RetryLastAction);
382 throw new IOException($
"Coffee machine reported a problem: {errorDescription}");
385 public event EventHandler<InteractiveErrorHandlingEventArgs>
HandleError;
Classes and interfaces that are meant for plugins. The classes and interfaces below this namespace ar...
ConnectionState
If your connectivity state changes, you should tell the user about it.
ErrorType
Lets a device implementing IHaveInteractiveErrorHandling specify which kind of error occurred.
A fake device. This namespace contains the fake device driver and auxiliary classes for settings,...
Example task implementations. Since there are lots of things that can be done from a task,...
The classes in this namespace demonstrate how to interact with the Chronos sample list.
To be implemented by the "device driver" part of a Chronos plugin.
For devices that need some kind of user configured connection string to address the hardware.
Implement this interface if you want to keep the user up-to-date about what your device is doing.
Implement this interface if you wish to provide debug log output.
Implement this interface if you need to abort schedules on some error condition.
Everything needed for showing the error dialog / reacting on input.
For devices that allow interactive error handling (like retrying the last action)
For devices that support pausing/aborting independent of a task.
Parameters that are constant for the duration of a schedule.
Helper functions for GUI related tasks.
System.Threading.Tasks.TaskFactory GuiTaskFactory
For your convenience, a default task factory for tasks running on the GUI thread.
IWin32Window MainWindow
If you need to set the owner window yourself or want to show message boxes.
Information about the current state change.
Currently starting schedule stage.
Implement this interface if you need to track the state of schedules.
This can be called for a sample list worker or device that writes its own set of log files which shou...
Implement this interface with your device or sample list worker to get fine-grained control about sto...
Options for stopping the schedule/queue.
StopMode
Details how to stop the run.
We have a fancy coffee machine that can regulate the warmer temperature for the pot and has lamps for...
Just a primitive UI Type Editor to demonstrate how you can add an editor of your own for connection s...
A chronos plugin implementation for a fake device. We pretend we are controlling a mixture of coffee ...
PropertyChangedEventHandler PropertyChanged
Action< string > DebugOutput
Action< string > SetStatusMessage
bool Aborted
If set, abort execution as soon as possible. You can throw an OperationCanceledException....
void BrewFrappuccino(BrewFrappuccino.CompositionData composition)
Pretend we are doing some operation on a complex parameter set.
void Connect()
Inform the user of our connect attempt / success. Instead of establishing a real connection,...
readonly ManualResetEventSlim mPauseEnded
Using an event here instead of a simple bool helps us avoid polling while checking for the events.
Action< string > AbortSchedule
void SomeDummyMethod()
Just for testing if methods of this device can be called from some other point in our code.
void OnIsConnectedChanged()
For thread-safe update of the toolbox's GUI elements representing the connection state.
EventHandler< InteractiveErrorHandlingEventArgs > HandleError
void Disconnect()
Pretend we are closing the connection. Actual operation substituted by a message box.
void ScheduleStateChangedHandler(object sender, ScheduleStateEventArgs e)
bool IsConnected
Helper for our toolbox.
Func< StopRunArgs, Task > StopRun
Callback function returning a task that completes once the schedule queue was stopped.
IScheduleEvents mScheduleEvents
void ShowTheMessage(string messageText)
Let our device set a status message and display some message box instead of doing real work.
string Name
User-selected name for the device instance.
Task ApplyParametersAsync(bool waitUntilSetpointIsReached, CancellationToken canToken)
string DisplayedTypeName
Visible to the user on the instruments page of the settings editor.
string DeviceTypeDescription
Device class specification referred to by some messages.
void TriggerAbort(string reason, bool softStop)
This will trigger the AbortSchedule-Event 5 seconds after it was called from a task.
IEnumerable< string > LogPaths
Provide full paths to each of your log files here.
bool Paused
If paused, wait until paused is reset before executing the next command.
readonly IGuiHelper mGuiHelper
void EndInteraction()
Will be called if you can lock the terminal again.
CoffeMakerParams Parameters
MockDevice(IGuiHelper guiHelper)
string Connection
Connection as set in the Chronos instrument settings.
void BeginInteraction()
Will be called if interaction is started, gives you a chance to unlock a terminal,...
readonly ManualResetEventSlim mAborted
IScheduleEvents ScheduleEvents
Hook up immediately or save this for later use.
Action< ConnectionState > ConnectionStateChanged
void RaiseError(string errorDescription, ErrorType errType, bool resolved)
"Retry" here means that we don't retry some action, but that we raise the error again.
const string DeviceTypeName
Provides an endless supply of nonsense sample lists.
static IEnumerable< string > GetFakeLogs(string creator)
Creates a few fake log files.
A task working on a complex parameter set.
Let's pretend the composition is really complex and better done with a custom editor.