diff --git a/CMakeLists.txt b/CMakeLists.txt index cc3c5030..1c6b9b8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -174,6 +174,7 @@ add_library(NintendoSDK OBJECT include/nn/os/os_Event.h include/nn/os/os_EventCommon.h include/nn/os/os_EventTypes.h + include/nn/os/os_MessageQueue.h include/nn/util/AccessorBase.h include/nn/util/MathTypes.h include/nn/util/util_Arithmetic.h diff --git a/include/nn/os.h b/include/nn/os.h index 843d4f7a..55df73ed 100644 --- a/include/nn/os.h +++ b/include/nn/os.h @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include @@ -86,26 +86,6 @@ void AllocateMemoryBlock(u64*, u64); void FreeMemoryBlock(u64, u64); void SetMemoryHeapSize(u64); -// QUEUE -void InitializeMessageQueue(nn::os::MessageQueueType*, u64* buf, u64 queueCount); -void FinalizeMessageQueue(nn::os::MessageQueueType*); - -bool TrySendMessageQueue(MessageQueueType*, u64); -void SendMessageQueue(MessageQueueType*, u64); -bool TimedSendMessageQueue(MessageQueueType*, u64, nn::TimeSpan); - -bool TryReceiveMessageQueue(u64* out, MessageQueueType*); -void ReceiveMessageQueue(u64* out, MessageQueueType*); -bool TimedReceiveMessageQueue(u64* out, MessageQueueType*, nn::TimeSpan); - -bool TryPeekMessageQueue(u64*, MessageQueueType const*); -void PeekMessageQueue(u64*, MessageQueueType const*); -bool TimedPeekMessageQueue(u64*, MessageQueueType const*); - -bool TryJamMessageQueue(nn::os::MessageQueueType*, u64); -void JamMessageQueue(nn::os::MessageQueueType*, u64); -bool TimedJamMessageQueue(nn::os::MessageQueueType*, u64, nn::TimeSpan); - // CONDITION VARIABLE void InitializeConditionVariable(ConditionVariableType*); void FinalizeConditionVariable(ConditionVariableType*); diff --git a/include/nn/os/os_MessageQueue.h b/include/nn/os/os_MessageQueue.h new file mode 100644 index 00000000..56e31a01 --- /dev/null +++ b/include/nn/os/os_MessageQueue.h @@ -0,0 +1,83 @@ +#pragma once + +#include +#include +#include + +namespace nn::os { + +void InitializeMessageQueue(nn::os::MessageQueueType*, u64* buf, u64 queueCount); +void FinalizeMessageQueue(nn::os::MessageQueueType*); + +void SendMessageQueue(MessageQueueType*, u64); +bool TrySendMessageQueue(MessageQueueType*, u64); +bool TimedSendMessageQueue(MessageQueueType*, u64, nn::TimeSpan); + +void ReceiveMessageQueue(u64* out, MessageQueueType*); +bool TryReceiveMessageQueue(u64* out, MessageQueueType*); +bool TimedReceiveMessageQueue(u64* out, MessageQueueType*, nn::TimeSpan); + +void PeekMessageQueue(u64*, const MessageQueueType*); +bool TryPeekMessageQueue(u64*, const MessageQueueType*); +bool TimedPeekMessageQueue(u64*, const MessageQueueType*, nn::TimeSpan); + +void JamMessageQueue(nn::os::MessageQueueType*, u64); +bool TryJamMessageQueue(nn::os::MessageQueueType*, u64); +bool TimedJamMessageQueue(nn::os::MessageQueueType*, u64, nn::TimeSpan); + +class MessageQueue { + NN_NO_COPY(MessageQueue); + NN_NO_MOVE(MessageQueue); + +public: + MessageQueue(uintptr_t* buffer, size_t count) { + InitializeMessageQueue(&m_MessageQueue, buffer, count); + } + + ~MessageQueue() { FinalizeMessageQueue(&m_MessageQueue); } + + void Send(uintptr_t data) { SendMessageQueue(&m_MessageQueue, data); } + + bool TrySend(uintptr_t data) { return TrySendMessageQueue(&m_MessageQueue, data); } + + bool TimedSend(uintptr_t data, TimeSpan timeSpan) { + return TimedSendMessageQueue(&m_MessageQueue, data, timeSpan); + } + + void Jam(uintptr_t data) { JamMessageQueue(&m_MessageQueue, data); } + + bool TryJam(uintptr_t data) { return TryJamMessageQueue(&m_MessageQueue, data); } + + bool TimedJam(uintptr_t data, TimeSpan timeSpan) { + return TimedJamMessageQueue(&m_MessageQueue, data, timeSpan); + } + + void Receive(uintptr_t* outData) { ReceiveMessageQueue(outData, &m_MessageQueue); } + + bool TryReceive(uintptr_t* outData) { return TryReceiveMessageQueue(outData, &m_MessageQueue); } + + bool TimedReceive(uintptr_t* outData, TimeSpan timeSpan) { + return TimedReceiveMessageQueue(outData, &m_MessageQueue, timeSpan); + } + + /// XXX: `Peek` functions could be `const`, but according to DWARF from BTD5, they + /// are not + void Peek(uintptr_t* outData) { PeekMessageQueue(outData, &m_MessageQueue); } + + bool TryPeek(uintptr_t* outData) { return TryPeekMessageQueue(outData, &m_MessageQueue); } + + bool TimedPeek(uintptr_t* outData, TimeSpan timeSpan) { + return TimedPeekMessageQueue(outData, &m_MessageQueue, timeSpan); + } + + operator MessageQueueType&() { return m_MessageQueue; } + + operator const MessageQueueType&() const { return m_MessageQueue; } + + MessageQueueType* GetBase() { return &m_MessageQueue; } + +private: + MessageQueueType m_MessageQueue; +}; + +} // namespace nn::os