1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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;
}
|