diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 39d6854..eaa49fe 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -61,9 +61,9 @@ AppFrame::AppFrame() : audioInputQueue = new AudioThreadInputQueue; audioThread = new AudioThread(audioInputQueue); - t1 = new std::thread(&AudioThread::threadMain, audioThread); + threadAudio = new std::thread(&AudioThread::threadMain, audioThread); - demodulatorTest = demodMgr.newThread(this); + demodulatorTest = demodMgr.newThread(); demodulatorTest->params.audioInputQueue = audioInputQueue; demodulatorTest->init(); @@ -77,7 +77,7 @@ AppFrame::AppFrame() : iqVisualQueue = new SDRThreadIQDataQueue; sdrThread->setIQVisualQueue(iqVisualQueue); - t_SDR = new std::thread(&SDRThread::threadMain, sdrThread); + threadSDR = new std::thread(&SDRThread::threadMain, sdrThread); // static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 }; // wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not"); diff --git a/src/AppFrame.h b/src/AppFrame.h index 66d988e..3fc8c75 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -16,10 +16,9 @@ class AppFrame: public wxFrame { public: AppFrame(); ~AppFrame(); - void OnThread (wxCommandEvent& event); + void OnThread(wxCommandEvent& event); void OnEventInput(wxThreadEvent& event); - void setFrequency(unsigned int freq); int getFrequency(); @@ -47,8 +46,8 @@ private: SDRThreadIQDataQueue* iqVisualQueue; DemodulatorThreadOutputQueue* audioVisualQueue; - std::thread *t1; - std::thread *t_SDR; + std::thread *threadAudio; + std::thread *threadSDR; // event table wxDECLARE_EVENT_TABLE(); diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index ea579ef..3d1ea42 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -44,6 +44,20 @@ static int audioCallback(const void *inputBuffer, void *outputBuffer, unsigned l return paContinue; } +AudioThread::AudioThread(AudioThreadInputQueue *inputQueue) : + inputQueue(inputQueue), stream(NULL), audio_queue_ptr(0) { + +} + +AudioThread::~AudioThread() { + PaError err; + err = Pa_StopStream(stream); + err = Pa_CloseStream(stream); + Pa_Terminate(); + + std::cout << std::endl << "Audio Thread Done." << std::endl << std::endl; +} + void AudioThread::threadMain() { PaError err; err = Pa_Initialize(); @@ -67,7 +81,7 @@ void AudioThread::threadMain() { stream = NULL; err = Pa_OpenStream(&stream, NULL, &outputParameters, AUDIO_FREQUENCY, paFramesPerBufferUnspecified, - paPrimeOutputBuffersUsingStreamCallback | paClipOff, &audioCallback, this); + paPrimeOutputBuffersUsingStreamCallback | paClipOff, &audioCallback, this); err = Pa_StartStream(stream); if (err != paNoError) { diff --git a/src/audio/AudioThread.h b/src/audio/AudioThread.h index 4e41cea..44823aa 100644 --- a/src/audio/AudioThread.h +++ b/src/audio/AudioThread.h @@ -33,19 +33,9 @@ public: std::queue > audio_queue; unsigned int audio_queue_ptr; - AudioThread(AudioThreadInputQueue *inputQueue) : - inputQueue(inputQueue), stream(NULL), audio_queue_ptr(0) { + AudioThread(AudioThreadInputQueue *inputQueue); - } - - ~AudioThread() { - PaError err; - err = Pa_StopStream(stream); - err = Pa_CloseStream(stream); - Pa_Terminate(); - - std::cout << std::endl << "Audio Thread Done." << std::endl << std::endl; - } + ~AudioThread(); void threadMain(); diff --git a/src/demod/DemodulatorMgr.cpp b/src/demod/DemodulatorMgr.cpp index e69de29..9dd94c4 100644 --- a/src/demod/DemodulatorMgr.cpp +++ b/src/demod/DemodulatorMgr.cpp @@ -0,0 +1,40 @@ +#include + +DemodulatorInstance::DemodulatorInstance() : + t_Demod(NULL), threadQueueDemod(NULL), demodulatorThread(NULL) { +} +void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) { + demodulatorThread->setVisualOutputQueue(tQueue); +} + +void DemodulatorInstance::init() { + if (threadQueueDemod) { + delete threadQueueDemod; + } + if (demodulatorThread) { + delete demodulatorThread; + } + + threadQueueDemod = new DemodulatorThreadInputQueue; + demodulatorThread = new DemodulatorThread(threadQueueDemod, ¶ms); + + t_Demod = new std::thread(&DemodulatorThread::threadMain, demodulatorThread); +} + +DemodulatorMgr::DemodulatorMgr() { + +} + +DemodulatorMgr::~DemodulatorMgr() { + while (demods.size()) { + DemodulatorInstance *d = demods.back(); + demods.pop_back(); + delete d; + } +} + +DemodulatorInstance *DemodulatorMgr::newThread() { + DemodulatorInstance *newDemod = new DemodulatorInstance; + demods.push_back(newDemod); + return newDemod; +} diff --git a/src/demod/DemodulatorMgr.h b/src/demod/DemodulatorMgr.h index 02b25a8..39b02a8 100644 --- a/src/demod/DemodulatorMgr.h +++ b/src/demod/DemodulatorMgr.h @@ -13,48 +13,18 @@ public: DemodulatorThreadInputQueue* threadQueueDemod; DemodulatorThreadParameters params; - DemodulatorInstance() : - t_Demod(NULL), threadQueueDemod(NULL), demodulatorThread(NULL) { - } - void setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) { - demodulatorThread->setVisualOutputQueue(tQueue); - } - - void init() { - if (threadQueueDemod) { - delete threadQueueDemod; - } - if (demodulatorThread) { - delete demodulatorThread; - } - - threadQueueDemod = new DemodulatorThreadInputQueue; - demodulatorThread = new DemodulatorThread(threadQueueDemod, ¶ms); - - t_Demod = new std::thread(&DemodulatorThread::threadMain, demodulatorThread); - } - + DemodulatorInstance(); + void setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue); + void init(); }; class DemodulatorMgr { public: - DemodulatorMgr() { + DemodulatorMgr(); + ~DemodulatorMgr(); - } - - ~DemodulatorMgr() { - while (demods.size()) { - DemodulatorInstance *d = demods.back(); - demods.pop_back(); - delete d; - } - } - - DemodulatorInstance *newThread(wxEvtHandler* pParent) { - DemodulatorInstance *newDemod = new DemodulatorInstance; - demods.push_back(newDemod); - return newDemod; - } + DemodulatorInstance *newThread(); +private: std::vector demods; }; diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index daa8990..26451b2 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -3,7 +3,7 @@ #include DemodulatorThread::DemodulatorThread(DemodulatorThreadInputQueue* pQueue, DemodulatorThreadParameters *params_in) : - m_pQueue(pQueue), visOutQueue(NULL) { + inputQueue(pQueue), visOutQueue(NULL) { DemodulatorThreadParameters defaultParams; if (!params_in) { @@ -57,7 +57,7 @@ void DemodulatorThread::threadMain() { while (1) { DemodulatorThreadIQData inp; - m_pQueue->pop(inp); + inputQueue->pop(inp); std::vector *data = &inp.data; if (data->size()) { @@ -139,22 +139,6 @@ void DemodulatorThread::threadMain() { if (visOutQueue != NULL) { visOutQueue->push(ati); } - - /*if (!TestDestroy()) { - DemodulatorThreadAudioData *audioOut = new DemodulatorThreadAudioData(task.data->frequency, params.audioSampleRate, newBuffer); - - m_pQueue->sendAudioData(DemodulatorThreadTask::DEMOD_THREAD_AUDIO_DATA, audioOut); - - if (params.audioInputQueue != NULL) { - AudioThreadInput ati; - ati.data = newBuffer; - params.audioInputQueue->push(ati); - // AudioThreadTask audio_task = AudioThreadTask(AudioThreadTask::AUDIO_THREAD_DATA); - // audio_task.data = new AudioThreadData(task.data->frequency, params.audioSampleRate, newBuffer); - // params.audioQueue->addTask(audio_task, AudioThreadQueue::AUDIO_PRIORITY_HIGHEST); - } - }*/ - } } } diff --git a/src/demod/DemodulatorThread.h b/src/demod/DemodulatorThread.h index b156309..32591e5 100644 --- a/src/demod/DemodulatorThread.h +++ b/src/demod/DemodulatorThread.h @@ -102,7 +102,7 @@ public: } protected: - DemodulatorThreadInputQueue* m_pQueue; + DemodulatorThreadInputQueue* inputQueue; DemodulatorThreadOutputQueue* visOutQueue; firfilt_crcf fir_filter; diff --git a/src/util/ThreadQueue.h b/src/util/ThreadQueue.h index 043e409..69b18d3 100644 --- a/src/util/ThreadQueue.h +++ b/src/util/ThreadQueue.h @@ -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 #include #include - - + /** A thread-safe asynchronous queue */ -template > -class ThreadQueue -{ - +template> +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 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 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 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 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 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 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 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 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 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 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 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 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 lock1 (m_mutex); - std::lock_guard 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 lock1 (m_mutex); - std::lock_guard lock2 (sq.m_mutex); - std::queue 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 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 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 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 -void swap (ThreadQueue& q1, ThreadQueue& q2) -{ - q1.swap (q2); +template +void swap(ThreadQueue& q1, ThreadQueue& q2) { + q1.swap(q2); } diff --git a/src/util/Timer.h b/src/util/Timer.h index 4037c94..58589d6 100644 --- a/src/util/Timer.h +++ b/src/util/Timer.h @@ -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