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
This commit is contained in:
commit
85a4c6d35d
|
@ -242,3 +242,44 @@ void uiQueueMain(void (*f)(void *data), void *data)
|
||||||
// the signature of f matches dispatch_function_t
|
// the signature of f matches dispatch_function_t
|
||||||
dispatch_async_f(dispatch_get_main_queue(), data, f);
|
dispatch_async_f(dispatch_get_main_queue(), data, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@interface uiprivTimerDelegate : NSObject {
|
||||||
|
int (*f)(void *data);
|
||||||
|
void *data;
|
||||||
|
}
|
||||||
|
- (id)initWithCallback:(int (*)(void *))callback data:(void*)callbackData;
|
||||||
|
- (void)doTimer:(NSTimer *)timer;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation uiprivTimerDelegate
|
||||||
|
|
||||||
|
- (id)initWithCallback:(int (*)(void *))callback data:(void*)callbackData
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
self->f = callback;
|
||||||
|
self->data = callbackData;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)doTimer:(NSTimer *)timer
|
||||||
|
{
|
||||||
|
if (!self->f(self->data))
|
||||||
|
[timer invalidate];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
void uiTimer(int milliseconds, int (*f)(void *data), void *data)
|
||||||
|
{
|
||||||
|
uiprivTimerDelegate *delegate;
|
||||||
|
|
||||||
|
delegate = [[uiprivTimerDelegate alloc] initWithCallback:f data:data];
|
||||||
|
[NSTimer scheduledTimerWithTimeInterval:milliseconds / 1000.0
|
||||||
|
target:delegate
|
||||||
|
selector:@selector(doTimer:)
|
||||||
|
userInfo:nil
|
||||||
|
repeats:YES];
|
||||||
|
[delegate release];
|
||||||
|
}
|
||||||
|
|
|
@ -42,9 +42,15 @@ _add_example(drawtext
|
||||||
${_EXAMPLE_RESOURCES_RC}
|
${_EXAMPLE_RESOURCES_RC}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_add_example(timer
|
||||||
|
timer/main.c
|
||||||
|
${_EXAMPLE_RESOURCES_RC}
|
||||||
|
)
|
||||||
|
|
||||||
add_custom_target(examples
|
add_custom_target(examples
|
||||||
DEPENDS
|
DEPENDS
|
||||||
controlgallery
|
controlgallery
|
||||||
histogram
|
histogram
|
||||||
cpp-multithread
|
cpp-multithread
|
||||||
drawtext)
|
drawtext
|
||||||
|
timer)
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "../../ui.h"
|
||||||
|
|
||||||
|
uiMultilineEntry *e;
|
||||||
|
|
||||||
|
int sayTime(void *data)
|
||||||
|
{
|
||||||
|
time_t t;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
t = time(NULL);
|
||||||
|
s = ctime(&t);
|
||||||
|
|
||||||
|
uiMultilineEntryAppend(e, s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int onClosing(uiWindow *w, void *data)
|
||||||
|
{
|
||||||
|
uiQuit();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void saySomething(uiButton *b, void *data)
|
||||||
|
{
|
||||||
|
uiMultilineEntryAppend(e, "Saying something\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
uiInitOptions o;
|
||||||
|
uiWindow *w;
|
||||||
|
uiBox *b;
|
||||||
|
uiButton *btn;
|
||||||
|
|
||||||
|
memset(&o, 0, sizeof (uiInitOptions));
|
||||||
|
if (uiInit(&o) != NULL)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
w = uiNewWindow("Hello", 320, 240, 0);
|
||||||
|
uiWindowSetMargined(w, 1);
|
||||||
|
|
||||||
|
b = uiNewVerticalBox();
|
||||||
|
uiBoxSetPadded(b, 1);
|
||||||
|
uiWindowSetChild(w, uiControl(b));
|
||||||
|
|
||||||
|
e = uiNewMultilineEntry();
|
||||||
|
uiMultilineEntrySetReadOnly(e, 1);
|
||||||
|
|
||||||
|
btn = uiNewButton("Say Something");
|
||||||
|
uiButtonOnClicked(btn, saySomething, NULL);
|
||||||
|
uiBoxAppend(b, uiControl(btn), 0);
|
||||||
|
|
||||||
|
uiBoxAppend(b, uiControl(e), 1);
|
||||||
|
|
||||||
|
uiTimer(1000, sayTime, NULL);
|
||||||
|
|
||||||
|
uiWindowOnClosing(w, onClosing, NULL);
|
||||||
|
uiControlShow(uiControl(w));
|
||||||
|
uiMain();
|
||||||
|
return 0;
|
||||||
|
}
|
2
ui.h
2
ui.h
|
@ -62,6 +62,8 @@ _UI_EXTERN void uiQuit(void);
|
||||||
|
|
||||||
_UI_EXTERN void uiQueueMain(void (*f)(void *data), void *data);
|
_UI_EXTERN void uiQueueMain(void (*f)(void *data), void *data);
|
||||||
|
|
||||||
|
_UI_EXTERN void uiTimer(int milliseconds, int (*f)(void *data), void *data);
|
||||||
|
|
||||||
_UI_EXTERN void uiOnShouldQuit(int (*f)(void *data), void *data);
|
_UI_EXTERN void uiOnShouldQuit(int (*f)(void *data), void *data);
|
||||||
|
|
||||||
_UI_EXTERN void uiFreeText(char *text);
|
_UI_EXTERN void uiFreeText(char *text);
|
||||||
|
|
27
unix/main.c
27
unix/main.c
|
@ -106,3 +106,30 @@ void uiQueueMain(void (*f)(void *data), void *data)
|
||||||
q->data = data;
|
q->data = data;
|
||||||
gdk_threads_add_idle(doqueued, q);
|
gdk_threads_add_idle(doqueued, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct timer {
|
||||||
|
int (*f)(void *);
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean dotimer(gpointer data)
|
||||||
|
{
|
||||||
|
struct timer *t = (struct timer *) data;
|
||||||
|
|
||||||
|
if((*(t->f))(t->data))
|
||||||
|
return TRUE;
|
||||||
|
else {
|
||||||
|
uiFree(t);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiTimer(int milliseconds, int (*f)(void *data), void *data)
|
||||||
|
{
|
||||||
|
struct timer *t;
|
||||||
|
|
||||||
|
t = uiNew(struct timer);
|
||||||
|
t->f = f;
|
||||||
|
t->data = data;
|
||||||
|
g_timeout_add(milliseconds, dotimer, t);
|
||||||
|
}
|
||||||
|
|
|
@ -128,3 +128,12 @@ void uiQueueMain(void (*f)(void *data), void *data)
|
||||||
// LONGTERM this is likely not safe to call across threads (allocates memory)
|
// LONGTERM this is likely not safe to call across threads (allocates memory)
|
||||||
logLastError(L"error queueing function to run on main thread");
|
logLastError(L"error queueing function to run on main thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uiTimer(int milliseconds, int (*f)(void *data), void *data)
|
||||||
|
{
|
||||||
|
UINT_PTR timer;
|
||||||
|
|
||||||
|
timer = (UINT_PTR) new TimerHandler(f, data);
|
||||||
|
if (SetTimer(utilWindow, timer, milliseconds, NULL) == 0)
|
||||||
|
logLastError(L"SetTimer()");
|
||||||
|
}
|
||||||
|
|
|
@ -95,6 +95,22 @@ extern const char *initUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor);
|
||||||
extern void uninitUtilWindow(void);
|
extern void uninitUtilWindow(void);
|
||||||
|
|
||||||
// main.cpp
|
// main.cpp
|
||||||
|
struct TimerHandler {
|
||||||
|
public:
|
||||||
|
TimerHandler() : TimerHandler(NULL, NULL) {}
|
||||||
|
TimerHandler(int(*f)(void *data), void *data)
|
||||||
|
{
|
||||||
|
this->f = f;
|
||||||
|
this->data = data;
|
||||||
|
}
|
||||||
|
int operator()()
|
||||||
|
{
|
||||||
|
return this->f(this->data);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
int(*f)(void *data);
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
extern int registerMessageFilter(void);
|
extern int registerMessageFilter(void);
|
||||||
extern void unregisterMessageFilter(void);
|
extern void unregisterMessageFilter(void);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ static LRESULT CALLBACK utilWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, L
|
||||||
{
|
{
|
||||||
void (*qf)(void *);
|
void (*qf)(void *);
|
||||||
LRESULT lResult;
|
LRESULT lResult;
|
||||||
|
TimerHandler *timer;
|
||||||
|
|
||||||
if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE)
|
if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE)
|
||||||
return lResult;
|
return lResult;
|
||||||
|
@ -36,6 +37,14 @@ static LRESULT CALLBACK utilWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, L
|
||||||
qf = (void (*)(void *)) wParam;
|
qf = (void (*)(void *)) wParam;
|
||||||
(*qf)((void *) lParam);
|
(*qf)((void *) lParam);
|
||||||
return 0;
|
return 0;
|
||||||
|
case WM_TIMER:
|
||||||
|
timer = (TimerHandler *) wParam;
|
||||||
|
if (!(*timer)()) {
|
||||||
|
if (!KillTimer(utilWindow, (UINT_PTR) timer))
|
||||||
|
logLastError(L"KillTimer()");
|
||||||
|
delete timer;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue