Skip to content

Commit 85a4c6d

Browse files
authored
Merge pull request #277 from cody271/timer
Adds a function uiTimer() that runs code on the main loop at certain intervals. Original comment: Add Timer API
2 parents 9cf6c3f + 5622b13 commit 85a4c6d

File tree

8 files changed

+175
-1
lines changed

8 files changed

+175
-1
lines changed

darwin/main.m

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,44 @@ void uiQueueMain(void (*f)(void *data), void *data)
242242
// the signature of f matches dispatch_function_t
243243
dispatch_async_f(dispatch_get_main_queue(), data, f);
244244
}
245+
246+
@interface uiprivTimerDelegate : NSObject {
247+
int (*f)(void *data);
248+
void *data;
249+
}
250+
- (id)initWithCallback:(int (*)(void *))callback data:(void*)callbackData;
251+
- (void)doTimer:(NSTimer *)timer;
252+
@end
253+
254+
@implementation uiprivTimerDelegate
255+
256+
- (id)initWithCallback:(int (*)(void *))callback data:(void*)callbackData
257+
{
258+
self = [super init];
259+
if (self) {
260+
self->f = callback;
261+
self->data = callbackData;
262+
}
263+
return self;
264+
}
265+
266+
- (void)doTimer:(NSTimer *)timer
267+
{
268+
if (!self->f(self->data))
269+
[timer invalidate];
270+
}
271+
272+
@end
273+
274+
void uiTimer(int milliseconds, int (*f)(void *data), void *data)
275+
{
276+
uiprivTimerDelegate *delegate;
277+
278+
delegate = [[uiprivTimerDelegate alloc] initWithCallback:f data:data];
279+
[NSTimer scheduledTimerWithTimeInterval:milliseconds / 1000.0
280+
target:delegate
281+
selector:@selector(doTimer:)
282+
userInfo:nil
283+
repeats:YES];
284+
[delegate release];
285+
}

examples/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,15 @@ _add_example(drawtext
4242
${_EXAMPLE_RESOURCES_RC}
4343
)
4444

45+
_add_example(timer
46+
timer/main.c
47+
${_EXAMPLE_RESOURCES_RC}
48+
)
49+
4550
add_custom_target(examples
4651
DEPENDS
4752
controlgallery
4853
histogram
4954
cpp-multithread
50-
drawtext)
55+
drawtext
56+
timer)

examples/timer/main.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include <string.h>
2+
#include <stdlib.h>
3+
#include <time.h>
4+
#include "../../ui.h"
5+
6+
uiMultilineEntry *e;
7+
8+
int sayTime(void *data)
9+
{
10+
time_t t;
11+
char *s;
12+
13+
t = time(NULL);
14+
s = ctime(&t);
15+
16+
uiMultilineEntryAppend(e, s);
17+
return 1;
18+
}
19+
20+
int onClosing(uiWindow *w, void *data)
21+
{
22+
uiQuit();
23+
return 1;
24+
}
25+
26+
void saySomething(uiButton *b, void *data)
27+
{
28+
uiMultilineEntryAppend(e, "Saying something\n");
29+
}
30+
31+
int main(void)
32+
{
33+
uiInitOptions o;
34+
uiWindow *w;
35+
uiBox *b;
36+
uiButton *btn;
37+
38+
memset(&o, 0, sizeof (uiInitOptions));
39+
if (uiInit(&o) != NULL)
40+
abort();
41+
42+
w = uiNewWindow("Hello", 320, 240, 0);
43+
uiWindowSetMargined(w, 1);
44+
45+
b = uiNewVerticalBox();
46+
uiBoxSetPadded(b, 1);
47+
uiWindowSetChild(w, uiControl(b));
48+
49+
e = uiNewMultilineEntry();
50+
uiMultilineEntrySetReadOnly(e, 1);
51+
52+
btn = uiNewButton("Say Something");
53+
uiButtonOnClicked(btn, saySomething, NULL);
54+
uiBoxAppend(b, uiControl(btn), 0);
55+
56+
uiBoxAppend(b, uiControl(e), 1);
57+
58+
uiTimer(1000, sayTime, NULL);
59+
60+
uiWindowOnClosing(w, onClosing, NULL);
61+
uiControlShow(uiControl(w));
62+
uiMain();
63+
return 0;
64+
}

ui.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ _UI_EXTERN void uiQuit(void);
6262

6363
_UI_EXTERN void uiQueueMain(void (*f)(void *data), void *data);
6464

65+
_UI_EXTERN void uiTimer(int milliseconds, int (*f)(void *data), void *data);
66+
6567
_UI_EXTERN void uiOnShouldQuit(int (*f)(void *data), void *data);
6668

6769
_UI_EXTERN void uiFreeText(char *text);

unix/main.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,30 @@ void uiQueueMain(void (*f)(void *data), void *data)
106106
q->data = data;
107107
gdk_threads_add_idle(doqueued, q);
108108
}
109+
110+
struct timer {
111+
int (*f)(void *);
112+
void *data;
113+
};
114+
115+
static gboolean dotimer(gpointer data)
116+
{
117+
struct timer *t = (struct timer *) data;
118+
119+
if((*(t->f))(t->data))
120+
return TRUE;
121+
else {
122+
uiFree(t);
123+
return FALSE;
124+
}
125+
}
126+
127+
void uiTimer(int milliseconds, int (*f)(void *data), void *data)
128+
{
129+
struct timer *t;
130+
131+
t = uiNew(struct timer);
132+
t->f = f;
133+
t->data = data;
134+
g_timeout_add(milliseconds, dotimer, t);
135+
}

windows/main.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,12 @@ void uiQueueMain(void (*f)(void *data), void *data)
128128
// LONGTERM this is likely not safe to call across threads (allocates memory)
129129
logLastError(L"error queueing function to run on main thread");
130130
}
131+
132+
void uiTimer(int milliseconds, int (*f)(void *data), void *data)
133+
{
134+
UINT_PTR timer;
135+
136+
timer = (UINT_PTR) new TimerHandler(f, data);
137+
if (SetTimer(utilWindow, timer, milliseconds, NULL) == 0)
138+
logLastError(L"SetTimer()");
139+
}

windows/uipriv_windows.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,22 @@ extern const char *initUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor);
9595
extern void uninitUtilWindow(void);
9696

9797
// main.cpp
98+
struct TimerHandler {
99+
public:
100+
TimerHandler() : TimerHandler(NULL, NULL) {}
101+
TimerHandler(int(*f)(void *data), void *data)
102+
{
103+
this->f = f;
104+
this->data = data;
105+
}
106+
int operator()()
107+
{
108+
return this->f(this->data);
109+
}
110+
private:
111+
int(*f)(void *data);
112+
void *data;
113+
};
98114
extern int registerMessageFilter(void);
99115
extern void unregisterMessageFilter(void);
100116

windows/utilwin.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ static LRESULT CALLBACK utilWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, L
1818
{
1919
void (*qf)(void *);
2020
LRESULT lResult;
21+
TimerHandler *timer;
2122

2223
if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE)
2324
return lResult;
@@ -36,6 +37,14 @@ static LRESULT CALLBACK utilWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, L
3637
qf = (void (*)(void *)) wParam;
3738
(*qf)((void *) lParam);
3839
return 0;
40+
case WM_TIMER:
41+
timer = (TimerHandler *) wParam;
42+
if (!(*timer)()) {
43+
if (!KillTimer(utilWindow, (UINT_PTR) timer))
44+
logLastError(L"KillTimer()");
45+
delete timer;
46+
}
47+
return 0;
3948
}
4049
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
4150
}

0 commit comments

Comments
 (0)