#pragma once
#include "env.h"
#include "p8-platform/threads/mutex.h"
#include "p8-platform/util/buffer.h"
namespace CEC
{
class CCECInputBuffer
{
public:
CCECInputBuffer(void) : m_bHasData(false) {}
virtual ~CCECInputBuffer(void)
{
Broadcast();
}
void Broadcast(void)
{
P8PLATFORM::CLockObject lock(m_mutex);
m_bHasData = true;
m_condition.Broadcast();
}
bool Push(const cec_command &command)
{
bool bReturn(false);
P8PLATFORM::CLockObject lock(m_mutex);
if (command.initiator == CECDEVICE_TV)
bReturn = m_tvInBuffer.Push(command);
else
bReturn = m_inBuffer.Push(command);
m_bHasData |= bReturn;
if (m_bHasData)
m_condition.Signal();
return bReturn;
}
bool Pop(cec_command &command, uint16_t iTimeout)
{
bool bReturn(false);
P8PLATFORM::CLockObject lock(m_mutex);
if (m_tvInBuffer.IsEmpty() && m_inBuffer.IsEmpty() &&
!m_condition.Wait(m_mutex, m_bHasData, iTimeout))
return bReturn;
if (m_tvInBuffer.Pop(command))
bReturn = true;
else if (m_inBuffer.Pop(command))
bReturn = true;
m_bHasData = !m_tvInBuffer.IsEmpty() || !m_inBuffer.IsEmpty();
return bReturn;
}
private:
P8PLATFORM::CMutex m_mutex;
P8PLATFORM::CCondition<volatile bool> m_condition;
volatile bool m_bHasData;
P8PLATFORM::SyncedBuffer<cec_command> m_tvInBuffer;
P8PLATFORM::SyncedBuffer<cec_command> m_inBuffer;
};
};