FrontPanel API 5.3.5
|
Class for managing device connections and disconnections. More...
Classes | |
struct | CallbackInfo |
Helper used for device monitoring by FrontPanelManager. More... | |
Public Member Functions | |
FrontPanelManager () | |
Default constructor. | |
virtual | ~FrontPanelManager () |
void | StartMonitoring (CallbackInfo *cbInfo=NULL) |
Start monitoring for Opal Kelly devices connections and disconnections. | |
void | StopMonitoring () |
int | EnterMonitorLoop (CallbackInfo &callbackInfo, int millisecondsTimeout=0) |
void | ExitMonitorLoop (int exitCode=0) |
virtual void | OnDeviceAdded (const char *serial)=0 |
Called when a new device is connected to the system. | |
virtual void | OnDeviceRemoved (const char *serial)=0 |
Called when a device is disconnected from the system. | |
okCFrontPanel * | Open (const char *serial) |
Create a new device object from the serial number. | |
This class allows to be notified about devices connections and disconnections.
To receive these notifications, you need to derive your own manager subclass from this class and override its virtual OnDeviceAdded() and OnDeviceRemoved() methods.
Notice that for these methods to actually be called whenever devices are connected or disconnected, either an event loop must be running or a separate thread must be used. As any standard GUI application under Microsoft Windows and macOS platforms typically does run an event loop, this class assumes that one is running under these platforms. Under other Unix systems, e.g. Linux, the application must indicate whether it uses an event loop or not: if it does, it should pass a valid CallbackInfo argument to StartMonitoring() function and then set things up so that the specified callback function is called whenever there is input on the file descriptor returned via CallbackInfo object by registering this descriptor with the event loop. Otherwise, it shouldn't pass any CallbackInfo and a worker thread for monitoring the device will be created internally instead.
If there is no event loop already running, e.g. in a console application, it is also possible to use EnterMonitorLoop() method to run a dedicated event loop just for the device connection detection. This method should be normally called in a separate thread, as it blocks the program execution until ExitMonitorLoop() loop is called. Typically, the program would create a thread and call first StartMonitoring() and then EnterMonitorLoop() from that thread. Notice that initially OnDeviceAdded() is called directly by StartMonitoring() and, hence, in the context of the thread calling that method, while subsequent OnDeviceAdded() and OnDeviceRemoved() calls will be performed from the thread in which EnterMonitorLoop() was called. To avoid confusion, it is strongly recommended to call both StartMonitoring() and EnterMonitorLoop() from the same thread. Use StopMonitoring() function to stop monitoring if it was started (with StartMonitoring()) in the separate thread. EnterMonitorLoop() can be called with timeout from the main application loop if there is no ability to use a separate thread.
Alternatively, use FrontPanelDevices if you need to simply open a connected device and are not interested in getting notifications for the devices connections and disconnections.
See Open() method documentation for a simple example of doing this.
OpalKelly::FrontPanelManager::FrontPanelManager | ( | ) |
This constructor doesn't do anything special, call StartMonitoring() to enable calls to OnDeviceAdded() and OnDeviceRemoved() methods.
|
virtual |
Destructor stops monitoring the devices.
Notice that StopMonitoring() method can be called, if you need to stop monitoring the devices before destroying the object. This is notably required if StartMonitoring() is called from a thread different from the one in which the object will be destroyed as the monitoring must be started and stopped from the same thread.
int OpalKelly::FrontPanelManager::EnterMonitorLoop | ( | CallbackInfo & | callbackInfo, |
int | millisecondsTimeout = 0 ) |
Listen for events about devices connections and disconnections in a loop.
This function doesn't return until ExitMonitorLoop() is called from another thread. Use it if you don't already have a message loop in your main program.
If the loop cannot be started, throws a runtime_error
exception.
callbackInfo | The same object that was passed to StartMonitoring(). |
millisecondsTimeout | The timeout in milliseconds. Zero timeout means that the function doesn't return until ExitMainLoop() is called, i.e. effectively no timeout. Throws an out_of_range exception if the value is negative. |
void OpalKelly::FrontPanelManager::ExitMonitorLoop | ( | int | exitCode = 0 | ) |
Stop the currently running monitoring loop.
Calling this function terminates EnterMonitorLoop().
Notice that it has, by necessity, to be called from another thread as EnterMonitorLoop() blocks the execution of the thread it is running in until it returns.
exitCode | The exit code to return from EnterMonitorLoop(), by convention 0 indicates success and any non-zero value an error. |
|
pure virtual |
The application will typically call FrontPanelManager::Open() to open the newly connected device.
[in] | serial | Unique identifier of the new device. |
|
pure virtual |
This callback can be used to remove the currently shown device from the application UI, for example.
Notice that serial will normally correspond to the same parameter of a previous call to OnDeviceAdded().
[in] | serial | Unique identifier of the disconnected device. |
okCFrontPanel * OpalKelly::FrontPanelManager::Open | ( | const char * | serial | ) |
Notice that the caller must delete the pointer returned by this method. The best way to do it is to ensure that it happens automatically by assigning its result to std::shared_ptr<>
or std::unique_ptr<>
. Otherwise you need to do it manually, e.g:
[in] | serial | The serial number of the device to open, typically obtained from a call to OnDeviceAdded(). |
NULL
if opening the device failed. void OpalKelly::FrontPanelManager::StartMonitoring | ( | CallbackInfo * | cbInfo = NULL | ) |
Call this method to subscribe to device connection and disconnection messages. If subscription fails, an std::runtime_error
exception is thrown.
Otherwise, OnDeviceAdded() will be called for each device connected at the moment of this call, allowing the application to build a full list of them.
Notice that this method relies on having a working event loop in the calling application which should dispatch OS-level notifications that are generated when the devices are added to or removed from the system, the notifications won't be generated without a running event loop.
If there is no running event loop or if the platform requires the use of cbInfo but it isn't provided or the file descriptor returned in it is not registered with the event loop, device connection and disconnection detection won't work, i.e. OnDeviceAdded() won't be called for the subsequently connected devices (it is still called for the devices already connected at the moment of this call) and OnDeviceRemoved() won't be called at all.
cbInfo | Information about the callback which needs to be executed when the file descriptor specified in this struct becomes available for reading. This is only used under (non-macOS) Unix systems where the library doesn't have any other way to monitor the devices. If this argument is null or its descriptor is not monitored to the main loop, a separate thread will be created internally to monitor the devices, as described above. |
void OpalKelly::FrontPanelManager::StopMonitoring | ( | ) |
Stops monitoring and notifies about the currently connected FrontPanel devices.
This function is only useful when StartMonitoring() is called from a thread different from the one in which the manager was created, otherwise there is no real need to call StopMonitoring() as this will be done in the object destructor anyhow.
However, if StartMonitoring() is called from another thread, you must call StopMonitoring() from the same thread before destroying the manager object.
Notice that if you call StopMonitoring() and then StartMonitoring(), OnDeviceAdded() will be called again for all currently connected devices.
An exception of runtime_error
class is thrown if stopping monitoring failed.