144 lines
4 KiB
C++
144 lines
4 KiB
C++
/*
|
|
*******************************************************************************
|
|
* INCLUDE
|
|
*******************************************************************************
|
|
*/
|
|
#include "Broadcast.h"
|
|
#include <Poco/Mutex.h>
|
|
#include <Poco/ScopedLock.h>
|
|
|
|
namespace Util
|
|
{
|
|
/*
|
|
*******************************************************************************
|
|
* CLASS DEFINE
|
|
*******************************************************************************
|
|
*/
|
|
class BroadcastObserver
|
|
{
|
|
public:
|
|
BroadcastObserver(BroadcastReceiver& receiver, IntentFilter::Ptr pFilter): _pReceiver(&receiver), _pFilter(pFilter)
|
|
{
|
|
}
|
|
|
|
void broadcast(Intent::Ptr pIntent)
|
|
{
|
|
if (_pFilter->match(pIntent))
|
|
_pReceiver->onReceive(pIntent);
|
|
}
|
|
|
|
bool equals(const BroadcastObserver& observer)
|
|
{
|
|
return _pReceiver == observer._pReceiver;
|
|
}
|
|
|
|
bool isBoundTo(BroadcastReceiver& receiver)
|
|
{
|
|
return _pReceiver == &receiver;
|
|
}
|
|
|
|
private:
|
|
BroadcastReceiver* _pReceiver;
|
|
IntentFilter::Ptr _pFilter;
|
|
};
|
|
|
|
class BroadcastCore
|
|
{
|
|
public:
|
|
void sendBroadcast(Intent::Ptr pIntent)
|
|
{
|
|
Poco::ScopedLockWithUnlock<Poco::Mutex> lock(_mutex);
|
|
BroadcastObserverList list(_broadcastObservers);
|
|
lock.unlock();
|
|
for (auto& p : list)
|
|
p->broadcast(pIntent);
|
|
}
|
|
|
|
void registerReceiver(BroadcastReceiver& receiver, IntentFilter::Ptr pFilter)
|
|
{
|
|
Poco::Mutex::ScopedLock lock(_mutex);
|
|
for (auto& obs : _broadcastObservers)
|
|
{
|
|
if (obs->isBoundTo(receiver))
|
|
return;
|
|
}
|
|
|
|
_broadcastObservers.push_back(new BroadcastObserver(receiver, pFilter));
|
|
}
|
|
|
|
void unregisterReceiver(BroadcastReceiver& receiver)
|
|
{
|
|
Poco::Mutex::ScopedLock lock(_mutex);
|
|
for (BroadcastObserverList::iterator it = _broadcastObservers.begin(); it != _broadcastObservers.end();)
|
|
{
|
|
if ((*it)->isBoundTo(receiver))
|
|
it = _broadcastObservers.erase(it);
|
|
else
|
|
++it;
|
|
}
|
|
}
|
|
|
|
private:
|
|
using BroadcastObserverPtr = Poco::SharedPtr<BroadcastObserver>;
|
|
using BroadcastObserverList = std::vector<BroadcastObserverPtr>;
|
|
|
|
BroadcastObserverList _broadcastObservers;
|
|
mutable Poco::Mutex _mutex;
|
|
};
|
|
|
|
/*
|
|
*******************************************************************************
|
|
* CLASS DEFINE
|
|
*******************************************************************************
|
|
*/
|
|
Intent& Intent::putExtra(const std::string& key, const char* value)
|
|
{
|
|
return putExtra(key, std::string(value));
|
|
}
|
|
|
|
/*
|
|
*******************************************************************************
|
|
* CLASS DEFINE
|
|
*******************************************************************************
|
|
*/
|
|
void IntentFilter::addAction(const std::string& action)
|
|
{
|
|
_actions.push_back(action);
|
|
}
|
|
|
|
bool IntentFilter::match(Intent::Ptr pIntent) const
|
|
{
|
|
const std::string& target = pIntent->getAction();
|
|
return std::find(_actions.begin(), _actions.end(), target) != _actions.end();
|
|
}
|
|
|
|
/*
|
|
*******************************************************************************
|
|
* LOCAL VARIABLES
|
|
*******************************************************************************
|
|
*/
|
|
namespace
|
|
{
|
|
static BroadcastCore core;
|
|
}
|
|
|
|
/*
|
|
*******************************************************************************
|
|
* CLASS DEFINE
|
|
*******************************************************************************
|
|
*/
|
|
void BroadcastSender::sendBroadcast(Intent::Ptr pIntent)
|
|
{
|
|
core.sendBroadcast(pIntent);
|
|
}
|
|
|
|
void BroadcastReceiverRegistry::registerReceiver(BroadcastReceiver& receiver, IntentFilter::Ptr pFilter)
|
|
{
|
|
core.registerReceiver(receiver, pFilter);
|
|
}
|
|
|
|
void BroadcastReceiverRegistry::unregisterReceiver(BroadcastReceiver& receiver)
|
|
{
|
|
core.unregisterReceiver(receiver);
|
|
}
|
|
}
|