Browse Source

Cleaned up timers a bit, though I'm still not happy with them

release/0.19
Jessica James 8 years ago
parent
commit
25cd40fbe9
  1. 136
      Jupiter/Timer.cpp
  2. 122
      Jupiter/Timer.h

136
Jupiter/Timer.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2015 Jessica James. * Copyright (C) 2014-2016 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -19,7 +19,7 @@
#include "Timer.h" #include "Timer.h"
#include "DLList.h" #include "DLList.h"
Jupiter::DLList<Jupiter::Timer> timers; Jupiter::DLList<Jupiter::Timer> o_timers;
/** Deallocates timers when the library is unloaded. */ /** Deallocates timers when the library is unloaded. */
struct TimerKiller struct TimerKiller
@ -29,59 +29,47 @@ struct TimerKiller
TimerKiller::~TimerKiller() TimerKiller::~TimerKiller()
{ {
Jupiter_killTimers(); Jupiter::Timer::killAll();
} }
struct Jupiter::Timer::Data Jupiter::Timer::Timer(unsigned int in_iterations, std::chrono::milliseconds in_delay, FunctionType in_function, void *in_parameters, bool in_immediate)
{
void (*function)(unsigned int, void *);
void (*functionNoParams)(unsigned int);
void *parameters;
time_t nextCall;
time_t delay;
int iterations;
};
Jupiter::Timer::Timer(unsigned int iterations, time_t timeDelay, void(*function)(unsigned int, void *), void *parameters, bool immediate)
{
Jupiter::Timer::data_ = new Jupiter::Timer::Data();
Jupiter::Timer::data_->function = function;
Jupiter::Timer::data_->functionNoParams = nullptr;
Jupiter::Timer::data_->parameters = parameters;
Jupiter::Timer::data_->iterations = iterations;
Jupiter::Timer::data_->delay = timeDelay;
Jupiter::Timer::data_->nextCall = immediate ? time(0) : time(0) + timeDelay;
timers.add(this);
}
Jupiter::Timer::Timer(unsigned int iterations, time_t timeDelay, void(*function)(unsigned int), bool immediate)
{ {
Jupiter::Timer::data_ = new Jupiter::Timer::Data(); m_function = in_function;
Jupiter::Timer::data_->function = nullptr; m_parameters = in_parameters;
Jupiter::Timer::data_->functionNoParams = function; m_iterations = in_iterations;
Jupiter::Timer::data_->parameters = nullptr; m_delay = in_delay;
Jupiter::Timer::data_->iterations = iterations; m_next_call = std::chrono::steady_clock::now();
Jupiter::Timer::data_->delay = timeDelay;
Jupiter::Timer::data_->nextCall = immediate ? time(0) : time(0) + timeDelay; if (in_immediate == false)
timers.add(this); m_next_call += m_delay;
o_timers.add(this);
} }
Jupiter::Timer::~Timer() Jupiter::Timer::Timer(unsigned int in_iterations, std::chrono::milliseconds in_delay, FunctionType in_function, bool in_immediate)
{ {
delete Jupiter::Timer::data_; m_function = in_function;
m_parameters = nullptr;
m_iterations = in_iterations;
m_delay = in_delay;
if (in_immediate == false)
m_next_call += m_delay;
o_timers.add(this);
} }
int Jupiter::Timer::think() int Jupiter::Timer::think()
{ {
if (Jupiter::Timer::data_->nextCall <= time(0)) if (m_next_call <= std::chrono::steady_clock::now())
{ {
int killMe = 0; int killMe = 0;
if (Jupiter::Timer::data_->iterations != 0 && --Jupiter::Timer::data_->iterations == 0) killMe = 1; if (m_iterations != 0 && --m_iterations == 0)
if (Jupiter::Timer::data_->function != nullptr) Jupiter::Timer::data_->function(Jupiter::Timer::data_->iterations, Jupiter::Timer::data_->parameters); killMe = 1;
else Jupiter::Timer::data_->functionNoParams(Jupiter::Timer::data_->iterations);
Jupiter::Timer::data_->nextCall = Jupiter::Timer::data_->delay + time(0); m_function(m_iterations, m_parameters);
m_next_call = m_delay + std::chrono::steady_clock::now();
return killMe; return killMe;
} }
@ -91,69 +79,65 @@ int Jupiter::Timer::think()
bool Jupiter::Timer::removeFromList() bool Jupiter::Timer::removeFromList()
{ {
if (timers.size() == 0) return false; for (Jupiter::DLList<Jupiter::Timer>::Node *node = o_timers.getHead(); node != nullptr; node = node->next)
for (Jupiter::DLList<Jupiter::Timer>::Node *n = timers.getNode(0); n != nullptr; n = n->next)
{ {
if (n->data == this) if (node->data == this)
{ {
timers.remove(n); o_timers.remove(node);
return true; return true;
} }
} }
return false; return false;
} }
bool Jupiter::Timer::kill() bool Jupiter::Timer::kill()
{ {
if (Jupiter::Timer::removeFromList()) if (this->removeFromList())
{ {
delete this; delete this;
return true; return true;
} }
delete this; delete this;
return false; return false;
} }
extern "C" void Jupiter_addTimer(unsigned int iterations, time_t timeDelay, bool immediate, void(*function)(unsigned int, void *), void *parameters) size_t Jupiter::Timer::total()
{ {
new Jupiter::Timer(iterations, timeDelay, function, parameters, immediate); return o_timers.size();
} }
extern "C" void Jupiter_addTimerNoParams(unsigned int iterations, time_t timeDelay, bool immediate, void(*function)(unsigned int)) size_t Jupiter::Timer::check()
{ {
new Jupiter::Timer(iterations, timeDelay, function, immediate); size_t result = 0;
} Jupiter::Timer *timer;
Jupiter::DLList<Jupiter::Timer>::Node *dead_node;
extern "C" unsigned int Jupiter_totalTimers() Jupiter::DLList<Jupiter::Timer>::Node *node = o_timers.getHead();
{
return timers.size();
}
extern "C" unsigned int Jupiter_checkTimers() while (node != nullptr)
{ {
unsigned int r = 0; timer = node->data;
Jupiter::Timer *t; if (timer->think() != 0)
Jupiter::DLList<Jupiter::Timer>::Node *o;
Jupiter::DLList<Jupiter::Timer>::Node *n = timers.size() == 0 ? nullptr : timers.getNode(0);
while (n != nullptr)
{ {
t = n->data; dead_node = node;
if (t->think() != 0) node = node->next;
{ delete o_timers.remove(dead_node);
o = n; ++result;
n = n->next;
delete timers.remove(o);
r++;
} }
else n = n->next; else
node = node->next;
} }
return r;
return result;
} }
extern "C" unsigned int Jupiter_killTimers() size_t Jupiter::Timer::killAll()
{ {
unsigned int r = timers.size(); size_t result = o_timers.size();
while (timers.size() != 0)
delete timers.remove(size_t{ 0 }); while (o_timers.size() != 0)
return r; delete o_timers.remove(size_t{ 0 });
return result;
} }

122
Jupiter/Timer.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2015 Jessica James. * Copyright (C) 2014-2016 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -21,25 +21,29 @@
/** /**
* @file Timer.h * @file Timer.h
* @brief Provides an timed event system. * @brief Provides a timed event system.
*/ */
#include <chrono>
#include "Jupiter.h" #include "Jupiter.h"
#if defined __cplusplus
#include <ctime>
#include "Thinker.h" #include "Thinker.h"
/** DLL Linkage Nagging */
#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4251)
#endif
namespace Jupiter namespace Jupiter
{ {
/** /**
* @brief Provides an interface for adding timed events. * @brief Provides an interface for adding timed events.
*/ */
class JUPITER_API Timer : public Thinker class JUPITER_API Timer : public Thinker
{ {
public: public:
typedef void(*FunctionType)(unsigned int, void *);
/** /**
* @brief Checks if the timed function should be called, and calls it if neccessary. * @brief Checks if the timed function should be called, and calls it if neccessary.
* Note: This is primarily used internally by checkTimers(). * Note: This is primarily used internally by checkTimers().
@ -63,6 +67,27 @@ namespace Jupiter
*/ */
bool kill(); bool kill();
/**
* @brief Fetches the number of active timers.
*
* @return Total number of timers active.
*/
static size_t total();
/**
* @brief Calls think() for every timer, and removes them if neccessary.
*
* @return Total number of timers removed.
*/
static size_t check();
/**
* @brief Immediately destroys all timers.
*
* @return Total number of timers removed.
*/
static size_t killAll();
/** /**
* @brief Constructs a timer and adds itself to the timer list. * @brief Constructs a timer and adds itself to the timer list.
* Note: This assumes infinite iterations, with as little time delay as possible. * Note: This assumes infinite iterations, with as little time delay as possible.
@ -71,7 +96,7 @@ namespace Jupiter
* @param parameters Parameters to pass to the function. * @param parameters Parameters to pass to the function.
* @param immediate (optional) True if the function should be execute on the next check. * @param immediate (optional) True if the function should be execute on the next check.
*/ */
Timer(void(*function)(unsigned int, void *), void *parameters, bool immediate = false) : Timer(unsigned int(0), time_t(0), function, parameters, immediate) {} Timer(FunctionType in_function, void *in_parameters, bool in_immediate = false) : Timer(0U, std::chrono::milliseconds(0), in_function, in_parameters, in_immediate) {}
/** /**
* @brief Constructs a timer and adds itself to the timer list. * @brief Constructs a timer and adds itself to the timer list.
@ -80,7 +105,7 @@ namespace Jupiter
* @param function Function for the timer to call. * @param function Function for the timer to call.
* @param immediate (optional) True if the function should be execute on the next check. * @param immediate (optional) True if the function should be execute on the next check.
*/ */
Timer(void(*function)(unsigned int), bool immediate = false) : Timer(unsigned int(0), time_t(0), function, immediate) {} Timer(FunctionType in_function, bool in_immediate = false) : Timer(0U, std::chrono::milliseconds(0), in_function, in_immediate) {}
/** /**
* @brief Constructs a timer and adds itself to the timer list. * @brief Constructs a timer and adds itself to the timer list.
@ -91,7 +116,7 @@ namespace Jupiter
* @param parameters Parameters to pass to the function. * @param parameters Parameters to pass to the function.
* @param immediate (optional) True if the function should be execute on the next check. * @param immediate (optional) True if the function should be execute on the next check.
*/ */
Timer(time_t timeDelay, void(*function)(unsigned int, void *), void *parameters, bool immediate = false) : Timer(unsigned int(0), timeDelay, function, parameters, immediate) {} Timer(std::chrono::milliseconds in_delay, FunctionType in_function, void *in_parameters, bool in_immediate = false) : Timer(0U, in_delay, in_function, in_parameters, in_immediate) {}
/** /**
* @brief Constructs a timer and adds itself to the timer list. * @brief Constructs a timer and adds itself to the timer list.
@ -101,7 +126,7 @@ namespace Jupiter
* @param function Function for the timer to call. * @param function Function for the timer to call.
* @param immediate (optional) True if the function should be execute on the next check. * @param immediate (optional) True if the function should be execute on the next check.
*/ */
Timer(time_t timeDelay, void(*function)(unsigned int), bool immediate = false) : Timer(unsigned int(0), timeDelay, function, immediate) {} Timer(std::chrono::milliseconds in_delay, FunctionType in_function, bool in_immediate = false) : Timer(0U, in_delay, in_function, in_immediate) {}
/** /**
* @brief Constructs a timer and adds itself to the timer list. * @brief Constructs a timer and adds itself to the timer list.
@ -112,7 +137,7 @@ namespace Jupiter
* @param parameters Parameters to pass to the function. * @param parameters Parameters to pass to the function.
* @param immediate (optional) True if the function should be execute on the next check. * @param immediate (optional) True if the function should be execute on the next check.
*/ */
Timer(unsigned int iterations, time_t timeDelay, void(*function)(unsigned int, void *), void *parameters, bool immediate = false); Timer(unsigned int in_iterations, std::chrono::milliseconds in_delay, FunctionType in_function, void *in_parameters, bool in_immediate = false);
/** /**
* @brief Constructs a timer and adds itself to the timer list. * @brief Constructs a timer and adds itself to the timer list.
@ -122,71 +147,22 @@ namespace Jupiter
* @param function Function for the timer to call. * @param function Function for the timer to call.
* @param immediate (optional) True if the function should be execute on the next check. * @param immediate (optional) True if the function should be execute on the next check.
*/ */
Timer(unsigned int iterations, time_t timeDelay, void(*function)(unsigned int), bool immediate = false); Timer(unsigned int in_iterations, std::chrono::milliseconds in_delay, FunctionType in_function, bool in_immediate = false);
/**
* @brief Destructor for the Timer class.
*/
~Timer();
/** Private data members */
private: private:
struct Data; /** Private data members */
Data *data_; std::chrono::steady_clock::time_point m_next_call;
std::chrono::milliseconds m_delay;
unsigned int m_iterations;
FunctionType m_function;
void *m_parameters;
}; };
} }
extern "C" /** Re-enable warnings */
{ #if defined _MSC_VER
#else #pragma warning(pop)
#include <stdbool.h> #endif // _MSC_VER
#include <time.h>
#endif // _cplusplus
/**
* @brief Creates a timer.
*
* @param iterations Number of iterations for the timer to execute. 0 if the timer is indefinite.
* @param timeDelay Delay in seconds between executions of the timed function.
* @param immediate True if the function should be execute on the next check.
* @param function Function for the timer to call.
* @param parameters Parameters to pass to the function.
*/
JUPITER_API void Jupiter_addTimer(unsigned int iterations, time_t timeDelay, bool immediate, void(*function)(unsigned int, void *), void *parameters);
/**
* @brief Creates a timer.
*
* @param iterations Number of iterations for the timer to execute. 0 if the timer is indefinite.
* @param timeDelay Delay in seconds between executions of the timed function.
* @param immediate True if the function should be execute on the next check.
* @param function Function for the timer to call.
*/
JUPITER_API void Jupiter_addTimerNoParams(unsigned int iterations, time_t timeDelay, bool immediate, void(*function)(unsigned int));
/**
* @brief Fetches the number of active timers.
*
* @return Total number of timers active.
*/
JUPITER_API unsigned int Jupiter_totalTimers();
/**
* @brief Calls think() for every timer, and removes them if neccessary.
*
* @return Total number of timers removed.
*/
JUPITER_API unsigned int Jupiter_checkTimers();
/**
* @brief Immediately destroys all timers.
*
* @return Total number of timers removed.
*/
JUPITER_API unsigned int Jupiter_killTimers();
#if defined __cplusplus
}
#endif // __cplusplus
#endif // _TIMER_H_HEADER #endif // _TIMER_H_HEADER
Loading…
Cancel
Save