diff options
| author | Andre Weissflog <floooh@gmail.com> | 2017-11-28 18:49:20 +0100 |
|---|---|---|
| committer | Andre Weissflog <floooh@gmail.com> | 2017-11-28 18:49:20 +0100 |
| commit | 282109e100ee9778c9b120c6754aee87c4e778c9 (patch) | |
| tree | b418108274af887710494407a6732290670b0683 /sokol_time.h | |
| parent | 9146bcaa43c91c99c7c77c0b2739f4c48a1c29bf (diff) | |
new header: sokol_time.h
Diffstat (limited to 'sokol_time.h')
| -rw-r--r-- | sokol_time.h | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/sokol_time.h b/sokol_time.h new file mode 100644 index 00000000..dda47f0e --- /dev/null +++ b/sokol_time.h @@ -0,0 +1,191 @@ +#pragma once +/* + sokol_time.h -- simple cross-platform time measurement + + Do this: + #define SOKOL_IMPL + before you include this file in *one* C or C++ file to create the + implementation. + + Optionally provide the following defines with your own implementations: + SOKOL_ASSERT(c) - your own assert macro (default: assert(c)) + + void stm_setup(); + Call once before any other functions to initialize sokol_time + (this calls for instance QueryPerformanceFrequency on Windows) + + uint64_t stm_now(); + Get current point in time in unspecified ticks. The value that + is returned has no relation to some absolute time or time unit, + it is only useful to compute time differences. + + uint64_t stm_diff(uint64_t new, uint64_t old); + Computes the time difference between new and old. This will always + return a positive, non-zero value. + + uint64_t stm_since(uint64_t start); + Takes the current time, and returns the elapsed time since start + (this is a shortcut for "stm_diff(stm_now(), start)") + + uint64_t stm_laptime(uint64_t* last_time); + Takes the current time, returns the time since last_time, + and stores current time in last_time. If last_time is 0, the + return value will be 0! + + double stm_sec(uint64_t ticks); + double stm_ms(uint64_t ticks); + double stm_us(uint64_t ticks); + double stm_ns(uint64_t ticks); + Convert a tick value into seconds, milliseconds, microseconds + or nanoseconds. Note that not all platforms will have nanosecond + or even microsecond precision. + + Use the following time measurement functions: + + Windows: QueryPerformanceFrequency() / QueryPerformanceCounter() + MacOS/iOS: mach_absolute_time() + emscripten: clock_gettime(CLOCK_MONOTONIC) + Linux+others: clock_gettime(CLOCK_MONITONIC) + + + MIT License + + Copyright (c) 2017 Andre Weissflog + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern void stm_setup(); +extern uint64_t stm_now(); +extern uint64_t stm_diff(uint64_t new_ticks, uint64_t old_ticks); +extern uint64_t stm_since(uint64_t start_ticks); +extern uint64_t stm_laptime(uint64_t* last_time); +extern double stm_sec(uint64_t ticks); +extern double stm_ms(uint64_t ticks); +extern double stm_us(uint64_t ticks); +extern double stm_ns(uint64_t ticks); + +/*-- IMPLEMENTATION ----------------------------------------------------------*/ +#ifdef SOKOL_IMPL +#ifndef SOKOL_ASSERT + #include <assert.h> + #define SOKOL_ASSERT(c) assert(c) +#endif + +static int _stm_initialized; +#if defined(_WIN32) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +LARGE_INTEGER _stm_win_freq; +LARGE_INTEGER _stm_win_start; +#elif defined(__APPLE__) && defined(__MACH__) +#include <mach/mach_time.h> +mach_timebase_info_data_t _stm_osx_timebase; +uint64_t _stm_osx_start; +#else /* anything else, this will need more care for non-Linux platforms */ +#include <time.h> +uint64_t _stm_posix_start; +#endif + +void stm_setup() { + SOKOL_ASSERT(0 == _stm_initialized); + _stm_initialized = 1; + #if defined(_WIN32) + QueryPerformanceFrequency(&_stm_win_freq); + QueryPerformanceCounter(&_stm_win_start); + #elif defined(__APPLE__) && defined(__MACH__) + mach_timebase_info(&_stm_osx_timebase); + _stm_osx_start = mach_absolute_time(); + #else + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + _stm_posix_start = (uint64_t)ts.tv_sec*1000000000 + (uint64_t)ts.tv_nsec; + #endif +} + +uint64_t stm_now() { + SOKOL_ASSERT(_stm_initialized); + uint64_t now; + #if defined(_WIN32) + LARGE_INTEGER qpc_t; + QueryPerformanceCounter(&qpc_t); + now = ((qpc_t.QuadPart - _stm_win_start.QuadPart) * 1000000000) / _stm_win_freq.QuadPart; + return + #elif defined(__APPLE__) && defined(__MACH__) + now = mach_absolute_time() - _stm_osx_start; + #else + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + now = ((uint64_t)ts.tv_sec*1000000000 + (uint64_t)ts.tv_nsec) - _stm_posix_start; + #endif + return now; +} + +uint64_t stm_diff(uint64_t new_ticks, uint64_t old_ticks) { + if (new_ticks > old_ticks) { + return new_ticks - old_ticks; + } + else { + /* FIXME: this should be a value that converts to a non-null double */ + return 1; + } +} + +uint64_t stm_since(uint64_t start_ticks) { + return stm_diff(stm_now(), start_ticks); +} + +uint64_t stm_laptime(uint64_t* last_time) { + SOKOL_ASSERT(last_time); + uint64_t dt = 0; + uint64_t now = stm_now(); + if (0 != *last_time) { + dt = stm_diff(now, *last_time); + } + *last_time = now; + return dt; +} + +double stm_sec(uint64_t ticks) { + return (double)ticks / 1000000000.0; +} + +double stm_ms(uint64_t ticks) { + return (double)ticks / 1000000.0; +} + +double stm_us(uint64_t ticks) { + return (double)ticks / 1000.0; +} + +double stm_ns(uint64_t ticks) { + return (double)ticks; +} +#endif /* SOKOL_IMPL */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif |