diff options
Diffstat (limited to 'portmidi/porttime/pthaiku.cpp')
| -rw-r--r-- | portmidi/porttime/pthaiku.cpp | 88 |
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 | |||
| 8 | namespace { | ||
| 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 | |||
| 33 | extern "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 | } | ||
