X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FTimer.cc;fp=src%2FMoof%2FTimer.cc;h=4eea488ad7f43d29af7280f63ea3371f2380f4b2;hp=0000000000000000000000000000000000000000;hb=c2321281bf12a7efaedde930422c7ddbc92080d4;hpb=87bc17e55b0c1dc73ecc66df856d3f08fd7a7724 diff --git a/src/Moof/Timer.cc b/src/Moof/Timer.cc new file mode 100644 index 0000000..4eea488 --- /dev/null +++ b/src/Moof/Timer.cc @@ -0,0 +1,119 @@ + +/******************************************************************************* + + Copyright (c) 2009, Charles McGarvey + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include +#include +#include + +#include "Timer.hh" + +#if HAVE_CONFIG_H +#include "config.h" +#endif + + +namespace Mf { + + +#if HAVE_CLOCK_GETTIME + +// Since the monotonic clock will provide us with the timer since the computer +// started, the number of seconds since that time could easily become so large +// that it cannot be accurately stored in a float (even with as little two days +// uptime), therefore we need to start from a more recent reference (when the +// program starts). Of course this isn't much of an issue if scalar is a +// double-precision number. + +static time_t setReference_() +{ + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) + { + return 0; + } + + return ts.tv_sec; +} + +static const time_t reference = setReference_(); + + +Scalar getTicks() +{ + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) + { + throw std::runtime_error("cannot access monotonic clock"); + } + + return Scalar(ts.tv_sec - reference) + Scalar(ts.tv_nsec) / 1000000000.0; +} + + +#else // ! HAVE_CLOCK_GETTIME + + +// If we don't have posix timers, we'll have to use a different timing method. +// SDL only promises centisecond accuracy, but that's better than a kick in the +// butt. + +#include + +Scalar getTicks() +{ + Uint32 ms = SDL_GetTicks(); + return Scalar(ms / 1000) + Scalar(ms % 1000) / 1000.0; +} + + +#endif // HAVE_CLOCK_GETTIME + + +void sleep(Scalar seconds, bool absolute) +{ + struct timespec ts; + int ret; + + if (absolute) seconds -= getTicks(); + ts.tv_sec = time_t(seconds); + ts.tv_nsec = long((seconds - Scalar(ts.tv_sec)) * 1000000000.0); + + do + { + ret = nanosleep(&ts, &ts); + } + while (ret == -1 && errno == EINTR); +} + + +} // namespace Mf + +/** vim: set ts=4 sw=4 tw=80: *************************************************/ +