Collaboration diagram for First step:
void callbackExample(MicoleBus *app, int argc, const char **argv)
Example of binding :
class ExampleAgent: public MicoleAgent { ExampleAgent() { ... bindMessage("^(.*) quitting$", BUS_CALLBACK_OF(ExampleAgent, handleQuitMessage)); ... } ... }; ... void ExampleAgent::handleQuitMessage(MicoleBus *bus, int argc, const char **argv) { /******** Here code to quit application ********/ }
If you add "catch" parenthesis in regular expression, "caught" vars are in argv.
In this case, the regular expression "^(.*) quitting$" will catch all message that will finish by " quitting". In argv[0] you can get the catched message juste before " quitting". argc return number of vars "catched". This is usefull only if your parameters number is not fixed. If you are not familiar with regular expressions, I recommend you to see some documentations before going further.
start(); //Start thread
This is a sample code of implementation of the run method in FF3DDeviceSenderAgent
void FF3DDeviceSenderAgent::run () { Vec3f p = Vec3f(0,0,0); MicoleStringStream s; while(getState()==ACTIVE) { p = _FF3DCoord->get(); s<< "IN FF3D : pos=(" << p.x << ", "<< p.y << ", " << p.z<<");"; if (_buttonPress->eventPressed()) s << " evt=PRESSED;"; if (_buttonPress->eventReleased()) s << " evt=RELEASED;"; sendMessage(s.str()); } ::Sleep(_delay); s.flush(); } }
MyLoggerAggent.h
#ifndef MYLOGGERAGENT_H #define MYLOGGERAGENT_H #include "micolelib.h" #include "MicoleAgent.h" #include <iostream> #include <fstream> using namespace std; class MyLoggerAgent: public MicoleAgent { public: MyLoggerAgent(); virtual ~MyLoggerAgent(); void handleAllMessage ( MicoleBus *app, int argc, const char **argv ); private: ofstream _log; FILE *_logFile; }; #endif
This is a classic class definition.
You can notice the handleAllMessage function prototypes. This is a "bindable" method by MicoleBus. Return type is always void and you have 3 parameters. MicoleBus (we will not take a look on this for the moment), argc (number of arguments in argv), argv: all strings catched by a regular expression. If you want to create new "bindable" method, you MUST follow this prototype.
#include "MyLoggerAgent.h" MyLoggerAgent::MyLoggerAgent() : MicoleAgent("MyLoggerAgent", "Logger") { _log.open(s.str().c_str()); bindMessage("(.*)", BUS_CALLBACK_OF(LoggerAgent, handleAllMessage)); } MyLoggerAgent::~LoggerAgent() { _log.close(); } void MyLoggerAgent::handleAllMessage ( MicoleBus *app, int argc, const char **argv ) { _log << argv[0] << endl; }
This example is pretty short and usefull to debug Micole messages system.
This class already exist in Micole Architecture his name is "LoggerAgent" and I recommend you to use it to monitor your applications.
If you want to filter specific message, you can, for example, catch only input message with "^IN (.*)" regular expression. Prefixes choice is important if you want to filter specific messages.
FF3DDeviceSenderAgent sa = FF3DDeviceSenderAgent(16);
And each 16ms you receive device coordinate on the bus. FF3DDeviceSenderAgent messages is like that
IN FF3D : pos=(-1.330810785e-003, -8.182675362e-002, -4.387708664e-002); evt=RELEASED;
All *DeviceInputAgent are "helpers" and provide you an adapter to handle all "common" possibility of a device.
Each DeviceInputAgent has his own "method" to implement, following his own possibilites. FF3DDeviceInputAgent has virtuals methods onInput and onButtonPress and onButtonRelease. Methods names here are quite explicit.
More information in section Use haptic devices with MicoleLib
After that, you need to send specific messages that corresponding devices can understand.
MicoleStringStream ss; ss << "OUT FF3D : line=(("<<_grab.x<<", "<<_grab.y<<", "<<_grab.z<<"),("<<_position.x<<", "<<_position.y<<", "<<_position.z<<"));"; sendMessage(ss.getString().c_str());
This is an example of a recognized message. If you want all possible messages you can see it at section : Use haptic devices with MicoleLib
void InputAgentExample::onInput() { if (_recording) { _path.push_back(_position); } if (_replay) { Vec3f _diff = _magneticPoint - _position; if (_diff.length()<=0.025) { if (_path.size() > 0) { _magneticPoint = _path.front(); _path.pop_front(); MicoleStringStream s; s << "OUT FF3D GUIDE : point=("<<_magneticPoint.x<<", "<<_magneticPoint.y<<", "<<_magneticPoint.z<<");"; FF3DDeviceInputAgent::sendMessage(s.str()); } else { //no more point in path _replay = 0; FF3DDeviceInputAgent::sendMessage("OUT FF3D GUIDE : none;"); FF3DDeviceInputAgent::sendMessage("OUT VTP : left=(0000000000000000);"); FF3DDeviceInputAgent::sendMessage("OUT VTP : right=(0000000000000000);"); } } } }