|
| 1 | +#include <mutex> |
| 2 | +#include <vector> |
| 3 | + |
| 4 | +#include "ultramodern/extensions.h" |
| 5 | +#include "ultramodern/ultramodern.hpp" |
| 6 | + |
| 7 | +struct DLEvent { |
| 8 | + PTR(OSMesgQueue) mq; |
| 9 | + OSMesg mesg; |
| 10 | + PTR(void) displaylist; |
| 11 | + u32 event_type; |
| 12 | +}; |
| 13 | + |
| 14 | +struct { |
| 15 | + struct { |
| 16 | + std::mutex dl_event_mutex; |
| 17 | + std::vector<DLEvent> pending_events; |
| 18 | + } dl_events; |
| 19 | +} extension_state; |
| 20 | + |
| 21 | +extern "C" void osExQueueDisplaylistEvent(PTR(OSMesgQueue) mq, OSMesg mesg, PTR(void) displaylist, u32 event_type) { |
| 22 | + std::lock_guard lock{ extension_state.dl_events.dl_event_mutex }; |
| 23 | + |
| 24 | + assert( |
| 25 | + event_type == OS_EX_DISPLAYLIST_EVENT_SUBMITTED || |
| 26 | + event_type == OS_EX_DISPLAYLIST_EVENT_PARSED || |
| 27 | + event_type == OS_EX_DISPLAYLIST_EVENT_COMPLETED); |
| 28 | + |
| 29 | + extension_state.dl_events.pending_events.emplace_back( |
| 30 | + DLEvent{ mq, mesg, displaylist, event_type } |
| 31 | + ); |
| 32 | +} |
| 33 | + |
| 34 | +void dispatch_displaylist_events(PTR(void) displaylist, u32 event_type) { |
| 35 | + std::lock_guard lock{ extension_state.dl_events.dl_event_mutex }; |
| 36 | + |
| 37 | + // Check every pending DL event to see if they match this displaylist and event type. |
| 38 | + for (auto iter = extension_state.dl_events.pending_events.begin(); iter != extension_state.dl_events.pending_events.end(); ) { |
| 39 | + if (iter->displaylist == displaylist && iter->event_type == event_type) { |
| 40 | + // Send the provided message to the corresponding message queue for this event, then remove this event from the queue. |
| 41 | + ultramodern::enqueue_external_message(iter->mq, iter->mesg, false, true); |
| 42 | + iter = extension_state.dl_events.pending_events.erase(iter); |
| 43 | + } |
| 44 | + else { |
| 45 | + ++iter; |
| 46 | + } |
| 47 | + } |
| 48 | +} |
| 49 | + |
| 50 | +void ultramodern::extensions::on_displaylist_submitted(PTR(void) displaylist) { |
| 51 | + dispatch_displaylist_events(displaylist, OS_EX_DISPLAYLIST_EVENT_SUBMITTED); |
| 52 | +} |
| 53 | + |
| 54 | +void ultramodern::extensions::on_displaylist_parsed(PTR(void) displaylist) { |
| 55 | + dispatch_displaylist_events(displaylist, OS_EX_DISPLAYLIST_EVENT_PARSED); |
| 56 | +} |
| 57 | + |
| 58 | +void ultramodern::extensions::on_displaylist_completed(PTR(void) displaylist) { |
| 59 | + dispatch_displaylist_events(displaylist, OS_EX_DISPLAYLIST_EVENT_COMPLETED); |
| 60 | +} |
0 commit comments