aboutsummaryrefslogtreecommitdiff
path: root/portmidi/porttime/pthaiku.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'portmidi/porttime/pthaiku.cpp')
-rw-r--r--portmidi/porttime/pthaiku.cpp88
1 files changed, 88 insertions, 0 deletions
diff --git a/portmidi/porttime/pthaiku.cpp b/portmidi/porttime/pthaiku.cpp
new file mode 100644
index 0000000..9d8de14
--- /dev/null
+++ b/portmidi/porttime/pthaiku.cpp
@@ -0,0 +1,88 @@
1// pthaiku.cpp - portable timer implementation for Haiku
2
3#include "porttime.h"
4#include <Looper.h>
5#include <MessageRunner.h>
6#include <OS.h>
7
8namespace {
9 const uint32 timerMessage = 'PTTM';
10
11 struct TimerLooper : BLooper {
12 TimerLooper() : BLooper() {
13 }
14
15
16 virtual void MessageReceived(BMessage *message)
17 {
18 PtCallback *callback;
19 void *userData;
20 if (message->what == timerMessage && message->FindPointer("callback", (void**)&callback) == B_OK && message->FindPointer("userData", &userData) == B_OK) {
21 (*callback)(Pt_Time(), userData);
22 }
23 BLooper::MessageReceived(message);
24 }
25 };
26
27 bool time_started_flag = false;
28 bigtime_t time_offset;
29 TimerLooper *timerLooper;
30 BMessageRunner *timerRunner;
31}
32
33extern "C" {
34 PtError Pt_Start(int resolution, PtCallback *callback, void *userData)
35 {
36 if (time_started_flag) return ptAlreadyStarted;
37 time_offset = system_time();
38 if (callback) {
39 timerLooper = new TimerLooper;
40 timerLooper->Run();
41 BMessenger target(timerLooper);
42 BMessage message(timerMessage);
43 message.AddPointer("callback", (void*)callback);
44 message.AddPointer("userData", userData);
45 bigtime_t interval = resolution * 1000;
46 timerRunner = new BMessageRunner(target, &message, interval);
47 if(timerRunner->InitCheck() != B_OK) {
48 delete timerRunner;
49 timerRunner = NULL;
50 timerLooper->PostMessage(B_QUIT_REQUESTED);
51 timerLooper = NULL;
52 return ptHostError;
53 }
54 }
55 time_started_flag = true;
56 return ptNoError;
57 }
58
59
60 PtError Pt_Stop()
61 {
62 if (!time_started_flag) return ptAlreadyStopped;
63 time_started_flag = false;
64 delete timerRunner;
65 timerRunner = NULL;
66 timerLooper->PostMessage(B_QUIT_REQUESTED);
67 timerLooper = NULL;
68 return ptNoError;
69 }
70
71
72 int Pt_Started()
73 {
74 return time_started_flag;
75 }
76
77
78 PtTimestamp Pt_Time()
79 {
80 return (system_time() - time_offset) / 1000;
81 }
82
83
84 void Pt_Sleep(int32_t duration)
85 {
86 snooze(duration * 1000);
87 }
88}