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
* purpose with or without fee is hereby granted, provided that the above
@ -19,7 +19,7 @@
#include "Timer.h"
#include "DLList.h"
Jupiter::DLList<Jupiter::Timer> timers;
Jupiter::DLList<Jupiter::Timer> o_timers;
/** Deallocates timers when the library is unloaded. */
struct TimerKiller
@ -29,59 +29,47 @@ struct TimerKiller
TimerKiller::~TimerKiller()
{
Jupiter_killTimers();
Jupiter::Timer::killAll();
}
struct Jupiter::Timer::Data
{
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::Timer(unsigned int in_iterations, std::chrono::milliseconds in_delay, FunctionType in_function, void *in_parameters, bool in_immediate)
{
Jupiter::Timer::data_ = new Jupiter::Timer::Data();
Jupiter::Timer::data_->function = nullptr;
Jupiter::Timer::data_->functionNoParams = function;
Jupiter::Timer::data_->parameters = nullptr;
Jupiter::Timer::data_->iterations = iterations;
Jupiter::Timer::data_->delay = timeDelay;
Jupiter::Timer::data_->nextCall = immediate ? time(0) : time(0) + timeDelay;
timers.add(this);
m_function = in_function;
m_parameters = in_parameters;
m_iterations = in_iterations;
m_delay = in_delay;
m_next_call = std::chrono::steady_clock::now();
if (in_immediate == false)
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()
{
if (Jupiter::Timer::data_->nextCall <= time(0))
if (m_next_call <= std::chrono::steady_clock::now())
{
int killMe = 0;
if (Jupiter::Timer::data_->iterations != 0 && --Jupiter::Timer::data_->iterations == 0) killMe = 1;
if (Jupiter::Timer::data_->function != nullptr) Jupiter::Timer::data_->function(Jupiter::Timer::data_->iterations, Jupiter::Timer::data_->parameters);
else Jupiter::Timer::data_->functionNoParams(Jupiter::Timer::data_->iterations);
if (m_iterations != 0 && --m_iterations == 0)
killMe = 1;
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;
}
@ -91,69 +79,65 @@ int Jupiter::Timer::think()
bool Jupiter::Timer::removeFromList()
{
if (timers.size() == 0) return false;
for (Jupiter::DLList<Jupiter::Timer>::Node *n = timers.getNode(0); n != nullptr; n = n->next)
for (Jupiter::DLList<Jupiter::Timer>::Node *node = o_timers.getHead(); node != nullptr; node = node->next)
{
if (n->data == this)
if (node->data == this)
{
timers.remove(n);
o_timers.remove(node);
return true;
}
}
return false;
}
bool Jupiter::Timer::kill()
{
if (Jupiter::Timer::removeFromList())
if (this->removeFromList())
{
delete this;
return true;
}
delete this;
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);
}
extern "C" unsigned int Jupiter_totalTimers()
{
return timers.size();
}
size_t result = 0;
Jupiter::Timer *timer;
Jupiter::DLList<Jupiter::Timer>::Node *dead_node;
Jupiter::DLList<Jupiter::Timer>::Node *node = o_timers.getHead();
extern "C" unsigned int Jupiter_checkTimers()
while (node != nullptr)
{
unsigned int r = 0;
Jupiter::Timer *t;
Jupiter::DLList<Jupiter::Timer>::Node *o;
Jupiter::DLList<Jupiter::Timer>::Node *n = timers.size() == 0 ? nullptr : timers.getNode(0);
while (n != nullptr)
timer = node->data;
if (timer->think() != 0)
{
t = n->data;
if (t->think() != 0)
{
o = n;
n = n->next;
delete timers.remove(o);
r++;
dead_node = node;
node = node->next;
delete o_timers.remove(dead_node);
++result;
}
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();
while (timers.size() != 0)
delete timers.remove(size_t{ 0 });
return r;
size_t result = o_timers.size();
while (o_timers.size() != 0)
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
* purpose with or without fee is hereby granted, provided that the above
@ -21,25 +21,29 @@
/**
* @file Timer.h
* @brief Provides an timed event system.
* @brief Provides a timed event system.
*/
#include <chrono>
#include "Jupiter.h"
#if defined __cplusplus
#include <ctime>
#include "Thinker.h"
/** DLL Linkage Nagging */
#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4251)
#endif
namespace Jupiter
{
/**
* @brief Provides an interface for adding timed events.
*/
class JUPITER_API Timer : public Thinker
{
public:
typedef void(*FunctionType)(unsigned int, void *);
/**
* @brief Checks if the timed function should be called, and calls it if neccessary.
* Note: This is primarily used internally by checkTimers().
@ -63,6 +67,27 @@ namespace Jupiter
*/
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.
* 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 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.
@ -80,7 +105,7 @@ namespace Jupiter
* @param function Function for the timer to call.
* @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.
@ -91,7 +116,7 @@ namespace Jupiter
* @param parameters Parameters to pass to the function.
* @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.
@ -101,7 +126,7 @@ namespace Jupiter
* @param function Function for the timer to call.
* @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.
@ -112,7 +137,7 @@ namespace Jupiter
* @param parameters Parameters to pass to the function.
* @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.
@ -122,71 +147,22 @@ namespace Jupiter
* @param function Function for the timer to call.
* @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);
/**
* @brief Destructor for the Timer class.
*/
~Timer();
Timer(unsigned int in_iterations, std::chrono::milliseconds in_delay, FunctionType in_function, bool in_immediate = false);
/** Private data members */
private:
struct Data;
Data *data_;
/** Private data members */
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"
{
#else
#include <stdbool.h>
#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
/** Re-enable warnings */
#if defined _MSC_VER
#pragma warning(pop)
#endif // _MSC_VER
#endif // _TIMER_H_HEADER
Loading…
Cancel
Save