diff options
Diffstat (limited to 'src/im_counter.cpp')
-rw-r--r-- | src/im_counter.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/im_counter.cpp b/src/im_counter.cpp new file mode 100644 index 0000000..8c5cd5c --- /dev/null +++ b/src/im_counter.cpp @@ -0,0 +1,151 @@ +/** \file + * \brief Processing Counter + * + * See Copyright Notice in im_lib.h + * $Id: im_counter.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $ + */ + +#include "im_counter.h" + +#include <stdlib.h> +#include <memory.h> + + +static imCounterCallback iCounterFunc = NULL; +static void* iCounterUserData = NULL; + +imCounterCallback imCounterSetCallback(void* user_data, imCounterCallback counter_func) +{ + imCounterCallback old_counter_func = iCounterFunc; + iCounterFunc = counter_func; + if (user_data) + iCounterUserData = user_data; + return old_counter_func; +} + +struct iCounter +{ + int total; + int current; + int sequence; + const char* message; +}; + +#define MAX_COUNTERS 10 +static iCounter iCounterList[MAX_COUNTERS]; + +int imCounterBegin(const char* title) +{ + static int first = 1; + if (first) + { + memset(iCounterList, 0, MAX_COUNTERS*sizeof(iCounter)); + first = 0; + } + + if (!iCounterFunc) // counter management is useless + return -1; + + int counter = -1; + for (int i = 0; i < MAX_COUNTERS; i++) + { + if (iCounterList[i].sequence == 0 || // the counter is free + iCounterList[i].current == 0) // or we are in a sequence + { + counter = i; + break; + } + } + + if (counter == -1) return -1; // too many counters + + iCounter *ct = &iCounterList[counter]; + + ct->sequence++; + + if (ct->sequence == 1) // top level counter + iCounterFunc(counter, iCounterUserData, title, -1); + + return counter; +} + +void imCounterEnd(int counter) +{ + if (counter == -1 || !iCounterFunc) return; // invalid counter + + iCounter *ct = &iCounterList[counter]; + + if (ct->sequence == 1) // top level counter + { + iCounterFunc(counter, iCounterUserData, NULL, 1001); + memset(ct, 0, sizeof(iCounter)); + } + else + ct->sequence--; +} + +int imCounterInc(int counter) +{ + if (counter == -1 || !iCounterFunc) // invalid counter + return 1; + + iCounter *ct = &iCounterList[counter]; + + if (ct->sequence == 0 || // counter with no begin or no total + ct->total == 0) + return 1; + + const char* msg = NULL; + if (ct->current == 0) + msg = ct->message; + + ct->current++; + + int progress = (int)((ct->current * 1000.0f)/ct->total); + + if (ct->current == ct->total) + ct->current = 0; + + return iCounterFunc(counter, iCounterUserData, msg, progress); +} + +int imCounterIncTo(int counter, int count) +{ + if (counter == -1 || !iCounterFunc) // invalid counter + return 1; + + iCounter *ct = &iCounterList[counter]; + + if (ct->sequence == 0 || // counter with no begin or no total + ct->total == 0) + return 1; + + if (count <= 0) count = 0; + if (count >= ct->total) count = ct->total; + + ct->current = count; + + const char* msg = NULL; + if (ct->current == 0) + msg = ct->message; + + int progress = (int)((ct->current * 1000.0f)/ct->total); + + if (ct->current == ct->total) + ct->current = 0; + + return iCounterFunc(counter, iCounterUserData, msg, progress); +} + +void imCounterTotal(int counter, int total, const char* message) +{ + if (counter == -1 || !iCounterFunc) return; // invalid counter + + iCounter *ct = &iCounterList[counter]; + + if (ct->sequence == 0) return; // counter with no begin + + ct->message = message; + ct->total = total; + ct->current = 0; +} |