mirror of
https://github.com/wjwwood/serial.git
synced 2026-01-22 11:44:53 +08:00
Serial Listener changes compile against the example reference, time to merge with John.
This commit is contained in:
parent
7c0c976033
commit
dfd1837cfc
@ -36,10 +36,10 @@ int main(void) {
|
|||||||
// Method #2:
|
// Method #2:
|
||||||
// comparator - blocking
|
// comparator - blocking
|
||||||
{
|
{
|
||||||
BlockingFilter f2 =
|
BlockingFilterPtr f2 =
|
||||||
listener.createBlockingFilter(SerialListener::endsWith("post"));
|
listener.createBlockingFilter(SerialListener::endsWith("post"));
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
std::string token = f2.wait(100); // Wait for 100 ms or a matched token
|
std::string token = f2->wait(100); // Wait for 100 ms or a matched token
|
||||||
if (token == "")
|
if (token == "")
|
||||||
std::cout << "Found something ending with 'post'" << std::endl;
|
std::cout << "Found something ending with 'post'" << std::endl;
|
||||||
else
|
else
|
||||||
@ -54,18 +54,18 @@ int main(void) {
|
|||||||
// comparator, token buffer size - blocking
|
// comparator, token buffer size - blocking
|
||||||
{
|
{
|
||||||
// Give it a comparator, then a buffer size of 10
|
// Give it a comparator, then a buffer size of 10
|
||||||
BufferedFilter f3 =
|
BufferedFilterPtr f3 =
|
||||||
listener.createBufferedFilter(SerialListener::contains("substr"), 10);
|
listener.createBufferedFilter(SerialListener::contains("substr"), 10);
|
||||||
SerialListener::sleep(75); // Sleep 75ms, should have about 7
|
SerialListener::sleep(75); // Sleep 75ms, should have about 7
|
||||||
std::cout << "Caught " << f3.count();
|
std::cout << "Caught " << f3->count();
|
||||||
std::cout << " tokens containing 'substr'" << std::endl;
|
std::cout << " tokens containing 'substr'" << std::endl;
|
||||||
for(size_t i = 0; i < 20; ++i) {
|
for(size_t i = 0; i < 20; ++i) {
|
||||||
std::string token = f3.wait(5); // Pull message from the buffer
|
std::string token = f3->wait(5); // Pull message from the buffer
|
||||||
if (token == "") // If an empty string is returned, a timeout occured
|
if (token == "") // If an empty string is returned, a timeout occured
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
f3.clear(); // Empties the buffer
|
f3->clear(); // Empties the buffer
|
||||||
if (f3.wait(0) == "") // Non-blocking wait
|
if (f3->wait(0) == "") // Non-blocking wait
|
||||||
std::cout << "We won the race condition!" << std::endl;
|
std::cout << "We won the race condition!" << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "We lost the race condition..." << std::endl;
|
std::cout << "We lost the race condition..." << std::endl;
|
||||||
|
|||||||
@ -178,160 +178,31 @@ public:
|
|||||||
*/
|
*/
|
||||||
typedef boost::shared_ptr<Filter> FilterPtr;
|
typedef boost::shared_ptr<Filter> FilterPtr;
|
||||||
|
|
||||||
/*!
|
class BlockingFilter;
|
||||||
* This is the a filter that provides a wait function for blocking until a
|
|
||||||
* match is found.
|
|
||||||
*
|
|
||||||
* This should probably not be created manually, but instead should be
|
|
||||||
* constructed using SerialListener::createBlockingFilter(ComparatorType)
|
|
||||||
* function which returns a BlockingFilter instance.
|
|
||||||
*
|
|
||||||
* \see serial::SerialListener::ComparatorType,
|
|
||||||
* serial::SerialListener::createBlockingFilter
|
|
||||||
*/
|
|
||||||
class BlockingFilter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BlockingFilter (ComparatorType comparator,
|
|
||||||
boost::shared_ptr<SerialListener> listener)
|
|
||||||
: listener(listener)
|
|
||||||
{
|
|
||||||
DataCallback cb = boost::bind(&BlockingFilter::callback, this, _1);
|
|
||||||
this->filter_ptr = listener.createFilter(comparator, cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~BlockingFilter () {
|
|
||||||
this->listener.removeFilter(filter_ptr);
|
|
||||||
this->result = "";
|
|
||||||
this->cond.notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Waits a given number of milliseconds or until a token is matched. If a
|
|
||||||
* token is matched it is returned, otherwise an empty string is returned.
|
|
||||||
*
|
|
||||||
* \param ms Time in milliseconds to wait on a new token.
|
|
||||||
*
|
|
||||||
* \return std::string token that was matched or "" if none were matched.
|
|
||||||
*/
|
|
||||||
std::string wait(size_t ms) {
|
|
||||||
this->result = "";
|
|
||||||
boost::unique_lock<boost::mutex> lock(this->mutex);
|
|
||||||
this->cond.timed_wait(lock, boost::posix_time::milliseconds(ms));
|
|
||||||
return this->result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void callback(const std::string& token) {
|
|
||||||
this->cond.notify_all();
|
|
||||||
this->result = token;
|
|
||||||
}
|
|
||||||
|
|
||||||
FilterPtr filter_ptr;
|
|
||||||
boost::shared_ptr<SerialListener> listener;
|
|
||||||
boost::condition_variable cond;
|
|
||||||
boost::mutex mutex;
|
|
||||||
std::string result;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This is the a filter that provides a wait function for blocking until a
|
* Shared Pointer of BlockingFilter, returned by
|
||||||
* match is found. It will also buffer up to a given buffer size of tokens so
|
* SerialListener::createBlockingFilter.
|
||||||
* that they can be counted or accessed after they are matched by the filter.
|
|
||||||
*
|
*
|
||||||
* This should probably not be created manually, but instead should be
|
* \see serial::BlockingFilter, SerialListener::createBlockingFilter
|
||||||
* constructed using SerialListener::createBufferedFilter(ComparatorType)
|
|
||||||
* function which returns a BufferedFilter instance.
|
|
||||||
*
|
|
||||||
* The internal buffer is a circular queue buffer, so when the buffer is full,
|
|
||||||
* the oldest token is dropped and the new one is added. Additionally, when
|
|
||||||
* wait is a called the oldest available token is returned.
|
|
||||||
*
|
|
||||||
* \see serial::SerialListener::ComparatorType,
|
|
||||||
* serial::SerialListener::createBufferedFilter
|
|
||||||
*/
|
*/
|
||||||
class BufferedFilter
|
typedef boost::shared_ptr<BlockingFilter> BlockingFilterPtr;
|
||||||
{
|
|
||||||
public:
|
|
||||||
BufferedFilter (ComparatorType comparator, size_t buffer_size,
|
|
||||||
boost::shared_ptr<SerialListener> listener)
|
|
||||||
: listener(listener), buffer_size(buffer_size)
|
|
||||||
{
|
|
||||||
DataCallback cb = boost::bind(&BlockingFilter::callback, this, _1);
|
|
||||||
this->filter_ptr = listener.createFilter(comparator, cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~BufferedFilter () {
|
class BufferedFilter;
|
||||||
this->listener.removeFilter(filter_ptr);
|
|
||||||
this->queue.clear();
|
|
||||||
this->result = "";
|
|
||||||
this->cond.notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Waits a given number of milliseconds or until a matched token is
|
* Shared Pointer of BufferedFilter, returned by
|
||||||
* available in the buffer. If a token is matched it is returned, otherwise
|
* SerialListener::createBufferedFilter.
|
||||||
* an empty string is returned.
|
*
|
||||||
*
|
* \see serial::BufferedFilter, SerialListener::createBufferedFilter
|
||||||
* \param ms Time in milliseconds to wait on a new token. If ms is set to 0
|
*/
|
||||||
* then it will try to get a new token if one is available but will not
|
typedef boost::shared_ptr<BufferedFilter> BufferedFilterPtr;
|
||||||
* block.
|
|
||||||
*
|
|
||||||
* \return std::string token that was matched or "" if none were matched.
|
|
||||||
*/
|
|
||||||
std::string wait(size_t ms) {
|
|
||||||
if (ms == 0)
|
|
||||||
if (!this->queue.try_pop(this->result))
|
|
||||||
this->result = "";
|
|
||||||
else
|
|
||||||
if (!this->queue.timed_wait_and_pop(this->result, ms))
|
|
||||||
this->result = "";
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Clears the buffer of any tokens.
|
|
||||||
*/
|
|
||||||
void clear() {
|
|
||||||
queue.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Returns the number of tokens waiting in the buffer.
|
|
||||||
*/
|
|
||||||
size_t count() {
|
|
||||||
return queue.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Returns the capacity of the buffer.
|
|
||||||
*/
|
|
||||||
size_t capacity() {
|
|
||||||
return buffer_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void callback(const std::string &token) {
|
|
||||||
std::string throw_away;
|
|
||||||
if (this->queue.size() == buffer_size)
|
|
||||||
this->queue.wait_and_pop(throw_away);
|
|
||||||
this->queue.push(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
FilterPtr filter_ptr;
|
|
||||||
size_t buffer_size;
|
|
||||||
boost::shared_ptr<SerialListener> listener;
|
|
||||||
ConcurrentQueue<std::string> queue;
|
|
||||||
std::string result;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This is a general exception generated by the SerialListener class.
|
* This is a general exception generated by the SerialListener class.
|
||||||
*
|
*
|
||||||
* Check the SerialListenerException::what function for the cause.
|
* Check the SerialListenerException::what function for the cause.
|
||||||
|
*
|
||||||
* \param e_what is a std::string that describes the cause of the error.
|
* \param e_what is a std::string that describes the cause of the error.
|
||||||
*/
|
*/
|
||||||
class SerialListenerException : public std::exception {
|
class SerialListenerException : public std::exception {
|
||||||
@ -489,98 +360,115 @@ public:
|
|||||||
/***** Filter Functions ******/
|
/***** Filter Functions ******/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Setups up a filter that calls a callback when a comparator returns true.
|
* Creates a filter that calls a callback when the comparator returns true.
|
||||||
*
|
*
|
||||||
* The user provides a comparator and a callback, and every time a line is
|
* The user provides a comparator and a callback, and every time a line is
|
||||||
* received the comparator is called and the comparator has to evaluate the
|
* received the comparator is called and the comparator has to evaluate the
|
||||||
* line and return true if it matches and false if it doesn't. If it does
|
* line and return true if it matches and false if it doesn't. If it does
|
||||||
* match, the callback is called with the resulting line.
|
* match, the callback is called with the resulting line.
|
||||||
*
|
*
|
||||||
* \param comparator This is a comparator for detecting if a line matches.
|
* \param comparator This is a comparator for detecting if a line matches.
|
||||||
* The comparartor receives a std::string reference and must return a true
|
* The comparartor receives a std::string reference and must return a true
|
||||||
* if it matches and false if it doesn't.
|
* if it matches and false if it doesn't.
|
||||||
*
|
*
|
||||||
* \param callback This is the handler for when a match occurs. It is given
|
* \param callback This is the handler for when a match occurs. It is given
|
||||||
* a std::string reference of the line that matched your comparator.
|
* a std::string reference of the line that matched your comparator.
|
||||||
*
|
*
|
||||||
* \return boost::shared_ptr<Filter> so you can remove it later.
|
* \return boost::shared_ptr<Filter> so you can remove it later.
|
||||||
*
|
*
|
||||||
* \see SerialListener::stopListeningFor
|
* \see SerialListener::removeFilter
|
||||||
*/
|
*/
|
||||||
FilterPtr
|
FilterPtr
|
||||||
listenFor (ComparatorType comparator, DataCallback callback);
|
createFilter (ComparatorType comparator, DataCallback callback);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Blocks until the comparator returns true or until the timeout occurs.
|
* Creates a BlockingFilter which blocks until the comparator returns true.
|
||||||
*
|
*
|
||||||
* \param comparator ComparatorType function that should return true if the
|
* The user provides a comparator, and every time a line is
|
||||||
* given std::string matches otherwise false.
|
* received the comparator is called and the comparator has to evaluate the
|
||||||
|
* line and return true if it matches and false if it doesn't. If it does
|
||||||
|
* match, any threads that have called BlockingFilter::wait will be
|
||||||
|
* notified. The BlockingFilter will remove itself when its destructor is
|
||||||
|
* called, i.e. when it leaves the scope, so in those cases an explicit call
|
||||||
|
* to SerialListener::removeFilter is not needed.
|
||||||
*
|
*
|
||||||
* \param timeout in milliseconds before timing out and returning false.
|
* \param comparator This is a comparator for detecting if a line matches.
|
||||||
* Defaults to 1000 milliseconds or 1 second.
|
* The comparartor receives a std::string reference and must return a true
|
||||||
|
* if it matches and false if it doesn't.
|
||||||
*
|
*
|
||||||
* \return std::string the token that was matched, returns an empty string
|
* \return BlockingFilterPtr So you can call BlockingFilter::wait on it.
|
||||||
* if the timeout occurs first.
|
*
|
||||||
* i.e. if (listenForOnce(...) != "") // Got match
|
* \see SerialListener::removeFilter, serial::BlockingFilter,
|
||||||
|
* serial::BlockingFilterPtr
|
||||||
*/
|
*/
|
||||||
std::string
|
BlockingFilterPtr
|
||||||
listenForOnce (ComparatorType comparator, size_t timeout = 1000);
|
createBlockingFilter (ComparatorType comparator);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Writes to the seiral port then blocks until the comparator returns true
|
* Creates a BlockingFilter blocks until the comparator returns true.
|
||||||
* or until the timeout occurs.
|
|
||||||
*
|
*
|
||||||
* This function creates a filter, writes the data, then waits for it to
|
* The user provides a comparator, and every time a line is
|
||||||
* match atleast once.
|
* received the comparator is called and the comparator has to evaluate the
|
||||||
|
* line and return true if it matches and false if it doesn't. If it does
|
||||||
|
* match, any threads that have called BlockingFilter::wait will be
|
||||||
|
* notified. The BlockingFilter will remove itself when its destructor is
|
||||||
|
* called, i.e. when it leaves the scope, so in those cases an explicit call
|
||||||
|
* to SerialListener::removeFilter is not needed.
|
||||||
*
|
*
|
||||||
* \param to_be_written const std::string reference of data to be written to
|
* \param comparator This is a comparator for detecting if a line matches.
|
||||||
* the serial port.
|
* The comparartor receives a std::string reference and must return a true
|
||||||
|
* if it matches and false if it doesn't.
|
||||||
*
|
*
|
||||||
* \param comparator ComparatorType function that should return true if the
|
* \param buffer_size This is the number of tokens to be buffered by the
|
||||||
* given std::string matches otherwise false.
|
* BufferedFilter, defaults to 1024.
|
||||||
*
|
*
|
||||||
* \param timeout in milliseconds before timing out and returning false.
|
* \return BlockingFilter So you can call BlockingFilter::wait on it.
|
||||||
* Defaults to 1000 milliseconds or 1 second.
|
|
||||||
*
|
*
|
||||||
* \return std::string the token that was matched, returns an empty string
|
* \see SerialListener::removeFilter, serial::BufferedFilter,
|
||||||
* if the timeout occurs first.
|
* serial::BufferedFilterPtr
|
||||||
* i.e. if (listenForOnce(...) != "") // Got match
|
|
||||||
*/
|
*/
|
||||||
std::string
|
BufferedFilterPtr
|
||||||
listenForOnce (ComparatorType comparator, size_t timeout = 1000);
|
createBufferedFilter (ComparatorType comparator, size_t buffer_size = 1024);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Blocks until the given string is detected or until the timeout occurs.
|
* Removes a filter by a given FilterPtr.
|
||||||
*
|
*
|
||||||
* \param token std::string that should be watched for, this string must
|
* \param filter_ptr A shared pointer to the filter to be removed.
|
||||||
* match the message exactly.
|
|
||||||
*
|
*
|
||||||
* \param timeout in milliseconds before timing out and returning false.
|
* \see SerialListener::createFilter
|
||||||
* Defaults to 1000 milliseconds or 1 second.
|
|
||||||
*
|
|
||||||
* \return bool If true then the token was detected before the token, false
|
|
||||||
* if the token was not heard and the timeout occured.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
listenForStringOnce (std::string token, size_t timeout = 1000);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Removes a filter by a given uuid.
|
|
||||||
*
|
|
||||||
* The uuid for a filter is returned by the listenFor function.
|
|
||||||
*
|
|
||||||
* \param filter_ptr A shared pointer to the filter.
|
|
||||||
*
|
|
||||||
* \see SerialListener::listenFor
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
stopListeningFor (FilterPtr filter_ptr);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Stops listening for anything, but doesn't stop reading the serial port.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
stopListeningForAll ();
|
removeFilter (FilterPtr filter_ptr);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Removes a BlockingFilter.
|
||||||
|
*
|
||||||
|
* The BlockingFilter will remove itself if the destructor is called.
|
||||||
|
*
|
||||||
|
* \param blocking_filter A BlockingFilter to be removed.
|
||||||
|
*
|
||||||
|
* \see SerialListener::createBlockingFilter
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
removeFilter (BlockingFilterPtr blocking_filter);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Removes a BufferedFilter.
|
||||||
|
*
|
||||||
|
* The BufferedFilter will remove itself if the destructor is called.
|
||||||
|
*
|
||||||
|
* \param buffered_filter A BufferedFilter to be removed.
|
||||||
|
*
|
||||||
|
* \see SerialListener::createBufferedFilter
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
removeFilter (BufferedFilterPtr buffered_filter);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Removes all filters.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
removeAllFilters ();
|
||||||
|
|
||||||
/***** Hooks and Handlers ******/
|
/***** Hooks and Handlers ******/
|
||||||
|
|
||||||
@ -912,6 +800,156 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
/*!
|
||||||
|
* This is the a filter that provides a wait function for blocking until a
|
||||||
|
* match is found.
|
||||||
|
*
|
||||||
|
* This should probably not be created manually, but instead should be
|
||||||
|
* constructed using SerialListener::createBlockingFilter(ComparatorType)
|
||||||
|
* function which returns a BlockingFilter instance.
|
||||||
|
*
|
||||||
|
* \see serial::SerialListener::ComparatorType,
|
||||||
|
* serial::SerialListener::createBlockingFilter
|
||||||
|
*/
|
||||||
|
class BlockingFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BlockingFilter (ComparatorType comparator,
|
||||||
|
boost::shared_ptr<SerialListener> listener)
|
||||||
|
: listener(listener)
|
||||||
|
{
|
||||||
|
DataCallback cb = boost::bind(&BlockingFilter::callback, this, _1);
|
||||||
|
this->filter_ptr = listener->createFilter(comparator, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~BlockingFilter () {
|
||||||
|
this->listener->removeFilter(filter_ptr);
|
||||||
|
this->result = "";
|
||||||
|
this->cond.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Waits a given number of milliseconds or until a token is matched. If a
|
||||||
|
* token is matched it is returned, otherwise an empty string is returned.
|
||||||
|
*
|
||||||
|
* \param ms Time in milliseconds to wait on a new token.
|
||||||
|
*
|
||||||
|
* \return std::string token that was matched or "" if none were matched.
|
||||||
|
*/
|
||||||
|
std::string wait(size_t ms) {
|
||||||
|
this->result = "";
|
||||||
|
boost::unique_lock<boost::mutex> lock(this->mutex);
|
||||||
|
this->cond.timed_wait(lock, boost::posix_time::milliseconds(ms));
|
||||||
|
return this->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterPtr filter_ptr;
|
||||||
|
|
||||||
|
void callback(const std::string& token) {
|
||||||
|
this->cond.notify_all();
|
||||||
|
this->result = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::shared_ptr<SerialListener> listener;
|
||||||
|
boost::condition_variable cond;
|
||||||
|
boost::mutex mutex;
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* This is the a filter that provides a wait function for blocking until a
|
||||||
|
* match is found. It will also buffer up to a given buffer size of tokens so
|
||||||
|
* that they can be counted or accessed after they are matched by the filter.
|
||||||
|
*
|
||||||
|
* This should probably not be created manually, but instead should be
|
||||||
|
* constructed using SerialListener::createBufferedFilter(ComparatorType)
|
||||||
|
* function which returns a BufferedFilter instance.
|
||||||
|
*
|
||||||
|
* The internal buffer is a circular queue buffer, so when the buffer is full,
|
||||||
|
* the oldest token is dropped and the new one is added. Additionally, when
|
||||||
|
* wait is a called the oldest available token is returned.
|
||||||
|
*
|
||||||
|
* \see serial::SerialListener::ComparatorType,
|
||||||
|
* serial::SerialListener::createBufferedFilter
|
||||||
|
*/
|
||||||
|
class BufferedFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BufferedFilter (ComparatorType comparator, size_t buffer_size,
|
||||||
|
boost::shared_ptr<SerialListener> listener)
|
||||||
|
: listener(listener), buffer_size(buffer_size)
|
||||||
|
{
|
||||||
|
DataCallback cb = boost::bind(&BufferedFilter::callback, this, _1);
|
||||||
|
this->filter_ptr = listener->createFilter(comparator, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~BufferedFilter () {
|
||||||
|
this->listener->removeFilter(filter_ptr);
|
||||||
|
this->queue.clear();
|
||||||
|
this->result = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Waits a given number of milliseconds or until a matched token is
|
||||||
|
* available in the buffer. If a token is matched it is returned, otherwise
|
||||||
|
* an empty string is returned.
|
||||||
|
*
|
||||||
|
* \param ms Time in milliseconds to wait on a new token. If ms is set to 0
|
||||||
|
* then it will try to get a new token if one is available but will not
|
||||||
|
* block.
|
||||||
|
*
|
||||||
|
* \return std::string token that was matched or "" if none were matched.
|
||||||
|
*/
|
||||||
|
std::string wait(size_t ms) {
|
||||||
|
if (ms == 0)
|
||||||
|
if (!this->queue.try_pop(this->result))
|
||||||
|
this->result = "";
|
||||||
|
else
|
||||||
|
if (!this->queue.timed_wait_and_pop(this->result, ms))
|
||||||
|
this->result = "";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Clears the buffer of any tokens.
|
||||||
|
*/
|
||||||
|
void clear() {
|
||||||
|
queue.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns the number of tokens waiting in the buffer.
|
||||||
|
*/
|
||||||
|
size_t count() {
|
||||||
|
return queue.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns the capacity of the buffer.
|
||||||
|
*/
|
||||||
|
size_t capacity() {
|
||||||
|
return buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterPtr filter_ptr;
|
||||||
|
|
||||||
|
void callback(const std::string &token) {
|
||||||
|
std::string throw_away;
|
||||||
|
if (this->queue.size() == buffer_size)
|
||||||
|
this->queue.wait_and_pop(throw_away);
|
||||||
|
this->queue.push(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t buffer_size;
|
||||||
|
boost::shared_ptr<SerialListener> listener;
|
||||||
|
ConcurrentQueue<std::string> queue;
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace serial
|
||||||
|
|
||||||
#endif // SERIAL_LISTENER_H
|
#endif // SERIAL_LISTENER_H
|
||||||
@ -111,7 +111,7 @@ SerialListener::stopListening() {
|
|||||||
this->serial_port = NULL;
|
this->serial_port = NULL;
|
||||||
|
|
||||||
// Delete all the filters
|
// Delete all the filters
|
||||||
this->stopListeningForAll();
|
this->removeAllFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
@ -186,7 +186,8 @@ SerialListener::listen() {
|
|||||||
/***** Filter Functions *****/
|
/***** Filter Functions *****/
|
||||||
|
|
||||||
FilterPtr
|
FilterPtr
|
||||||
SerialListener::listenFor(ComparatorType comparator, DataCallback callback) {
|
SerialListener::createFilter(ComparatorType comparator, DataCallback callback)
|
||||||
|
{
|
||||||
FilterPtr filter_ptr(new Filter(comparator, callback));
|
FilterPtr filter_ptr(new Filter(comparator, callback));
|
||||||
|
|
||||||
boost::mutex::scoped_lock l(filter_mux);
|
boost::mutex::scoped_lock l(filter_mux);
|
||||||
@ -195,50 +196,40 @@ SerialListener::listenFor(ComparatorType comparator, DataCallback callback) {
|
|||||||
return filter_ptr;
|
return filter_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef boost::shared_ptr<boost::condition_variable> shared_cond_var_ptr_t;
|
BlockingFilterPtr
|
||||||
|
SerialListener::createBlockingFilter(ComparatorType comparator) {
|
||||||
|
return BlockingFilterPtr(
|
||||||
|
new BlockingFilter(comparator, boost::shared_ptr<SerialListener>(this)));
|
||||||
|
}
|
||||||
|
|
||||||
inline void
|
BufferedFilterPtr
|
||||||
listenForOnceCallback(const std::string &token,
|
SerialListener::createBufferedFilter(ComparatorType comparator,
|
||||||
shared_cond_var_ptr_t cond,
|
size_t buffer_size)
|
||||||
boost::shared_ptr<std::string> result)
|
|
||||||
{
|
{
|
||||||
(*result) = token;
|
return BufferedFilterPtr(
|
||||||
cond->notify_all();
|
new BufferedFilter(comparator,
|
||||||
}
|
buffer_size,
|
||||||
|
boost::shared_ptr<SerialListener>(this)));
|
||||||
std::string
|
|
||||||
SerialListener::listenForOnce(ComparatorType comparator, size_t ms) {
|
|
||||||
boost::shared_ptr<std::string> result(new std::string(""));
|
|
||||||
|
|
||||||
shared_cond_var_ptr_t cond(new boost::condition_variable());
|
|
||||||
boost::mutex mutex;
|
|
||||||
|
|
||||||
DataCallback callback = boost::bind(listenForOnceCallback,_1,cond,result);
|
|
||||||
FilterPtr filter_id = this->listenFor(comparator, callback);
|
|
||||||
|
|
||||||
boost::unique_lock<boost::mutex> lock(mutex);
|
|
||||||
cond->timed_wait(lock, boost::posix_time::milliseconds(ms)));
|
|
||||||
|
|
||||||
this->stopListeningFor(filter_id);
|
|
||||||
|
|
||||||
// If the callback never got called then result will be "" because tokens
|
|
||||||
// can never be ""
|
|
||||||
return (*result);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
SerialListener::listenForStringOnce(std::string token, size_t milliseconds) {
|
|
||||||
return this->listenForOnce(exactly(token), milliseconds) == token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SerialListener::stopListeningFor(FilterPtr filter_ptr) {
|
SerialListener::removeFilter(FilterPtr filter_ptr) {
|
||||||
boost::mutex::scoped_lock l(filter_mux);
|
boost::mutex::scoped_lock l(filter_mux);
|
||||||
filters.erase(std::find(filters.begin(),filters.end(),filter_ptr));
|
filters.erase(std::find(filters.begin(),filters.end(),filter_ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SerialListener::stopListeningForAll() {
|
SerialListener::removeFilter(BlockingFilterPtr blocking_filter) {
|
||||||
|
this->removeFilter(blocking_filter->filter_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SerialListener::removeFilter(BufferedFilterPtr buffered_filter) {
|
||||||
|
this->removeFilter(buffered_filter->filter_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SerialListener::removeAllFilters() {
|
||||||
boost::mutex::scoped_lock l(filter_mux);
|
boost::mutex::scoped_lock l(filter_mux);
|
||||||
filters.clear();
|
filters.clear();
|
||||||
callback_queue.clear();
|
callback_queue.clear();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user