The Callback example is meant to show how to register a custom callback function to a property or feature in Impact Acquire.
- Program location
- The source file Callback.cpp can be found under:
%INSTALLDIR%\apps\Callback\
- Note
- If you have installed the package without example applications, this file will not be available. On Windows® the sample application can be installed or removed from the target system at any time by simply restarting the installation package.
- Callback example:
- Opens a Balluff device.
- Shows custom callbacks.
- Console Output
[0]: GX001559 (mvBlueCOUGAR-X122G, Family: mvBlueCOUGAR, interface layout: DeviceSpecific)
[1]: BF000306 (mvBlueFOX-202C, Family: mvBlueFOX, interface layout: DeviceSpecific)
Please enter the number in front of the listed device followed by [ENTER] to open it: 1
Using device number 1.
Initialising the device. This might take some time...
=== List of records BEFORE callbacks ===
This record is called 'The number of the Beast' and since creation it has been played 0 times.
This record is called 'Holy Diver' and since creation it has been played 0 times.
This record is called 'Master of Reality' and since creation it has been played 0 times.
Component 'ImageRequestTimeout_ms' did just cause a callback. It's the 1 time this function got called.
This callback carries 3 good old vinyl records with it.
There is a record called 'The number of the Beast'
There is a record called 'Holy Diver', which I will play now
There is a record called 'Master of Reality'
Component 'ImageRequestTimeout_ms' did just cause a callback. It's the 2 time this function got called.
This callback carries 3 good old vinyl records with it.
There is a record called 'The number of the Beast'
There is a record called 'Holy Diver'
There is a record called 'Master of Reality', which I will play now
Component 'RequestCount' did just cause a callback. It's the 3 time this function got called.
This callback carries 3 good old vinyl records with it.
There is a record called 'The number of the Beast', which I will play now
There is a record called 'Holy Diver'
There is a record called 'Master of Reality'
...
- How it works
After getting the device from user input the sample tries to
-
open the device by calling
-
Attach a custom callback to some driver properties that get called whenever a property is modified.
-
Modify these properties in order to cause the callbacks to be called.
But now step by step through the source:
Any application that wants to get notified when a certain feature in the Impact Acquire property tree did change needs to derive a class from mvIMPACT::acquire::ComponentCallback and override the mvIMPACT::acquire::ComponentCallback::execute() method:
class MyCallback : public ComponentCallback
{
unsigned int hitCount_;
public:
explicit MyCallback( void* pUserData = 0 ) : ComponentCallback( pUserData ),
hitCount_( 0 ) {}
virtual void execute( Component& c, void* pUserData )
{
RecordStack* pRecordStack = reinterpret_cast<RecordStack*>( pUserData );
const RecordStack::size_type recordCount = pRecordStack->size();
cout << "Component '" << c.name() << "' did just cause a callback. It's the " << ++hitCount_ << " time this function got called." << endl
<< "This callback carries " << recordCount << " good old vinyl records with it." << endl;
RecordStack::const_iterator it = pRecordStack->begin();
const RecordStack::const_iterator itEND = pRecordStack->end();
unsigned int i = 0;
while( it != itEND )
{
cout << " There is a record called '" << ( *it )->getAlbum() << "'";
if( hitCount_ % recordCount == i )
{
cout << ", which I will play now";
( *it )->play();
}
cout << endl;
++it;
++i;
}
}
};
In order to be able to do something useful each callback can carry a pointer to arbitrary user data that can be used to get access to any part of the application code within the callback context. This example attaches an instance of the class VinylRecord when creating the callback handler later.
Now within the actual application first of all a device handle must be obtained. In this sample the user is prompted to select the device he wants to use:
DeviceManager devMgr;
Device* pDev = getDeviceFromUserInput( devMgr );
The function getDeviceFromUserInput()
is included via
#include <apps/Common/exampleHelper.h>
Afterwards some interface classes are created in order to get access to some driver properties that shall get a callback attached to.
BasicDeviceSettings bds( pDev );
SystemSettings ss( pDev );
Now some objects that will serve as dummy user data for the callback will be created:
vector<VinylRecord*> vinylRecords;
vinylRecords.push_back( new VinylRecord( "The number of the Beast" ) );
vinylRecords.push_back( new VinylRecord( "Holy Diver" ) );
vinylRecords.push_back( new VinylRecord( "Master of Reality" ) );
Now the actual callback handler will be created and 2 properties will be registered to it:
MyCallback myCallback( &vinylRecords );
myCallback.registerComponent( bds.imageRequestTimeout_ms );
myCallback.registerComponent( ss.requestCount );
When now modifying one of these properties the callback handler will be invoked
for( int i = 1; i < 30; i++ )
{
bds.imageRequestTimeout_ms.write( i );
ss.requestCount.write( i );
}
This can be shown by sending the user data objects to the standard output now. In this example this will increase the play counter of a record:
cout << "=== List of records AFTER callbacks ===" << endl;
for_each( vinylRecords.begin(), vinylRecords.end(), mem_fn( &VinylRecord::display ) );
- Source code
#ifdef _MSC_VER
# if _MSC_VER < 1300
# pragma warning( disable : 4786 )
# endif
#endif
#include <algorithm>
#include <apps/Common/exampleHelper.h>
#include <functional>
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
using namespace std;
class VinylRecord
{
private:
std::string album_;
unsigned int timesPlayed_;
public:
explicit VinylRecord( const std::string& album ) : album_( album ), timesPlayed_( 0 ) {}
bool display( void )
{
cout << "This record is called '" << getAlbum() << "' and since creation it has been played " << getTimesPlayed() << " times." << endl;
return true;
}
const std::string& getAlbum( void ) const
{
return album_;
}
unsigned int getTimesPlayed( void ) const
{
return timesPlayed_;
}
void play( void )
{
++timesPlayed_;
}
};
typedef vector<VinylRecord*> RecordStack;
{
unsigned int hitCount_;
public:
hitCount_( 0 ) {}
virtual void execute(
Component& c,
void* pUserData )
{
RecordStack* pRecordStack = reinterpret_cast<RecordStack*>( pUserData );
const RecordStack::size_type recordCount = pRecordStack->size();
cout <<
"Component '" << c.
name() <<
"' did just cause a callback. It's the " << ++hitCount_ <<
" time this function got called." << endl
<< "This callback carries " << recordCount << " good old vinyl records with it." << endl;
RecordStack::const_iterator it = pRecordStack->begin();
const RecordStack::const_iterator itEND = pRecordStack->end();
unsigned int i = 0;
while( it != itEND )
{
cout << " There is a record called '" << ( *it )->getAlbum() << "'";
if( ( hitCount_ % recordCount ) == i )
{
cout << ", which I will play now";
( *it )->play();
}
cout << endl;
++it;
++i;
}
}
};
int main( void )
{
Device* pDev = getDeviceFromUserInput( devMgr );
if( !pDev )
{
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
{
}
{
cout <<
"An error occurred while opening the device(error code: " << e.
getErrorCode() <<
")." << endl
<< "Press [ENTER] to end the application" << endl;
cin.get();
return 1;
}
vector<VinylRecord*> vinylRecords;
vinylRecords.push_back( new VinylRecord( "The number of the Beast" ) );
vinylRecords.push_back( new VinylRecord( "Holy Diver" ) );
vinylRecords.push_back( new VinylRecord( "Master of Reality" ) );
MyCallback myCallback( &vinylRecords );
myCallback.registerComponent( bds.imageRequestTimeout_ms );
myCallback.registerComponent( ss.requestCount );
const vector<VinylRecord*>::size_type vinylRecordCnt = vinylRecords.size();
cout << "=== List of records BEFORE callbacks ===" << endl;
for( vector<VinylRecord*>::iterator it = vinylRecords.begin(); it != vinylRecords.end(); ++it )
{
( *it )->display();
}
for( int i = 1; i < 30; i++ )
{
bds.imageRequestTimeout_ms.write( i );
ss.requestCount.write( i );
}
cout << "=== List of records AFTER callbacks ===" << endl;
for( vector<VinylRecord*>::iterator it = vinylRecords.begin(); it != vinylRecords.end(); ++it )
{
( *it )->display();
}
myCallback.unregisterComponent( ss.requestCount );
myCallback.unregisterComponent( bds.imageRequestTimeout_ms );
for( vector<VinylRecord*>::size_type j = 0; j < vinylRecordCnt; j++ )
{
delete vinylRecords[j];
}
vinylRecords.clear();
cout << "Press [ENTER] to end the application" << endl;
cin.get();
return 0;
}
A base class for essential device related settings.
Definition mvIMPACT_acquire.h:12215
std::string name(void) const
Returns the name of the component referenced by this object.
Definition mvIMPACT_acquire.h:1206
A simple helper class to wrap the creation of a callback object.
Definition mvIMPACT_acquire.h:2101
A base class to implement access to internal driver components.
Definition mvIMPACT_acquire.h:1439
Grants access to devices that can be operated by this software interface.
Definition mvIMPACT_acquire.h:7171
This class and its functions represent an actual device detected by this interface in the current sys...
Definition mvIMPACT_acquire.h:6118
void open(void)
Opens a device.
Definition mvIMPACT_acquire.h:6420
A base class for exceptions generated by Impact Acquire.
Definition mvIMPACT_acquire.h:256
int getErrorCode(void) const
Returns a unique numerical representation for this error.
Definition mvIMPACT_acquire.h:275
A base class for accessing settings that control the overall behaviour of a device driver.
Definition mvIMPACT_acquire.h:14728
This namespace contains classes and functions belonging to the image acquisition module of this SDK.
Definition mvCommonDataTypes.h:34