summaryrefslogtreecommitdiff
path: root/src/im_counter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/im_counter.cpp')
-rw-r--r--src/im_counter.cpp151
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;
+}