Cleanup / Reformat

This commit is contained in:
Charles J. Cliffe
2014-11-22 22:33:32 -05:00
parent 58708a720e
commit 39ba38b82a
10 changed files with 353 additions and 395 deletions
+153 -177
View File
@@ -1,5 +1,5 @@
#pragma once
/* Credit to Alfredo Pons / https://plus.google.com/109903449837592676231
* Code from http://gnodebian.blogspot.com.es/2013/07/a-thread-safe-asynchronous-queue-in-c11.html
*
@@ -14,171 +14,157 @@
#include <thread>
#include <cstdint>
#include <condition_variable>
/** A thread-safe asynchronous queue */
template <class T, class Container = std::list<T>>
class ThreadQueue
{
template<class T, class Container = std::list<T>>
class ThreadQueue {
typedef typename Container::value_type value_type;
typedef typename Container::size_type size_type;
typedef Container container_type;
public:
public:
/*! Create safe queue. */
ThreadQueue() = default;
ThreadQueue (ThreadQueue&& sq)
{
m_queue = std::move (sq.m_queue);
ThreadQueue(ThreadQueue&& sq) {
m_queue = std::move(sq.m_queue);
}
ThreadQueue (const ThreadQueue& sq)
{
std::lock_guard<std::mutex> lock (sq.m_mutex);
m_queue = sq.m_queue;
ThreadQueue(const ThreadQueue& sq) {
std::lock_guard < std::mutex > lock(sq.m_mutex);
m_queue = sq.m_queue;
}
/*! Destroy safe queue. */
~ThreadQueue()
{
std::lock_guard<std::mutex> lock (m_mutex);
~ThreadQueue() {
std::lock_guard < std::mutex > lock(m_mutex);
}
/**
* Sets the maximum number of items in the queue. Defaults is 0: No limit
* \param[in] item An item.
*/
void set_max_num_items (unsigned int max_num_items)
{
m_max_num_items = max_num_items;
void set_max_num_items(unsigned int max_num_items) {
m_max_num_items = max_num_items;
}
/**
* Pushes the item into the queue.
* \param[in] item An item.
* \return true if an item was pushed into the queue
*/
bool push (const value_type& item)
{
std::lock_guard<std::mutex> lock (m_mutex);
if (m_max_num_items > 0 && m_queue.size() > m_max_num_items)
return false;
m_queue.push (item);
m_condition.notify_one();
return true;
bool push(const value_type& item) {
std::lock_guard < std::mutex > lock(m_mutex);
if (m_max_num_items > 0 && m_queue.size() > m_max_num_items)
return false;
m_queue.push(item);
m_condition.notify_one();
return true;
}
/**
* Pushes the item into the queue.
* \param[in] item An item.
* \return true if an item was pushed into the queue
*/
bool push (const value_type&& item)
{
std::lock_guard<std::mutex> lock (m_mutex);
if (m_max_num_items > 0 && m_queue.size() > m_max_num_items)
return false;
m_queue.push (item);
m_condition.notify_one();
return true;
bool push(const value_type&& item) {
std::lock_guard < std::mutex > lock(m_mutex);
if (m_max_num_items > 0 && m_queue.size() > m_max_num_items)
return false;
m_queue.push(item);
m_condition.notify_one();
return true;
}
/**
* Pops item from the queue. If queue is empty, this function blocks until item becomes available.
* \param[out] item The item.
*/
void pop (value_type& item)
{
std::unique_lock<std::mutex> lock (m_mutex);
m_condition.wait (lock, [this]() // Lambda funct
{
return !m_queue.empty();
});
item = m_queue.front();
m_queue.pop();
void pop(value_type& item) {
std::unique_lock < std::mutex > lock(m_mutex);
m_condition.wait(lock, [this]() // Lambda funct
{
return !m_queue.empty();
});
item = m_queue.front();
m_queue.pop();
}
/**
* Pops item from the queue using the contained type's move assignment operator, if it has one..
* This method is identical to the pop() method if that type has no move assignment operator.
* If queue is empty, this function blocks until item becomes available.
* \param[out] item The item.
*/
void move_pop (value_type& item)
{
std::unique_lock<std::mutex> lock (m_mutex);
m_condition.wait (lock, [this]() // Lambda funct
{
return !m_queue.empty();
});
item = std::move (m_queue.front());
m_queue.pop();
void move_pop(value_type& item) {
std::unique_lock < std::mutex > lock(m_mutex);
m_condition.wait(lock, [this]() // Lambda funct
{
return !m_queue.empty();
});
item = std::move(m_queue.front());
m_queue.pop();
}
/**
* Tries to pop item from the queue.
* \param[out] item The item.
* \return False is returned if no item is available.
*/
bool try_pop (value_type& item)
{
std::unique_lock<std::mutex> lock (m_mutex);
if (m_queue.empty())
return false;
item = m_queue.front();
m_queue.pop();
return true;
bool try_pop(value_type& item) {
std::unique_lock < std::mutex > lock(m_mutex);
if (m_queue.empty())
return false;
item = m_queue.front();
m_queue.pop();
return true;
}
/**
* Tries to pop item from the queue using the contained type's move assignment operator, if it has one..
* This method is identical to the try_pop() method if that type has no move assignment operator.
* \param[out] item The item.
* \return False is returned if no item is available.
*/
bool try_move_pop (value_type& item)
{
std::unique_lock<std::mutex> lock (m_mutex);
if (m_queue.empty())
return false;
item = std::move (m_queue.front());
m_queue.pop();
return true;
bool try_move_pop(value_type& item) {
std::unique_lock < std::mutex > lock(m_mutex);
if (m_queue.empty())
return false;
item = std::move(m_queue.front());
m_queue.pop();
return true;
}
/**
* Pops item from the queue. If the queue is empty, blocks for timeout microseconds, or until item becomes available.
* \param[out] t An item.
* \param[in] timeout The number of microseconds to wait.
* \return true if get an item from the queue, false if no item is received before the timeout.
*/
bool timeout_pop (value_type& item, std::uint64_t timeout)
{
std::unique_lock<std::mutex> lock (m_mutex);
if (m_queue.empty())
{
if (timeout == 0)
return false;
if (m_condition.wait_for (lock, std::chrono::microseconds (timeout)) == std::cv_status::timeout)
return false;
bool timeout_pop(value_type& item, std::uint64_t timeout) {
std::unique_lock < std::mutex > lock(m_mutex);
if (m_queue.empty()) {
if (timeout == 0)
return false;
if (m_condition.wait_for(lock, std::chrono::microseconds(timeout)) == std::cv_status::timeout)
return false;
}
item = m_queue.front();
m_queue.pop();
return true;
item = m_queue.front();
m_queue.pop();
return true;
}
/**
* Pops item from the queue using the contained type's move assignment operator, if it has one..
* If the queue is empty, blocks for timeout microseconds, or until item becomes available.
@@ -187,104 +173,94 @@ class ThreadQueue
* \param[in] timeout The number of microseconds to wait.
* \return true if get an item from the queue, false if no item is received before the timeout.
*/
bool timeout_move_pop (value_type& item, std::uint64_t timeout)
{
std::unique_lock<std::mutex> lock (m_mutex);
if (m_queue.empty())
{
if (timeout == 0)
return false;
if (m_condition.wait_for (lock, std::chrono::microseconds (timeout)) == std::cv_status::timeout)
return false;
bool timeout_move_pop(value_type& item, std::uint64_t timeout) {
std::unique_lock < std::mutex > lock(m_mutex);
if (m_queue.empty()) {
if (timeout == 0)
return false;
if (m_condition.wait_for(lock, std::chrono::microseconds(timeout)) == std::cv_status::timeout)
return false;
}
item = std::move (m_queue.front());
m_queue.pop();
return true;
item = std::move(m_queue.front());
m_queue.pop();
return true;
}
/**
* Gets the number of items in the queue.
* \return Number of items in the queue.
*/
size_type size() const
{
std::lock_guard<std::mutex> lock (m_mutex);
return m_queue.size();
size_type size() const {
std::lock_guard < std::mutex > lock(m_mutex);
return m_queue.size();
}
/**
* Check if the queue is empty.
* \return true if queue is empty.
*/
bool empty() const
{
std::lock_guard<std::mutex> lock (m_mutex);
return m_queue.empty();
bool empty() const {
std::lock_guard < std::mutex > lock(m_mutex);
return m_queue.empty();
}
/**
* Swaps the contents.
* \param[out] sq The ThreadQueue to swap with 'this'.
*/
void swap (ThreadQueue& sq)
{
if (this != &sq)
{
std::lock_guard<std::mutex> lock1 (m_mutex);
std::lock_guard<std::mutex> lock2 (sq.m_mutex);
m_queue.swap (sq.m_queue);
if (!m_queue.empty())
m_condition.notify_all();
if (!sq.m_queue.empty())
sq.m_condition.notify_all();
void swap(ThreadQueue& sq) {
if (this != &sq) {
std::lock_guard < std::mutex > lock1(m_mutex);
std::lock_guard < std::mutex > lock2(sq.m_mutex);
m_queue.swap(sq.m_queue);
if (!m_queue.empty())
m_condition.notify_all();
if (!sq.m_queue.empty())
sq.m_condition.notify_all();
}
}
/*! The copy assignment operator */
ThreadQueue& operator= (const ThreadQueue& sq)
{
if (this != &sq)
{
std::lock_guard<std::mutex> lock1 (m_mutex);
std::lock_guard<std::mutex> lock2 (sq.m_mutex);
std::queue<T, Container> temp {sq.m_queue};
m_queue.swap (temp);
if (!m_queue.empty())
m_condition.notify_all();
ThreadQueue& operator=(const ThreadQueue& sq) {
if (this != &sq) {
std::lock_guard < std::mutex > lock1(m_mutex);
std::lock_guard < std::mutex > lock2(sq.m_mutex);
std::queue<T, Container> temp { sq.m_queue };
m_queue.swap(temp);
if (!m_queue.empty())
m_condition.notify_all();
}
return *this;
return *this;
}
/*! The move assignment operator */
ThreadQueue& operator= (ThreadQueue && sq)
{
std::lock_guard<std::mutex> lock (m_mutex);
m_queue = std::move (sq.m_queue);
if (!m_queue.empty()) m_condition.notify_all();
return *this;
ThreadQueue& operator=(ThreadQueue && sq) {
std::lock_guard < std::mutex > lock(m_mutex);
m_queue = std::move(sq.m_queue);
if (!m_queue.empty())
m_condition.notify_all();
return *this;
}
private:
private:
std::queue<T, Container> m_queue;
mutable std::mutex m_mutex;
std::condition_variable m_condition;
unsigned int m_max_num_items = 0;
};
/*! Swaps the contents of two ThreadQueue objects. */
template <class T, class Container>
void swap (ThreadQueue<T, Container>& q1, ThreadQueue<T, Container>& q2)
{
q1.swap (q2);
template<class T, class Container>
void swap(ThreadQueue<T, Container>& q1, ThreadQueue<T, Container>& q2) {
q1.swap(q2);
}
+127 -142
View File
@@ -1,4 +1,3 @@
#ifndef TIMER_H
#define TIMER_H
@@ -12,165 +11,151 @@
/**
* Class provides high resolution timing and useful time control functions
*/
class Timer
{
class Timer {
private:
unsigned long time_elapsed;
unsigned long system_milliseconds;
unsigned long start_time;
unsigned long end_time;
unsigned long last_update;
unsigned long num_updates;
unsigned long paused_time;
unsigned long offset;
unsigned long time_elapsed;
unsigned long system_milliseconds;
unsigned long start_time;
unsigned long end_time;
unsigned long last_update;
unsigned long num_updates;
unsigned long paused_time;
unsigned long offset;
#ifndef WIN32
struct timeval time_val;
struct timezone time_zone;
struct timeval time_val;
struct timezone time_zone;
#endif
bool paused_state;
bool lock_state;
float lock_rate;
bool paused_state;
bool lock_state;
float lock_rate;
public:
/// Constructor
Timer();
/// Constructor
Timer();
/// Start the timer
/**
* Resets the timer to 0 and begins timing
*/
void start(void);
/// Stop the timer
/**
* Stops the timer and records the end time
*/
void stop(void);
/// Locks the timer to a specified framerate (for recording / benchmarking purposes typically)
/**
* Locks the timer to a specified framerate (for recording / benchmarking purposes typically)
*/
void lockFramerate(float f_rate);
/// Start the timer
/**
* Resets the timer to 0 and begins timing
*/
void start(void);
/// Unlock any framerate lock that's been applied
/**
* Unlock any framerate lock that's been applied
*/
void unlock();
/// Stop the timer
/**
* Stops the timer and records the end time
*/
void stop(void);
/// Check locked state
/**
* Check locked state
*/
bool locked();
/// Reset the timer counter
/**
* Resetting the timer will reset the current time to 0
*/
void reset(void);
/// Locks the timer to a specified framerate (for recording / benchmarking purposes typically)
/**
* Locks the timer to a specified framerate (for recording / benchmarking purposes typically)
*/
void lockFramerate(float f_rate);
/// Timer update
/**
* Calling the update command will bring the timer value up to date, this is meant
* to be called at the begining of the frame to establish the time index which is being drawn.
*/
void update(void);
/// Unlock any framerate lock that's been applied
/**
* Unlock any framerate lock that's been applied
*/
void unlock();
/// Get the total time elapsed since the timer start, not counting paused time
/**
* Returns the total time elapsed in since the timer start() to the last update() but
* does not count the time elapsed while the timer is paused().
* \return Total time elapsed since the timer start() to the last update() excluding time paused() in milliseconds
*/
unsigned long getMilliseconds(void);
/// Alias of getMilliseconds() which returns time in seconds
/**
* \return Total time elapsed since the timer start() to the last update() excluding time paused() in seconds
*/
double getSeconds(void);
/// Check locked state
/**
* Check locked state
*/
bool locked();
/// Get the total time elapsed since the timer start
/**
* Returns the total time elapsed in since the timer start() to the last update()
* this includes any time accumulated during updates while paused()
* \return Total time elapsed since the timer start() to the last update() including time paused() in milliseconds
*/
unsigned long totalMilliseconds(void);
/// Alias of totalMilliseconds() which returns time in seconds
/**
* \return Total time elapsed since the timer start() to the last update() including time paused() in seconds
*/
double totalSeconds(void);
/// Reset the timer counter
/**
* Resetting the timer will reset the current time to 0
*/
void reset(void);
/// Set the amount of time elapsed
/**
* Force the timer duration to a specific value, useful for rolling forward or back in a system
* based upon the timer.
* \param milliseconds_in Time to set timer to in milliseconds
*/
void setMilliseconds(unsigned long milliseconds_in);
/// alias of setMilliseconds() which accepts time in seconds
/**
* \param seconds_in Time to set timer to in seconds
*/
void setSeconds(double seconds_in);
/// Timer update
/**
* Calling the update command will bring the timer value up to date, this is meant
* to be called at the begining of the frame to establish the time index which is being drawn.
*/
void update(void);
/// Get the amount of times the update() command has been called
/**
* By using the number of times the update() command has been called you can easily determine
* an average frame rate. Also useful for merely determining how many frames have been drawn.
* \return Number of times update() has been called
*/
unsigned long getNumUpdates(void);
/// Get the timer duration during the last update
/**
* Useful for determining the amount of time which elapsed during the last update
* can be used to accurately control values with a per-second rate or determine the current frame rate.
* \return Duration of time between the last two calls to update() in milliseconds
*/
unsigned long lastUpdateMilliseconds(void);
/// Alias of lastUpdateMilliseconds() which returns time in seconds
/**
* \return Duration of time between the last two calls to update() in seconds
*/
double lastUpdateSeconds(void);
/// Get the total time elapsed since the timer start, not counting paused time
/**
* Returns the total time elapsed in since the timer start() to the last update() but
* does not count the time elapsed while the timer is paused().
* \return Total time elapsed since the timer start() to the last update() excluding time paused() in milliseconds
*/
unsigned long getMilliseconds(void);
/// Alias of getMilliseconds() which returns time in seconds
/**
* \return Total time elapsed since the timer start() to the last update() excluding time paused() in seconds
*/
double getSeconds(void);
/// Set the timer pause state
/**
* Pause the timer, allowing for continued update() calls without an increment in timing but
* maintaining the update and total time count, useful for pausing a scene but allowing frame
* timing to resume.
* \param pause_in Value to set the current pause state to
*/
void paused(bool pause_in);
/// Check if the timer is currently in a paused state
/**
* \return Current pause state, true if paused, false otherwise
*/
bool paused();
/// Get the total time elapsed since the timer start
/**
* Returns the total time elapsed in since the timer start() to the last update()
* this includes any time accumulated during updates while paused()
* \return Total time elapsed since the timer start() to the last update() including time paused() in milliseconds
*/
unsigned long totalMilliseconds(void);
/// Alias of totalMilliseconds() which returns time in seconds
/**
* \return Total time elapsed since the timer start() to the last update() including time paused() in seconds
*/
double totalSeconds(void);
/// Set the amount of time elapsed
/**
* Force the timer duration to a specific value, useful for rolling forward or back in a system
* based upon the timer.
* \param milliseconds_in Time to set timer to in milliseconds
*/
void setMilliseconds(unsigned long milliseconds_in);
/// alias of setMilliseconds() which accepts time in seconds
/**
* \param seconds_in Time to set timer to in seconds
*/
void setSeconds(double seconds_in);
/// Get the amount of times the update() command has been called
/**
* By using the number of times the update() command has been called you can easily determine
* an average frame rate. Also useful for merely determining how many frames have been drawn.
* \return Number of times update() has been called
*/
unsigned long getNumUpdates(void);
/// Get the timer duration during the last update
/**
* Useful for determining the amount of time which elapsed during the last update
* can be used to accurately control values with a per-second rate or determine the current frame rate.
* \return Duration of time between the last two calls to update() in milliseconds
*/
unsigned long lastUpdateMilliseconds(void);
/// Alias of lastUpdateMilliseconds() which returns time in seconds
/**
* \return Duration of time between the last two calls to update() in seconds
*/
double lastUpdateSeconds(void);
/// Set the timer pause state
/**
* Pause the timer, allowing for continued update() calls without an increment in timing but
* maintaining the update and total time count, useful for pausing a scene but allowing frame
* timing to resume.
* \param pause_in Value to set the current pause state to
*/
void paused(bool pause_in);
/// Check if the timer is currently in a paused state
/**
* \return Current pause state, true if paused, false otherwise
*/
bool paused();
};
#endif