mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
Corrected negative timers
This commit is contained in:
@@ -5,21 +5,43 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
//GOD DAMN IT: https://stackoverflow.com/questions/15846762/timeval-subtract-explanation
|
||||||
|
int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) {
|
||||||
|
//normallize
|
||||||
|
if (x->tv_usec > 999999) {
|
||||||
|
x->tv_sec += x->tv_usec / 1000000;
|
||||||
|
x->tv_usec %= 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y->tv_usec > 999999) {
|
||||||
|
y->tv_sec += y->tv_usec / 1000000;
|
||||||
|
y->tv_usec %= 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
//calc
|
||||||
|
result->tv_sec = x->tv_sec - y->tv_sec;
|
||||||
|
|
||||||
|
if ((result->tv_usec = x->tv_usec - y->tv_usec) < 0) {
|
||||||
|
if (result->tv_sec != 0) { //only works far from 0
|
||||||
|
result->tv_usec += 1000000;
|
||||||
|
result->tv_sec--; // borrow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result->tv_sec < 0 || (result->tv_sec == 0 && result->tv_usec < 0);
|
||||||
|
}
|
||||||
|
|
||||||
//god damn it
|
//god damn it
|
||||||
static struct timeval* diff(struct timeval* lhs, struct timeval* rhs) {
|
static struct timeval* diff(struct timeval* lhs, struct timeval* rhs) {
|
||||||
struct timeval* d = ALLOCATE(struct timeval, 1);
|
struct timeval* d = ALLOCATE(struct timeval, 1);
|
||||||
|
|
||||||
d->tv_sec = rhs->tv_sec - lhs->tv_sec;
|
//I gave up, copied from SO
|
||||||
d->tv_usec = rhs->tv_usec - lhs->tv_usec;
|
timeval_subtract(d, rhs, lhs);
|
||||||
|
|
||||||
if (d->tv_usec < 0) {
|
|
||||||
d->tv_sec--;
|
|
||||||
d->tv_usec += 1000 * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//callbacks
|
||||||
static int nativeStartTimer(Interpreter* interpreter, LiteralArray* arguments) {
|
static int nativeStartTimer(Interpreter* interpreter, LiteralArray* arguments) {
|
||||||
//no arguments
|
//no arguments
|
||||||
if (arguments->count != 0) {
|
if (arguments->count != 0) {
|
||||||
@@ -107,6 +129,13 @@ static int nativeCreateTimer(Interpreter* interpreter, LiteralArray* arguments)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AS_INTEGER(microsecondLiteral) <= -1000 * 1000 || AS_INTEGER(microsecondLiteral) >= 1000 * 1000) {
|
||||||
|
interpreter->errorOutput("Microseconds out of range in createTimer\n");
|
||||||
|
freeLiteral(secondLiteral);
|
||||||
|
freeLiteral(microsecondLiteral);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
//get the timeinfo from toy
|
//get the timeinfo from toy
|
||||||
struct timeval* timeinfo = ALLOCATE(struct timeval, 1);
|
struct timeval* timeinfo = ALLOCATE(struct timeval, 1);
|
||||||
timeinfo->tv_sec = AS_INTEGER(secondLiteral);
|
timeinfo->tv_sec = AS_INTEGER(secondLiteral);
|
||||||
@@ -259,9 +288,17 @@ static int nativeTimerToString(Interpreter* interpreter, LiteralArray* arguments
|
|||||||
struct timeval* timer = AS_OPAQUE(timeLiteral);
|
struct timeval* timer = AS_OPAQUE(timeLiteral);
|
||||||
|
|
||||||
//create the string literal
|
//create the string literal
|
||||||
|
Literal resultLiteral = TO_NULL_LITERAL;
|
||||||
|
if (timer->tv_sec == 0 && timer->tv_usec < 0) { //special case, for when the negative sign is encoded in the usec
|
||||||
|
char buffer[128];
|
||||||
|
snprintf(buffer, 128, "-%ld.%06ld", timer->tv_sec, -timer->tv_usec);
|
||||||
|
resultLiteral = TO_STRING_LITERAL( copyString(buffer, strlen(buffer)), strlen(buffer));
|
||||||
|
}
|
||||||
|
else { //normal case
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
snprintf(buffer, 128, "%ld.%06ld", timer->tv_sec, timer->tv_usec);
|
snprintf(buffer, 128, "%ld.%06ld", timer->tv_sec, timer->tv_usec);
|
||||||
Literal resultLiteral = TO_STRING_LITERAL( copyString(buffer, strlen(buffer)), strlen(buffer));
|
resultLiteral = TO_STRING_LITERAL( copyString(buffer, strlen(buffer)), strlen(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
pushLiteralArray(&interpreter->stack, resultLiteral);
|
pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import timer;
|
||||||
|
|
||||||
|
var a = createTimer(1, 0);
|
||||||
|
var b = createTimer(2, 0);
|
||||||
|
|
||||||
|
print a.compareTimer(b).timerToString();
|
||||||
|
print b.compareTimer(a).timerToString();
|
||||||
|
|
||||||
|
var c = createTimer(0, 1);
|
||||||
|
var d = createTimer(0, 2);
|
||||||
|
|
||||||
|
print c.compareTimer(d).timerToString();
|
||||||
|
print d.compareTimer(c).timerToString();
|
||||||
|
|||||||
@@ -56,5 +56,37 @@
|
|||||||
timer.destroyTimer();
|
timer.destroyTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
//test positive and negative values of timers
|
||||||
|
import timer;
|
||||||
|
|
||||||
|
var a = createTimer(1, 0);
|
||||||
|
var b = createTimer(2, 0);
|
||||||
|
|
||||||
|
var acmp = a.compareTimer(b);
|
||||||
|
var bcmp = b.compareTimer(a);
|
||||||
|
|
||||||
|
var c = createTimer(0, 1);
|
||||||
|
var d = createTimer(0, 2);
|
||||||
|
|
||||||
|
var ccmp = c.compareTimer(d);
|
||||||
|
var dcmp = d.compareTimer(c);
|
||||||
|
|
||||||
|
assert acmp.timerToString() == "1.000000", "positive and negative tests failed (acmp)";
|
||||||
|
assert bcmp.timerToString() == "-1.000000", "positive and negative tests failed (bcmp)";
|
||||||
|
assert ccmp.timerToString() == "0.000001", "positive and negative tests failed (ccmp)";
|
||||||
|
assert dcmp.timerToString() == "-0.000001", "positive and negative tests failed (dcmp)";
|
||||||
|
|
||||||
|
a.destroyTimer();
|
||||||
|
b.destroyTimer();
|
||||||
|
c.destroyTimer();
|
||||||
|
d.destroyTimer();
|
||||||
|
acmp.destroyTimer();
|
||||||
|
bcmp.destroyTimer();
|
||||||
|
ccmp.destroyTimer();
|
||||||
|
dcmp.destroyTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
print "All good";
|
print "All good";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user