diff --git a/headers/os/media/TimedEventQueue.h b/headers/os/media/TimedEventQueue.h index 54cb46b695..313e346f55 100644 --- a/headers/os/media/TimedEventQueue.h +++ b/headers/os/media/TimedEventQueue.h @@ -1,24 +1,20 @@ /* - * Copyright 2009, Haiku, Inc. All rights reserved. + * Copyright 2009-2024, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _TIMED_EVENT_QUEUE_H #define _TIMED_EVENT_QUEUE_H -#include -struct _event_queue_imp; +#include struct media_timed_event { media_timed_event(); - media_timed_event(bigtime_t inTime, - int32 inType); - media_timed_event(bigtime_t inTime, - int32 inType, void*inPointer, - uint32 inCleanup); - media_timed_event( - bigtime_t inTime, int32 inType, + media_timed_event(bigtime_t inTime, int32 inType); + media_timed_event(bigtime_t inTime, int32 inType, + void* inPointer, uint32 inCleanup); + media_timed_event(bigtime_t inTime, int32 inType, void* inPointer, uint32 inCleanup, int32 inData, int64 inBigdata, const char* inUserData, size_t dataSize = 0); @@ -28,9 +24,9 @@ struct media_timed_event { ~media_timed_event(); - // TODO: Should this not return "media_timed_event&" ?! void operator=(const media_timed_event& other); +public: bigtime_t event_time; int32 type; void* pointer; @@ -39,6 +35,7 @@ struct media_timed_event { int64 bigdata; char user_data[64]; +private: uint32 _reserved_media_timed_event_[8]; }; @@ -49,15 +46,16 @@ bool operator<(const media_timed_event& a, const media_timed_event& b); bool operator>(const media_timed_event& a, const media_timed_event&b); -/*! A priority queue for holding media_timed_events. Sorts by increasing time, - so events near the front of the queue are to occur earlier. -*/ +namespace BPrivate { + class TimedEventQueueData; +}; + class BTimedEventQueue { public: - enum event_type { - B_NO_EVENT = -1, // Pushing this type will always fail. - B_ANY_EVENT = 0, // Pushing this type will always fail. + B_NO_EVENT = -1, + B_ANY_EVENT = 0, + B_START, B_STOP, B_SEEK, @@ -68,16 +66,13 @@ public: B_HARDWARE, B_PARAMETER, - // User defined events are greater than this value. B_USER_EVENT = 0x4000 }; enum cleanup_flag { B_NO_CLEANUP = 0, - B_RECYCLE_BUFFER, // Specifies to recycle buffers handled by - // BTimedEventQueue. - B_EXPIRE_TIMER, // Specifies to call TimerExpired() on the - // event->data. + B_RECYCLE_BUFFER, + B_EXPIRE_TIMER, B_USER_CLEANUP = 0x4000 }; @@ -88,13 +83,18 @@ public: B_AFTER_TIME }; - +public: void* operator new(size_t size); void operator delete(void* ptr, size_t size); BTimedEventQueue(); virtual ~BTimedEventQueue(); + typedef void (*cleanup_hook)(const media_timed_event* event, + void* context); + void SetCleanupHook(cleanup_hook hook, + void* context); + status_t AddEvent(const media_timed_event& event); status_t RemoveEvent(const media_timed_event* event); status_t RemoveFirstEvent( @@ -103,7 +103,6 @@ public: bool HasEvents() const; int32 EventCount() const; - const media_timed_event* FirstEvent() const; bigtime_t FirstEventTime() const; const media_timed_event* LastEvent() const; @@ -114,12 +113,6 @@ public: bool inclusive = true, int32 eventType = B_ANY_EVENT); - - // Queue manipulation - // Call DoForEach to perform a function on each event in the queue. - // Return an appropriate status defining an action to take for that event. - // DoForEach is an atomic operation ensuring the consistency of the queue - // during the call. enum queue_action { B_DONE = -1, B_NO_ACTION = 0, @@ -135,14 +128,6 @@ public: bool inclusive = true, int32 eventType = B_ANY_EVENT); - - // Flushing events - // The cleanup hook is called when events are flushed from the queue and - // the cleanup is not B_NO_CLEANUP or B_RECYCLE_BUFFER. - typedef void (*cleanup_hook)(const media_timed_event* event, - void* context); - void SetCleanupHook(cleanup_hook hook, - void* context); status_t FlushEvents(bigtime_t eventTime, time_direction direction, bool inclusive = true, @@ -150,39 +135,45 @@ public: private: // FBC padding and forbidden methods - BTimedEventQueue( - const BTimedEventQueue& other); - BTimedEventQueue& operator=(const BTimedEventQueue& other); + virtual void _ReservedTimedEventQueue0(); + virtual void _ReservedTimedEventQueue1(); + virtual void _ReservedTimedEventQueue2(); + virtual void _ReservedTimedEventQueue3(); + virtual void _ReservedTimedEventQueue4(); + virtual void _ReservedTimedEventQueue5(); + virtual void _ReservedTimedEventQueue6(); + virtual void _ReservedTimedEventQueue7(); + virtual void _ReservedTimedEventQueue8(); + virtual void _ReservedTimedEventQueue9(); + virtual void _ReservedTimedEventQueue10(); + virtual void _ReservedTimedEventQueue11(); + virtual void _ReservedTimedEventQueue12(); + virtual void _ReservedTimedEventQueue13(); + virtual void _ReservedTimedEventQueue14(); + virtual void _ReservedTimedEventQueue15(); + virtual void _ReservedTimedEventQueue16(); + virtual void _ReservedTimedEventQueue17(); + virtual void _ReservedTimedEventQueue18(); + virtual void _ReservedTimedEventQueue19(); + virtual void _ReservedTimedEventQueue20(); + virtual void _ReservedTimedEventQueue21(); + virtual void _ReservedTimedEventQueue22(); + virtual void _ReservedTimedEventQueue23(); - virtual status_t _Reserved_BTimedEventQueue_0(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_1(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_2(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_3(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_4(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_5(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_6(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_7(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_8(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_9(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_10(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_11(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_12(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_13(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_14(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_15(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_16(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_17(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_18(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_19(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_20(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_21(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_22(void*, ...); - virtual status_t _Reserved_BTimedEventQueue_23(void*, ...); + BTimedEventQueue(const BTimedEventQueue&); + BTimedEventQueue& operator=(const BTimedEventQueue&); private: - _event_queue_imp* fImp; + static int _Match(const media_timed_event& event, + bigtime_t eventTime, + time_direction direction, + bool inclusive, int32 eventType); - uint32 _reserved_timed_event_queue_[6]; +private: + BPrivate::TimedEventQueueData* fData; + + uint32 _reserved[6]; }; + #endif diff --git a/src/kits/media/Jamfile b/src/kits/media/Jamfile index c07fae9d1e..a63eb36e3e 100644 --- a/src/kits/media/Jamfile +++ b/src/kits/media/Jamfile @@ -2,7 +2,7 @@ SubDir HAIKU_TOP src kits media ; AddResources libmedia.so : libmedia.rdef ; -UsePrivateHeaders app media shared ; +UsePrivateHeaders app media kernel shared ; UsePrivateHeaders [ FDirName media experimental ] ; UsePrivateHeaders [ FDirName interface ] ; @@ -70,7 +70,6 @@ for architectureObject in [ MultiArchSubDirSetup ] { request_data.cpp SharedBufferList.cpp TrackReader.cpp - TimedEventQueuePrivate.cpp TimeSourceObject.cpp TimeSourceObjectManager.cpp SoundPlayNode.cpp diff --git a/src/kits/media/TimedEventQueue.cpp b/src/kits/media/TimedEventQueue.cpp index 22818aa65b..ab99e703b2 100644 --- a/src/kits/media/TimedEventQueue.cpp +++ b/src/kits/media/TimedEventQueue.cpp @@ -1,17 +1,19 @@ -/*********************************************************************** - * AUTHOR: Marcus Overhagen - * FILE: TimedEventQueue.cpp - * DESCR: used by BMediaEventLooper - ***********************************************************************/ +/* + * Copyright 2024, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ #include -#include -#include "TimedEventQueuePrivate.h" -#include "MediaDebug.h" -/************************************************************* - * struct media_timed_event - *************************************************************/ +#include +#include +#include +#include +#include + + +// #pragma mark - media_timed_event + media_timed_event::media_timed_event() { @@ -20,23 +22,22 @@ media_timed_event::media_timed_event() } -media_timed_event::media_timed_event(bigtime_t inTime, - int32 inType) +media_timed_event::media_timed_event(bigtime_t inTime, int32 inType) { CALLED(); memset(this, 0, sizeof(*this)); + event_time = inTime; type = inType; } -media_timed_event::media_timed_event(bigtime_t inTime, - int32 inType, - void *inPointer, - uint32 inCleanup) +media_timed_event::media_timed_event(bigtime_t inTime, int32 inType, + void* inPointer, uint32 inCleanup) { CALLED(); memset(this, 0, sizeof(*this)); + event_time = inTime; type = inType; pointer = inPointer; @@ -44,28 +45,26 @@ media_timed_event::media_timed_event(bigtime_t inTime, } -media_timed_event::media_timed_event(bigtime_t inTime, - int32 inType, - void *inPointer, - uint32 inCleanup, - int32 inData, - int64 inBigdata, - const char *inUserData, - size_t dataSize) +media_timed_event::media_timed_event(bigtime_t inTime, int32 inType, + void* inPointer, uint32 inCleanup, + int32 inData, int64 inBigdata, + const char* inUserData, size_t dataSize) { CALLED(); memset(this, 0, sizeof(*this)); + event_time = inTime; type = inType; pointer = inPointer; cleanup = inCleanup; data = inData; bigdata = inBigdata; - memcpy(user_data,inUserData,min_c(sizeof(media_timed_event::user_data),dataSize)); + memcpy(user_data, inUserData, + min_c(sizeof(media_timed_event::user_data), dataSize)); } -media_timed_event::media_timed_event(const media_timed_event &clone) +media_timed_event::media_timed_event(const media_timed_event& clone) { CALLED(); *this = clone; @@ -73,7 +72,7 @@ media_timed_event::media_timed_event(const media_timed_event &clone) void -media_timed_event::operator=(const media_timed_event &clone) +media_timed_event::operator=(const media_timed_event& clone) { CALLED(); memcpy(this, &clone, sizeof(*this)); @@ -85,58 +84,120 @@ media_timed_event::~media_timed_event() CALLED(); } -/************************************************************* - * global operators - *************************************************************/ -bool operator==(const media_timed_event & a, const media_timed_event & b) +// #pragma mark - media_timed_event global operators + + +bool +operator==(const media_timed_event& a, const media_timed_event& b) { CALLED(); - return (0 == memcmp(&a,&b,sizeof(media_timed_event))); + return (memcmp(&a, &b, sizeof(media_timed_event)) == 0); } -bool operator!=(const media_timed_event & a, const media_timed_event & b) + +bool +operator!=(const media_timed_event& a, const media_timed_event& b) { CALLED(); - return (0 != memcmp(&a,&b,sizeof(media_timed_event))); + return (memcmp(&a, &b, sizeof(media_timed_event)) != 0); } -bool operator<(const media_timed_event & a, const media_timed_event & b) + +bool +operator<(const media_timed_event& a, const media_timed_event& b) { CALLED(); return a.event_time < b.event_time; } -bool operator>(const media_timed_event & a, const media_timed_event &b) + +bool +operator>(const media_timed_event& a, const media_timed_event& b) { CALLED(); return a.event_time > b.event_time; } -/************************************************************* - * public BTimedEventQueue - *************************************************************/ +// #pragma mark - BTimedEventQueue -void * -BTimedEventQueue::operator new(size_t s) -{ - CALLED(); - return ::operator new(s); -} +struct queue_entry : public DoublyLinkedListLinkImpl { + media_timed_event event; +}; +typedef DoublyLinkedList QueueEntryList; -void -BTimedEventQueue::operator delete(void *p, size_t s) -{ - CALLED(); - return ::operator delete(p); -} +class BPrivate::TimedEventQueueData { +public: + TimedEventQueueData() + : + fLock("BTimedEventQueue"), + fEntryAllocationLock("BTimedEventQueue entry allocation") + { + fEventCount = 0; + fCleanupHook = NULL; + fCleanupHookContext = NULL; + + for (size_t i = 0; i < B_COUNT_OF(fInlineEntries); i++) + fFreeEntries.Add(&fInlineEntries[i]); + } + ~TimedEventQueueData() + { + while (queue_entry* chunk = fChunkHeads.RemoveHead()) + free(chunk); + } + + queue_entry* AllocateEntry() + { + BAutolock locker(fEntryAllocationLock); + if (fFreeEntries.Head() != NULL) + return fFreeEntries.RemoveHead(); + + // We need a new chunk. + const size_t chunkSize = B_PAGE_SIZE; + queue_entry* newEntries = (queue_entry*)malloc(chunkSize); + fChunkHeads.Add(&newEntries[0]); + for (size_t i = 1; i < (chunkSize / sizeof(queue_entry)); i++) + fFreeEntries.Add(&newEntries[i]); + + return fFreeEntries.RemoveHead(); + } + + void FreeEntry(queue_entry* entry) + { + BAutolock locker(fEntryAllocationLock); + fFreeEntries.Add(entry); + + // TODO: Chunks are currently only freed in the destructor. + // (Is that a problem? They're probably rarely used, anyway.) + } + + status_t AddEntry(queue_entry* newEntry); + void RemoveEntry(queue_entry* newEntry); + void CleanupAndFree(queue_entry* entry); + +public: + BLocker fLock; + QueueEntryList fEvents; + int32 fEventCount; + + BTimedEventQueue::cleanup_hook fCleanupHook; + void* fCleanupHookContext; + +private: + BLocker fEntryAllocationLock; + QueueEntryList fFreeEntries; + QueueEntryList fChunkHeads; + queue_entry fInlineEntries[8]; +}; + +using BPrivate::TimedEventQueueData; -BTimedEventQueue::BTimedEventQueue() : - fImp(new _event_queue_imp) +BTimedEventQueue::BTimedEventQueue() + : fData(new TimedEventQueueData) { CALLED(); } @@ -145,31 +206,157 @@ BTimedEventQueue::BTimedEventQueue() : BTimedEventQueue::~BTimedEventQueue() { CALLED(); - delete fImp; + delete fData; } status_t -BTimedEventQueue::AddEvent(const media_timed_event &event) +BTimedEventQueue::AddEvent(const media_timed_event& event) { CALLED(); - return fImp->AddEvent(event); + + if (event.type < B_START) + return B_BAD_VALUE; + + queue_entry* newEntry = fData->AllocateEntry(); + if (newEntry == NULL) + return B_NO_MEMORY; + + newEntry->event = event; + + BAutolock locker(fData->fLock); + return fData->AddEntry(newEntry); } status_t -BTimedEventQueue::RemoveEvent(const media_timed_event *event) +BTimedEventQueue::RemoveEvent(const media_timed_event* event) { CALLED(); - return fImp->RemoveEvent(event); + BAutolock locker(fData->fLock); + + QueueEntryList::Iterator it = fData->fEvents.GetIterator(); + while (queue_entry* entry = it.Next()) { + if (entry->event != *event) + continue; + + fData->RemoveEntry(entry); + + locker.Unlock(); + + // No cleanup. + fData->FreeEntry(entry); + return B_OK; + } + + return B_ERROR; } status_t -BTimedEventQueue::RemoveFirstEvent(media_timed_event *outEvent) +BTimedEventQueue::RemoveFirstEvent(media_timed_event* _event) { CALLED(); - return fImp->RemoveFirstEvent(outEvent); + BAutolock locker(fData->fLock); + + if (fData->fEventCount == 0) + return B_ERROR; + + queue_entry* entry = fData->fEvents.Head(); + fData->RemoveEntry(entry); + + locker.Unlock(); + + if (_event != NULL) { + // No cleanup. + *_event = entry->event; + fData->FreeEntry(entry); + } else { + fData->CleanupAndFree(entry); + } + return B_OK; +} + + +status_t +TimedEventQueueData::AddEntry(queue_entry* newEntry) +{ + ASSERT(fLock.IsLocked()); + + if (fEvents.IsEmpty()) { + fEvents.Add(newEntry); + fEventCount++; + return B_OK; + } + if (fEvents.First()->event.event_time > newEntry->event.event_time) { + fEvents.Add(newEntry, false); + fEventCount++; + return B_OK; + } + + QueueEntryList::ReverseIterator it = fEvents.GetReverseIterator(); + while (queue_entry* entry = it.Next()) { + if (newEntry->event.event_time < entry->event.event_time) + continue; + + // Insert the new event after this entry. + fEvents.InsertAfter(entry, newEntry); + fEventCount++; + return B_OK; + } + + debugger("BTimedEventQueue::AddEvent: Invalid queue!"); + return B_ERROR; +} + + +void +TimedEventQueueData::RemoveEntry(queue_entry* entry) +{ + ASSERT(fLock.IsLocked()); + + fEvents.Remove(entry); + fEventCount--; +} + + +void +TimedEventQueueData::CleanupAndFree(queue_entry* entry) +{ + uint32 cleanup = entry->event.cleanup; + if (cleanup == B_DELETE) { + // B_DELETE is a keyboard code, but the Be Book indicates it's a valid + // cleanup value. (Early sample code may have used it too.) + cleanup = BTimedEventQueue::B_USER_CLEANUP; + } + + if (cleanup == BTimedEventQueue::B_NO_CLEANUP) { + // Nothing to do. + } else if (entry->event.type == BTimedEventQueue::B_HANDLE_BUFFER + && cleanup == BTimedEventQueue::B_RECYCLE_BUFFER) { + (reinterpret_cast(entry->event.pointer))->Recycle(); + } else if (cleanup == BTimedEventQueue::B_EXPIRE_TIMER) { + // TimerExpired() is invoked in BMediaEventLooper::DispatchEvent; nothing to do. + } else if (cleanup >= BTimedEventQueue::B_USER_CLEANUP) { + if (fCleanupHook != NULL) + (*fCleanupHook)(&entry->event, fCleanupHookContext); + } else { + ERROR("BTimedEventQueue: Unhandled cleanup! (type %" B_PRId32 ", " + "cleanup %" B_PRId32 ")\n", entry->event.type, entry->event.cleanup); + } + + FreeEntry(entry); +} + + +void +BTimedEventQueue::SetCleanupHook(cleanup_hook hook, void* context) +{ + CALLED(); + + BAutolock lock(fData->fLock); + fData->fCleanupHook = hook; + fData->fCleanupHookContext = context; } @@ -177,7 +364,9 @@ bool BTimedEventQueue::HasEvents() const { CALLED(); - return fImp->HasEvents(); + + BAutolock locker(fData->fLock); + return fData->fEventCount != 0; } @@ -185,15 +374,22 @@ int32 BTimedEventQueue::EventCount() const { CALLED(); - return fImp->EventCount(); + + BAutolock locker(fData->fLock); + return fData->fEventCount; } -const media_timed_event * +const media_timed_event* BTimedEventQueue::FirstEvent() const { CALLED(); - return fImp->FirstEvent(); + BAutolock locker(fData->fLock); + + queue_entry* entry = fData->fEvents.First(); + if (entry == NULL) + return NULL; + return &entry->event; } @@ -201,15 +397,25 @@ bigtime_t BTimedEventQueue::FirstEventTime() const { CALLED(); - return fImp->FirstEventTime(); + BAutolock locker(fData->fLock); + + queue_entry* entry = fData->fEvents.First(); + if (entry == NULL) + return B_INFINITE_TIMEOUT; + return entry->event.event_time; } -const media_timed_event * +const media_timed_event* BTimedEventQueue::LastEvent() const { CALLED(); - return fImp->LastEvent(); + BAutolock locker(fData->fLock); + + queue_entry* entry = fData->fEvents.Last(); + if (entry == NULL) + return NULL; + return &entry->event; } @@ -217,84 +423,182 @@ bigtime_t BTimedEventQueue::LastEventTime() const { CALLED(); - return fImp->LastEventTime(); + BAutolock locker(fData->fLock); + + queue_entry* entry = fData->fEvents.Last(); + if (entry == NULL) + return B_INFINITE_TIMEOUT; + return entry->event.event_time; } -const media_timed_event * +const media_timed_event* BTimedEventQueue::FindFirstMatch(bigtime_t eventTime, - time_direction direction, - bool inclusive, - int32 eventType) + time_direction direction, bool inclusive, int32 eventType) { CALLED(); - return fImp->FindFirstMatch(eventTime, direction, inclusive, eventType); + BAutolock locker(fData->fLock); + + QueueEntryList::Iterator it = fData->fEvents.GetIterator(); + while (queue_entry* entry = it.Next()) { + int match = _Match(entry->event, eventTime, direction, inclusive, eventType); + if (match == B_DONE) + break; + if (match == B_NO_ACTION) + continue; + + return &entry->event; + } + + return NULL; } status_t -BTimedEventQueue::DoForEach(for_each_hook hook, - void *context, - bigtime_t eventTime, - time_direction direction, - bool inclusive, - int32 eventType) +BTimedEventQueue::DoForEach(for_each_hook hook, void* context, + bigtime_t eventTime, time_direction direction, + bool inclusive, int32 eventType) { CALLED(); - return fImp->DoForEach(hook, context, eventTime, direction, inclusive, eventType); + BAutolock locker(fData->fLock); + + bool resort = false; + + QueueEntryList::Iterator it = fData->fEvents.GetIterator(); + while (queue_entry* entry = it.Next()) { + int match = _Match(entry->event, eventTime, direction, inclusive, eventType); + if (match == B_DONE) + break; + if (match == B_NO_ACTION) + continue; + + queue_action action = hook(&entry->event, context); + if (action == B_DONE) + break; + + switch (action) { + case B_REMOVE_EVENT: + fData->RemoveEntry(entry); + fData->CleanupAndFree(entry); + break; + + case B_RESORT_QUEUE: + resort = true; + break; + + case B_NO_ACTION: + default: + break; + } + } + + if (resort) { + QueueEntryList entries; + entries.MoveFrom(&fData->fEvents); + fData->fEventCount = 0; + + while (queue_entry* entry = entries.RemoveHead()) + fData->AddEntry(entry); + } + + return B_OK; +} + + +status_t +BTimedEventQueue::FlushEvents(bigtime_t eventTime, time_direction direction, + bool inclusive, int32 eventType) +{ + CALLED(); + BAutolock locker(fData->fLock); + + QueueEntryList::Iterator it = fData->fEvents.GetIterator(); + while (queue_entry* entry = it.Next()) { + int match = _Match(entry->event, eventTime, direction, inclusive, eventType); + if (match == B_DONE) + break; + if (match == B_NO_ACTION) + continue; + + fData->RemoveEntry(entry); + fData->CleanupAndFree(entry); + } + + return B_OK; +} + + +int +BTimedEventQueue::_Match(const media_timed_event& event, + bigtime_t eventTime, time_direction direction, + bool inclusive, int32 eventType) +{ + if (direction == B_ALWAYS) { + // Nothing to check. + } else if (direction == B_BEFORE_TIME) { + if (event.event_time > eventTime) + return B_DONE; + if (event.event_time == eventTime && !inclusive) + return B_DONE; + } else if (direction == B_AT_TIME) { + if (event.event_time > eventTime) + return B_DONE; + if (event.event_time != eventTime) + return B_NO_ACTION; + } else if (direction == B_AFTER_TIME) { + if (event.event_time < eventTime) + return B_NO_ACTION; + if (event.event_time == eventTime && !inclusive) + return B_NO_ACTION; + } + + if (eventType != B_ANY_EVENT && eventType != event.type) + return B_NO_ACTION; + + return 1; +} + + +// #pragma mark - C++ binary compatibility + + +void* +BTimedEventQueue::operator new(size_t size) +{ + CALLED(); + return ::operator new(size); } void -BTimedEventQueue::SetCleanupHook(cleanup_hook hook, - void *context) +BTimedEventQueue::operator delete(void* ptr, size_t s) { CALLED(); - fImp->SetCleanupHook(hook, context); + return ::operator delete(ptr); } -status_t -BTimedEventQueue::FlushEvents(bigtime_t eventTime, - time_direction direction, - bool inclusive, - int32 eventType) -{ - CALLED(); - return fImp->FlushEvents(eventTime, direction, inclusive, eventType); -} - -/************************************************************* - * private BTimedEventQueue - *************************************************************/ - -/* -// unimplemented -BTimedEventQueue::BTimedEventQueue(const BTimedEventQueue &other) -BTimedEventQueue &BTimedEventQueue::operator=(const BTimedEventQueue &other) -*/ - -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_0(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_1(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_2(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_3(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_4(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_5(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_6(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_7(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_8(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_9(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_10(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_11(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_12(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_13(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_14(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_15(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_16(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_17(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_18(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_19(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_20(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_21(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_22(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_23(void *, ...) { return B_ERROR; } +void BTimedEventQueue::_ReservedTimedEventQueue0() {} +void BTimedEventQueue::_ReservedTimedEventQueue1() {} +void BTimedEventQueue::_ReservedTimedEventQueue2() {} +void BTimedEventQueue::_ReservedTimedEventQueue3() {} +void BTimedEventQueue::_ReservedTimedEventQueue4() {} +void BTimedEventQueue::_ReservedTimedEventQueue5() {} +void BTimedEventQueue::_ReservedTimedEventQueue6() {} +void BTimedEventQueue::_ReservedTimedEventQueue7() {} +void BTimedEventQueue::_ReservedTimedEventQueue8() {} +void BTimedEventQueue::_ReservedTimedEventQueue9() {} +void BTimedEventQueue::_ReservedTimedEventQueue10() {} +void BTimedEventQueue::_ReservedTimedEventQueue11() {} +void BTimedEventQueue::_ReservedTimedEventQueue12() {} +void BTimedEventQueue::_ReservedTimedEventQueue13() {} +void BTimedEventQueue::_ReservedTimedEventQueue14() {} +void BTimedEventQueue::_ReservedTimedEventQueue15() {} +void BTimedEventQueue::_ReservedTimedEventQueue16() {} +void BTimedEventQueue::_ReservedTimedEventQueue17() {} +void BTimedEventQueue::_ReservedTimedEventQueue18() {} +void BTimedEventQueue::_ReservedTimedEventQueue19() {} +void BTimedEventQueue::_ReservedTimedEventQueue20() {} +void BTimedEventQueue::_ReservedTimedEventQueue21() {} +void BTimedEventQueue::_ReservedTimedEventQueue22() {} +void BTimedEventQueue::_ReservedTimedEventQueue23() {} diff --git a/src/kits/media/TimedEventQueuePrivate.cpp b/src/kits/media/TimedEventQueuePrivate.cpp deleted file mode 100644 index 75811bb7e8..0000000000 --- a/src/kits/media/TimedEventQueuePrivate.cpp +++ /dev/null @@ -1,631 +0,0 @@ -/* - * Copyright (c) 2002, 2003 Marcus Overhagen - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files or portions - * thereof (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice - * in the binary, as well as this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with - * the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -/* Implements _event_queue_imp used by BTimedEventQueue, not thread save! - */ -#include - -#include -#include -#include //defines B_DELETE -#include -#include - -#include "TimedEventQueuePrivate.h" - -#include "Debug.h" -#include "MediaDebug.h" - -_event_queue_imp::_event_queue_imp() : - fLock(new BLocker("BTimedEventQueue locker")), - fEventCount(0), - fFirstEntry(NULL), - fLastEntry(NULL), - fCleanupHookContext(NULL), - fCleanupHook(0) -{ -} - - -_event_queue_imp::~_event_queue_imp() -{ - event_queue_entry *entry; - entry = fFirstEntry; - while (entry) { - event_queue_entry *deleteme; - deleteme = entry; - entry = entry->next; - delete deleteme; - } - delete fLock; -} - - -status_t -_event_queue_imp::AddEvent(const media_timed_event &event) -{ - BAutolock lock(fLock); - -// printf(" adding %12Ld at %12Ld\n", event.event_time, system_time()); - - if (event.type <= 0) { - return B_BAD_VALUE; - } - - //create a new queue - if (fFirstEntry == NULL) { - ASSERT(fEventCount == 0); - ASSERT(fLastEntry == NULL); - fFirstEntry = fLastEntry = new event_queue_entry; - fFirstEntry->event = event; - fFirstEntry->prev = NULL; - fFirstEntry->next = NULL; - fEventCount++; - return B_OK; - } - - //insert at queue begin - if (fFirstEntry->event.event_time >= event.event_time) { - event_queue_entry *newentry = new event_queue_entry; - newentry->event = event; - newentry->prev = NULL; - newentry->next = fFirstEntry; - fFirstEntry->prev = newentry; - fFirstEntry = newentry; - fEventCount++; - return B_OK; - } - - //insert at queue end - if (fLastEntry->event.event_time <= event.event_time) { - event_queue_entry *newentry = new event_queue_entry; - newentry->event = event; - newentry->prev = fLastEntry; - newentry->next = NULL; - fLastEntry->next = newentry; - fLastEntry = newentry; - fEventCount++; - return B_OK; - } - - //insert into the queue - for (event_queue_entry *entry = fLastEntry; entry; entry = entry->prev) { - if (entry->event.event_time <= event.event_time) { - //insert after entry - event_queue_entry *newentry = new event_queue_entry; - newentry->event = event; - newentry->prev = entry; - newentry->next = entry->next; - (entry->next)->prev = newentry; - entry->next = newentry; - fEventCount++; - return B_OK; - } - } - - debugger("_event_queue_imp::AddEvent failed, should not be here\n"); - return B_OK; -} - - -status_t -_event_queue_imp::RemoveEvent(const media_timed_event *event) -{ - BAutolock lock(fLock); - - for (event_queue_entry *entry = fFirstEntry; entry; entry = entry->next) { - if (entry->event == *event) { - // No cleanup here - RemoveEntry(entry); - return B_OK; - } - } - - return B_ERROR; -} - - -status_t -_event_queue_imp::RemoveFirstEvent(media_timed_event * outEvent) -{ - BAutolock lock(fLock); - - if (fFirstEntry == 0) - return B_ERROR; - - if (outEvent != 0) { - // No cleanup here - *outEvent = fFirstEntry->event; - } else { - CleanupEvent(&fFirstEntry->event); - } - - RemoveEntry(fFirstEntry); - - return B_OK; -} - - -bool -_event_queue_imp::HasEvents() const -{ - return fEventCount != 0; -} - - -int32 -_event_queue_imp::EventCount() const -{ - #if DEBUG > 1 - Dump(); - #endif - return fEventCount; -} - - -const media_timed_event * -_event_queue_imp::FirstEvent() const -{ - return fFirstEntry ? &fFirstEntry->event : NULL; -} - - -bigtime_t -_event_queue_imp::FirstEventTime() const -{ - return fFirstEntry ? fFirstEntry->event.event_time : B_INFINITE_TIMEOUT; -} - - -const media_timed_event * -_event_queue_imp::LastEvent() const -{ - return fLastEntry ? &fLastEntry->event : NULL; -} - - -bigtime_t -_event_queue_imp::LastEventTime() const -{ - return fLastEntry ? fLastEntry->event.event_time : B_INFINITE_TIMEOUT; -} - - -const media_timed_event * -_event_queue_imp::FindFirstMatch(bigtime_t eventTime, - BTimedEventQueue::time_direction direction, - bool inclusive, - int32 eventType) -{ - event_queue_entry *end; - event_queue_entry *entry; - - BAutolock lock(fLock); - - switch (direction) { - case BTimedEventQueue::B_ALWAYS: - for (entry = fFirstEntry; entry; entry = entry->next) { - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) - return &entry->event; - } - return NULL; - - case BTimedEventQueue::B_BEFORE_TIME: - end = GetEnd_BeforeTime(eventTime, inclusive); - if (end == NULL) - return NULL; - end = end->next; - for (entry = fFirstEntry; entry != end; entry = entry->next) { - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) { - return &entry->event; - } - } - return NULL; - - case BTimedEventQueue::B_AT_TIME: - { - bool found_time = false; - for (entry = fFirstEntry; entry; entry = entry->next) { - if (eventTime == entry->event.event_time) { - found_time = true; - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) - return &entry->event; - } else if (found_time) - return NULL; - } - return NULL; - } - - case BTimedEventQueue::B_AFTER_TIME: - for (entry = GetStart_AfterTime(eventTime, inclusive); entry; entry = entry->next) { - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) { - return &entry->event; - } - } - return NULL; - } - - return NULL; -} - - -status_t -_event_queue_imp::DoForEach(BTimedEventQueue::for_each_hook hook, - void *context, - bigtime_t eventTime, - BTimedEventQueue::time_direction direction, - bool inclusive, - int32 eventType) -{ - event_queue_entry *end; - event_queue_entry *entry; - event_queue_entry *remove; - BTimedEventQueue::queue_action action; - - BAutolock lock(fLock); - - switch (direction) { - case BTimedEventQueue::B_ALWAYS: - for (entry = fFirstEntry; entry; ) { - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) { - action = (*hook)(&entry->event, context); - switch (action) { - case BTimedEventQueue::B_DONE: - return B_OK; - case BTimedEventQueue::B_REMOVE_EVENT: - CleanupEvent(&entry->event); - remove = entry; - entry = entry->next; - RemoveEntry(remove); - break; - case BTimedEventQueue::B_NO_ACTION: - case BTimedEventQueue::B_RESORT_QUEUE: - default: - entry = entry->next; - break; - } - } else { - entry = entry->next; - } - } - return B_OK; - - case BTimedEventQueue::B_BEFORE_TIME: - end = GetEnd_BeforeTime(eventTime, inclusive); - if (end == NULL) - return B_OK; - end = end->next; - for (entry = fFirstEntry; entry != end; ) { - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) { - action = (*hook)(&entry->event, context); - switch (action) { - case BTimedEventQueue::B_DONE: - return B_OK; - case BTimedEventQueue::B_REMOVE_EVENT: - CleanupEvent(&entry->event); - remove = entry; - entry = entry->next; - RemoveEntry(remove); - break; - case BTimedEventQueue::B_NO_ACTION: - case BTimedEventQueue::B_RESORT_QUEUE: - default: - entry = entry->next; - break; - } - } else { - entry = entry->next; - } - } - return B_OK; - - case BTimedEventQueue::B_AT_TIME: - { - bool found_time = false; - for (entry = fFirstEntry; entry; ) { - if (eventTime == entry->event.event_time) { - found_time = true; - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) { - action = (*hook)(&entry->event, context); - switch (action) { - case BTimedEventQueue::B_DONE: - return B_OK; - case BTimedEventQueue::B_REMOVE_EVENT: - CleanupEvent(&entry->event); - remove = entry; - entry = entry->next; - RemoveEntry(remove); - break; - case BTimedEventQueue::B_NO_ACTION: - case BTimedEventQueue::B_RESORT_QUEUE: - default: - entry = entry->next; - break; - } - } else { - entry = entry->next; - } - } else if (found_time) { - break; - } else { - entry = entry->next; - } - } - return B_OK; - } - - case BTimedEventQueue::B_AFTER_TIME: - for (entry = GetStart_AfterTime(eventTime, inclusive); entry; ) { - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) { - action = (*hook)(&entry->event, context); - switch (action) { - case BTimedEventQueue::B_DONE: - return B_OK; - case BTimedEventQueue::B_REMOVE_EVENT: - CleanupEvent(&entry->event); - remove = entry; - entry = entry->next; - RemoveEntry(remove); - break; - case BTimedEventQueue::B_NO_ACTION: - case BTimedEventQueue::B_RESORT_QUEUE: - default: - entry = entry->next; - break; - } - } else { - entry = entry->next; - } - } - return B_OK; - } - - return B_ERROR; -} - - -status_t -_event_queue_imp::FlushEvents(bigtime_t eventTime, - BTimedEventQueue::time_direction direction, - bool inclusive, - int32 eventType) -{ - event_queue_entry *end; - event_queue_entry *entry; - event_queue_entry *remove; - - BAutolock lock(fLock); - - switch (direction) { - case BTimedEventQueue::B_ALWAYS: - for (entry = fFirstEntry; entry; ) { - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) { - CleanupEvent(&entry->event); - remove = entry; - entry = entry->next; - RemoveEntry(remove); - } else { - entry = entry->next; - } - } - return B_OK; - - case BTimedEventQueue::B_BEFORE_TIME: - end = GetEnd_BeforeTime(eventTime, inclusive); - if (end == NULL) - return B_OK; - end = end->next; - for (entry = fFirstEntry; entry != end; ) { - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) { - CleanupEvent(&entry->event); - remove = entry; - entry = entry->next; - RemoveEntry(remove); - } else { - entry = entry->next; - } - } - return B_OK; - - case BTimedEventQueue::B_AT_TIME: - { - bool found_time = false; - for (entry = fFirstEntry; entry; ) { - if (eventTime == entry->event.event_time) { - found_time = true; - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) { - CleanupEvent(&entry->event); - remove = entry; - entry = entry->next; - RemoveEntry(remove); - } else { - entry = entry->next; - } - } else if (found_time) { - break; - } else { - entry = entry->next; - } - } - return B_OK; - } - - case BTimedEventQueue::B_AFTER_TIME: - for (entry = GetStart_AfterTime(eventTime, inclusive); entry; ) { - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) { - CleanupEvent(&entry->event); - remove = entry; - entry = entry->next; - RemoveEntry(remove); - } else { - entry = entry->next; - } - } - return B_OK; - } - - return B_ERROR; -} - - -void -_event_queue_imp::SetCleanupHook(BTimedEventQueue::cleanup_hook hook, void *context) -{ - BAutolock lock(fLock); - fCleanupHookContext = context; - fCleanupHook = hook; -} - - -void -_event_queue_imp::RemoveEntry(event_queue_entry *entry) -{ - //remove the entry from double-linked list - //and delete it - if (entry->prev != NULL) - (entry->prev)->next = entry->next; - if (entry->next != NULL) - (entry->next)->prev = entry->prev; - if (entry == fFirstEntry) { - fFirstEntry = entry->next; - if (fFirstEntry != NULL) - fFirstEntry->prev = NULL; - } - if (entry == fLastEntry) { - fLastEntry = entry->prev; - if (fLastEntry != NULL) - fLastEntry->next = NULL; - } - delete entry; - fEventCount--; - ASSERT(fEventCount >= 0); - ASSERT(fEventCount != 0 || ((fFirstEntry == NULL) && (fLastEntry == NULL))); -} - - -void -_event_queue_imp::CleanupEvent(media_timed_event *event) -{ - //perform the cleanup action required - //when deleting an event from the queue - - //BeBook says: - // Each event has a cleanup flag associated with it that indicates - // what sort of special action needs to be performed when the event is - // removed from the queue. If this value is B_NO_CLEANUP, nothing is done. - // If it's B_RECYCLE, and the event is a B_HANDLE_BUFFER event, BTimedEventQueue - // will automatically recycle the buffer associated with the event. - // If the cleanup flag is B_DELETE or is B_USER_CLEANUP or greater, - // the cleanup hook function will be called. - //and: - // cleanup hook function specified by hook to be called for events - // as they're removed from the queue. The hook will be called only - // for events with cleanup_flag values of B_DELETE or B_USER_CLEANUP or greater. - //and: - // These values define how BTimedEventQueue should handle removing - // events from the queue. If the flag is B_USER_CLEANUP or greater, - // the cleanup hook function is called when the event is removed. - //Problems: - // B_DELETE is a keyboard code! (seems to have existed in early - // sample code as a cleanup flag) - // - // exiting cleanup flags are: - // B_NO_CLEANUP = 0, - // B_RECYCLE_BUFFER, // recycle buffers handled by BTimedEventQueue - // B_EXPIRE_TIMER, // call TimerExpired() on the event->data - // B_USER_CLEANUP = 0x4000 // others go to the cleanup func - // - - if (event->cleanup == BTimedEventQueue::B_NO_CLEANUP) { - // do nothing - } else if (event->type == BTimedEventQueue::B_HANDLE_BUFFER - && event->cleanup == BTimedEventQueue::B_RECYCLE_BUFFER) { - ((BBuffer *)event->pointer)->Recycle(); - DEBUG_ONLY(*const_cast(&event->pointer) = NULL); - } else if (event->cleanup == BTimedEventQueue::B_EXPIRE_TIMER) { - // do nothing, called in BMediaEventLooper::DispatchEvent - } else if (event->cleanup == B_DELETE - || event->cleanup >= BTimedEventQueue::B_USER_CLEANUP) { - if (fCleanupHook) - (*fCleanupHook)(event,fCleanupHookContext); - } else { - ERROR("BTimedEventQueue cleanup unhandled! type = %" B_PRId32 - ", cleanup = %" B_PRId32 "\n", event->type, event->cleanup); - } -} - - -_event_queue_imp::event_queue_entry * -_event_queue_imp::GetEnd_BeforeTime(bigtime_t eventTime, bool inclusive) -{ - event_queue_entry *entry; - - entry = fLastEntry; - while (entry) { - if ((entry->event.event_time > eventTime) || (!inclusive && entry->event.event_time == eventTime)) - entry = entry->prev; - else - break; - } - return entry; -} - - -_event_queue_imp::event_queue_entry * -_event_queue_imp::GetStart_AfterTime(bigtime_t eventTime, bool inclusive) -{ - event_queue_entry *entry; - - entry = fFirstEntry; - while (entry) { - if ((entry->event.event_time < eventTime) || (!inclusive && entry->event.event_time == eventTime)) - entry = entry->next; - else - break; - } - return entry; -} - - -#if DEBUG > 1 -void -_event_queue_imp::Dump() const -{ - TRACE("fEventCount = %" B_PRId32 "\n", fEventCount); - TRACE("fFirstEntry = 0x%p\n", (void*)fFirstEntry); - TRACE("fLastEntry = 0x%p\n", (void*)fLastEntry); - for (event_queue_entry *entry = fFirstEntry; entry; entry = entry->next) { - TRACE("entry = 0x%p\n", (void*)entry); - TRACE(" entry.prev = 0x%p\n", (void*)entry->prev); - TRACE(" entry.next = 0x%p\n", (void*)entry->next); - TRACE(" entry.event.event_time = %" B_PRId64 "\n", - entry->event.event_time); - } -} -#endif diff --git a/src/kits/media/TimedEventQueuePrivate.h b/src/kits/media/TimedEventQueuePrivate.h deleted file mode 100644 index 871faddbbf..0000000000 --- a/src/kits/media/TimedEventQueuePrivate.h +++ /dev/null @@ -1,79 +0,0 @@ -/*********************************************************************** - * AUTHOR: Marcus Overhagen - * FILE: TimedEventQueuePrivate.cpp - * DESCR: implements _event_queue_imp used by BTimedEventQueue, - * not thread save! - ***********************************************************************/ - -#ifndef _TIMED_EVENT_QUEUE_PRIVATE_H -#define _TIMED_EVENT_QUEUE_PRIVATE_H - -#include -#include -#include "MediaDebug.h" - -struct _event_queue_imp -{ - _event_queue_imp(); - ~_event_queue_imp(); - - status_t AddEvent(const media_timed_event &event); - status_t RemoveEvent(const media_timed_event *event); - status_t RemoveFirstEvent(media_timed_event * outEvent); - - bool HasEvents() const; - int32 EventCount() const; - - const media_timed_event * FirstEvent() const; - bigtime_t FirstEventTime() const; - const media_timed_event * LastEvent() const; - bigtime_t LastEventTime() const; - - const media_timed_event * FindFirstMatch( - bigtime_t eventTime, - BTimedEventQueue::time_direction direction, - bool inclusive, - int32 eventType); - - status_t DoForEach( - BTimedEventQueue::for_each_hook hook, - void *context, - bigtime_t eventTime, - BTimedEventQueue::time_direction direction, - bool inclusive, - int32 eventType); - - void SetCleanupHook(BTimedEventQueue::cleanup_hook hook, void *context); - status_t FlushEvents( - bigtime_t eventTime, - BTimedEventQueue::time_direction direction, - bool inclusive, - int32 eventType); - -#if DEBUG > 1 - void Dump() const; -#endif - -private: - struct event_queue_entry - { - struct event_queue_entry *prev; - struct event_queue_entry *next; - media_timed_event event; - }; - - void RemoveEntry(event_queue_entry *entry); - void CleanupEvent(media_timed_event *event); - - event_queue_entry *GetEnd_BeforeTime(bigtime_t eventTime, bool inclusive); - event_queue_entry *GetStart_AfterTime(bigtime_t eventTime, bool inclusive); - - BLocker * fLock; - int32 fEventCount; - event_queue_entry *fFirstEntry; - event_queue_entry *fLastEntry; - void * fCleanupHookContext; - BTimedEventQueue::cleanup_hook fCleanupHook; -}; - -#endif //_TIMED_EVENT_QUEUE_PRIVATE_H