Impact Acquire SDK C++
RequestProvider Class Referencefinal

A helper class that can be used to implement a simple continuous acquisition from a device. More...

#include <mvIMPACT_acquire_helper.h>

Public Member Functions

template<typename FUNC , typename ... PARAMS>
void acquisitionStart (FUNC pFn, PARAMS ...params)
 Starts the acquisition.
 
void acquisitionStart (void)
 Starts the acquisition.
 
void acquisitionStop (void)
 Stops the acquisition.
 
void endThreadExecution (void)
 Signaling the acquisition thread to terminate.
 
bool isAcquisitionRunning (void) const
 Returns the current state of the acquisition engine.
 
RequestProvideroperator= (const RequestProvider &rhs)=delete
 assignment operator (deleted)
 
 RequestProvider (const RequestProvider &src)=delete
 Copy-constructor (deleted)
 
 RequestProvider (Device *pDev, RequestFactory *pRequestFactory=nullptr)
 Creates a new mvIMPACT::acquire::helper::RequestProvider instance.
 
void terminateWaitForNextRequest (void)
 Terminates a single wait operation currently pending from another thread without delivering data.
 
std::shared_ptr< RequestwaitForNextRequest (unsigned int ms)
 Waits for the next request to become ready and will return a shared_ptr instance to it.
 
bool waitForNextRequest (unsigned int ms, std::shared_ptr< Request > *ppRequest)
 Waits for the next request to become ready and will return a shared_ptr instance to it.
 
std::shared_ptr< RequestwaitForNextRequest (void)
 Waits for the next request to become ready and will return a shared_ptr instance to it.
 
void waitForThreadTermination (void)
 Waits for the acquisition thread to terminate.
 

Detailed Description

A helper class that can be used to implement a simple continuous acquisition from a device.

This class is meant to provide a very convenient way of capturing data continuously from a device. All buffer handling is done internally. An application simply needs to start and stop the acquisition and can pick up data in between.

Picking up data can be done in 2 ways:

Both methods internally create a thread. When passing the function pointer and parameters the function is invoked from this internal thread context. So an application should not spend much time here in order not to block the acquisition engine. When using the mvIMPACT::acquire::helper::RequestProvider::waitForNextRequest approach the internal thread pushes it's data into an instance of mvIMPACT::acquire::helper::ThreadSafeQueue so capturing can continue if an application does not immediately pick up the data.

Note
Both ways of using the class have their pros and cons. However the mvIMPACT::acquire::helper::ThreadSafeQueue is only served when NOT passing a function pointer.
Internally an instance to mvIMPACT::acquire::FunctionInterface is created. The number of requests available to this mvIMPACT::acquire::helper::RequestProvider must (if needed) be configured before starting the acquisition. See mvIMPACT::acquire::SystemSettings::requestCount for details.
Attention
An application shall NEVER store the raw pointer (mvIMPACT::acquire::Request*) to requests returned wrapped in std::shared_ptr objects! This would jeopardize auto-unlocking of request and thus more or less the purpose of this class. Instead always store the std::shared_ptr objects directly. When no longer needed simply dump them. Keeping them all will result in the acquisition engine to run out of buffers. It can only re-use mvIMPACT::acquire::Request when no more std::shared_ptr references to it exist. On the other hand make sure you did drop all references to requests before the mvIMPACT::acquire::helper::RequestProvider instance that did return them goes out of scope. Not doing this will result in undefined behavior!
// The easiest way to use this class is probably like this:
Device* pDev = getDevicePointerFromSomewhere();
helper::RequestProvider requestProvider( pDev );
requestProvider.acquisitionStart();
for(size_t i = 0; i < 5; i++)
{
std::shared_ptr<Request> pRequest = requestProvider.waitForNextRequest();
std::cout << "Image captured: " << pRequest->imageOffsetX.read() << "x" << pRequest->imageOffsetY.read() << "@" << pRequest->imageWidth.read() << "x" << pRequest->imageHeight.read() << std::endl;
}
requestProvider.acquisitionStop();
This class and its functions represent an actual device detected by this interface in the current sys...
Definition mvIMPACT_acquire.h:6118
A helper class that can be used to implement a simple continuous acquisition from a device.
Definition mvIMPACT_acquire_helper.h:432

a more complex example using the function pointer approach can be found in the description of the corresponding overload of mvIMPACT::acquire::helper::RequestProvider::acquisitionStart.

Note
This class requires a C++11 compliant compiler!
When using this class together with mvIMPACT::acquire::display::ImageDisplay CPP_STANDARD_VERSION must be defined to a value greater than or equal to 11! If not some of the magic in mvIMPACT::acquire::display::ImageDisplay will not be compiled resulting in the auto-unlocking feature of the requests attached to the display will not work and might result in undefined behavior!
Since
2.33.0
Examples
ContinuousCapture.cpp, ContinuousCaptureAllFormats.cpp, ContinuousCaptureFFmpeg.cpp, ContinuousCaptureGenDC.cpp, ContinuousCaptureMultiPart.cpp, ContinuousCapture_BVS-3D-RV0.cpp, ContinuousCapture_BVS-3D-RV1.cpp, GenICamCommonSettingsUsage.cpp, GenICamInterfaceLayout.cpp, and SequenceCapture.cpp.

Constructor & Destructor Documentation

◆ RequestProvider() [1/2]

RequestProvider ( Device * pDev,
RequestFactory * pRequestFactory = nullptr )
inlineexplicit

Creates a new mvIMPACT::acquire::helper::RequestProvider instance.

Parameters
[in]pDevA pointer to a mvIMPACT::acquire::Device object obtained from a mvIMPACT::acquire::DeviceManager object.
[in]pRequestFactoryA pointer to a request factory. By supplying a custom request factory the user can control the type of request objects that will be created by the function interface.

◆ RequestProvider() [2/2]

RequestProvider ( const RequestProvider & src)
delete

Copy-constructor (deleted)

Objects of this type shall not be copy-constructed!

Member Function Documentation

◆ acquisitionStart() [1/2]

template<typename FUNC , typename ... PARAMS>
void acquisitionStart ( FUNC pFn,
PARAMS ... params )
inline

Starts the acquisition.

Will start the acquisition by creating an internal thread. To get access to the data that will be acquired from the device an application passes a callback function and a variable list of arbitrary parameters to this function. Whenever a request becomes ready this function then will be called (from within the internal thread's context!). What kind of function is passed is completely up to the application. The only restriction for the functions signature is that the first parameter must be std::shared_ptr<Request> pRequest.

Attention
Unlocking will be done automatically when the last reference to the std::shared_ptr goes out of scope. As a consequence do NOT store the raw pointer to the mvIMPACT::acquire::Request object stored by the std::shared_ptr but always the std::shared_ptr<Request> itself in order not to break reference counting. Do not call mvIMPACT::acquire::Request::unlock for requests returned wrapped in a std::shared_ptr<Request> (you can but it is not necessary).

If the acquisition is already running then calling this function will raise an exception of type mvIMPACT::acquire::ImpactAcquireException.

// EXAMPLE
//-----------------------------------------------------------------------------
struct ThreadParameter
//-----------------------------------------------------------------------------
{
Device* pDev_;
unsigned int requestsCaptured_;
Statistics statistics_;
explicit ThreadParameter( Device* pDev ) : pDev_( pDev ), requestsCaptured_( 0 ), statistics_( pDev ) {}
ThreadParameter( const ThreadParameter& src ) = delete;
ThreadParameter& operator=( const ThreadParameter& rhs ) = delete;
};
//-----------------------------------------------------------------------------
/// Gets called for each 'Request' object that becomes ready. No need to call 'Request::unlock'!
/// Unlocking will be done automatically when the last 'shared_ptr' reference to this
/// request goes out of scope.
void myThreadCallback( shared_ptr<Request> pRequest, ThreadParameter& threadParameter )
//-----------------------------------------------------------------------------
{
++threadParameter.requestsCaptured_;
// display some statistical information every 100th image
if( threadParameter.requestsCaptured_ % 100 == 0 )
{
const Statistics& s = threadParameter.statistics_;
cout << "Info from " << threadParameter.pDev_->serial.read()
<< ": " << s.framesPerSecond.name() << ": " << s.framesPerSecond.readS()
<< ", " << s.errorCount.name() << ": " << s.errorCount.readS()
<< ", " << s.captureTime_s.name() << ": " << s.captureTime_s.readS() << endl;
}
if( pRequest->isOK() )
{
cout << "Image captured: " << pRequest->imageOffsetX.read() << "x" << pRequest->imageOffsetY.read() << "@" << pRequest->imageWidth.read() << "x" << pRequest->imageHeight.read() << endl;
}
else
{
cout << "Error: " << pRequest->requestResult.readS() << endl;
}
}
//-----------------------------------------------------------------------------
int main( void )
//-----------------------------------------------------------------------------
{
DeviceManager devMgr;
Device* pDev = getDeviceFromUserInput( devMgr );
if( pDev == nullptr )
{
cout << "Unable to continue! Press [ENTER] to end the application" << endl;
cin.get();
return 1;
}
cout << "Initialising the device. This might take some time..." << endl;
try
{
pDev->open();
}
catch( const ImpactAcquireException& e )
{
// this e.g. might happen if the same device is already opened in another process...
cout << "An error occurred while opening the device " << pDev->serial.read()
<< "(error code: " << e.getErrorCodeAsString() << ").";
return 1;
}
cout << "Press [ENTER] to stop the acquisition thread" << endl;
ThreadParameter threadParam( pDev );
helper::RequestProvider requestProvider( pDev );
requestProvider.acquisitionStart( myThreadCallback, std::ref( threadParam ) );
cin.get();
requestProvider.acquisitionStop();
return 0;
}
std::string name(void) const
Returns the name of the component referenced by this object.
Definition mvIMPACT_acquire.h:1206
std::string readS(int index=0, const std::string &format="") const
Reads data from this property as a string.
Definition mvIMPACT_acquire.h:3340
Contains basic statistical information.
Definition mvIMPACT_acquire.h:14509
PropertyF framesPerSecond
A float property (read-only) containing the current number of frames captured per second.
Definition mvIMPACT_acquire.h:14586
PropertyF captureTime_s
A float property (read-only) containing the overall time an image request spent in the device drivers...
Definition mvIMPACT_acquire.h:14560
PropertyI errorCount
An integer property (read-only) containing the overall count of image requests which returned with an...
Definition mvIMPACT_acquire.h:14568
See also
mvIMPACT::acquire::helper::RequestProvider::acquisitionStop,
mvIMPACT::acquire::helper::RequestProvider::waitForNextRequest
Parameters
[in]pFnAn arbitrary function that shall be called from the internal thread context whenever a mvIMPACT::acquire::Request object becomes ready
[in]paramsA variable number of arbitrary arguments that shall be passed to the thread callback function passed as the previous argument.

◆ acquisitionStart() [2/2]

void acquisitionStart ( void )
inline

Starts the acquisition.

Will start the acquisition by creating an internal thread. To get access to captured blocks of data (typically images) an application can periodically call mvIMPACT::acquire::helper::RequestProvider::waitForNextRequest afterwards.

If the acquisition is already running then calling this function will raise an exception of type mvIMPACT::acquire::ImpactAcquireException.

See also
mvIMPACT::acquire::helper::RequestProvider::acquisitionStop,
mvIMPACT::acquire::helper::RequestProvider::waitForNextRequest

◆ acquisitionStop()

void acquisitionStop ( void )
inline

Stops the acquisition.

Will stop the acquisition previously started by a call to mvIMPACT::acquire::helper::RequestProvider::acquisitionStart.

Note
If the acquisition is not running then calling this function will do nothing.
This is a convenience function! Internally this is simply a combination of mvIMPACT::acquire::helper::RequestProvider::endThreadExecution and mvIMPACT::acquire::helper::RequestProvider::waitForThreadTermination.
See also
mvIMPACT::acquire::helper::RequestProvider::acquisitionStart,
mvIMPACT::acquire::helper::RequestProvider::waitForNextRequest

◆ endThreadExecution()

◆ isAcquisitionRunning()

bool isAcquisitionRunning ( void ) const
inline

Returns the current state of the acquisition engine.

Returns
  • true when the internal acquisition thread is running
  • false otherwise
Since
2.50.0

◆ operator=()

RequestProvider & operator= ( const RequestProvider & rhs)
delete

assignment operator (deleted)

Objects of this type shall not be assigned!

◆ terminateWaitForNextRequest()

void terminateWaitForNextRequest ( void )
inline

Terminates a single wait operation currently pending from another thread without delivering data.

If one or multiple thread(s) are currently executing a mvIMPACT::acquire::helper::RequestProvider::waitForNextRequest operation ONE of these threads will get signaled and the call will return.

See also
mvIMPACT::acquire::helper::RequestProvider::waitForNextRequest

◆ waitForNextRequest() [1/3]

std::shared_ptr< Request > waitForNextRequest ( unsigned int ms)
inline

Waits for the next request to become ready and will return a shared_ptr instance to it.

Waits for the next request to become ready and will return a std::shared_ptr<Request> instance to it effectively removing it from the internal queue. This is a blocking function. It will return not unless either a mvIMPACT::acquire::Request object became ready, the specified timeout did elapse or mvIMPACT::acquire::helper::RequestProvider::terminateWaitForNextRequest has been called from a different thread.

See also
mvIMPACT::acquire::helper::RequestProvider::acquisitionStart,
mvIMPACT::acquire::helper::RequestProvider::terminateWaitForNextRequest
Returns
A std::shared_ptr<Request> either holding a valid pointer to a mvIMPACT::acquire::Request object or nullptr if no data became ready and either mvIMPACT::acquire::helper::RequestProvider::terminateWaitForNextRequest has been called from another thread or the specified timeout has elapsed.
Parameters
[in]msA timeout in milliseconds specifying the maximum time this function shall wait for a request to become ready

◆ waitForNextRequest() [2/3]

bool waitForNextRequest ( unsigned int ms,
std::shared_ptr< Request > * ppRequest )
inline

Waits for the next request to become ready and will return a shared_ptr instance to it.

Waits for the next request to become ready and will return a std::shared_ptr<Request> instance to it effectively removing it from the internal queue. This is a blocking function. It will return not unless either a mvIMPACT::acquire::Request object became ready, the specified timeout did elapse or mvIMPACT::acquire::helper::RequestProvider::terminateWaitForNextRequest has been called from a different thread.

See also
mvIMPACT::acquire::helper::RequestProvider::acquisitionStart,
mvIMPACT::acquire::helper::RequestProvider::terminateWaitForNextRequest
Returns
  • true when a new request became ready
  • false otherwise
Parameters
[in]msA timeout in milliseconds specifying the maximum time this function shall wait for a request to become ready
[in,out]ppRequestA pointer to the storage location that shall receive a pointer to the next mvIMPACT::acquire::Request object that becomes ready or the oldest element already available. An application can pass nullptr if a caller just wants to remove an element from the queue but is not actually interested in it.

◆ waitForNextRequest() [3/3]

std::shared_ptr< Request > waitForNextRequest ( void )
inline

Waits for the next request to become ready and will return a shared_ptr instance to it.

Waits for the next request to become ready and will return a std::shared_ptr<Request> instance to it effectively removing it from the internal queue. This is a blocking function. It will return not unless either a mvIMPACT::acquire::Request object became ready or mvIMPACT::acquire::helper::RequestProvider::terminateWaitForNextRequest has been called from a different thread.

See also
mvIMPACT::acquire::helper::RequestProvider::acquisitionStart,
mvIMPACT::acquire::helper::RequestProvider::terminateWaitForNextRequest
Returns
A std::shared_ptr<Request> either holding a valid pointer to a mvIMPACT::acquire::Request object or nullptr if no data became ready and mvIMPACT::acquire::helper::RequestProvider::terminateWaitForNextRequest has been called from another thread.

◆ waitForThreadTermination()

void waitForThreadTermination ( void )
inline