#ifndef EventSender_h
#define EventSender_h
#include "platform/Timer.h"
#include "wtf/Vector.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
template<typename T> class EventSender {
WTF_MAKE_NONCOPYABLE(EventSender); WTF_MAKE_FAST_ALLOCATED;
public:
explicit EventSender(const AtomicString& eventType);
const AtomicString& eventType() const { return m_eventType; }
void dispatchEventSoon(T*);
void cancelEvent(T*);
void dispatchPendingEvents();
#ifndef NDEBUG
bool hasPendingEvents(T* sender) const
{
return m_dispatchSoonList.find(sender) != kNotFound || m_dispatchingList.find(sender) != kNotFound;
}
#endif
private:
void timerFired(Timer<EventSender<T> >*) { dispatchPendingEvents(); }
AtomicString m_eventType;
Timer<EventSender<T> > m_timer;
Vector<T*> m_dispatchSoonList;
Vector<T*> m_dispatchingList;
};
template<typename T> EventSender<T>::EventSender(const AtomicString& eventType)
: m_eventType(eventType)
, m_timer(this, &EventSender::timerFired)
{
}
template<typename T> void EventSender<T>::dispatchEventSoon(T* sender)
{
m_dispatchSoonList.append(sender);
if (!m_timer.isActive())
m_timer.startOneShot(0, FROM_HERE);
}
template<typename T> void EventSender<T>::cancelEvent(T* sender)
{
size_t size = m_dispatchSoonList.size();
for (size_t i = 0; i < size; ++i) {
if (m_dispatchSoonList[i] == sender)
m_dispatchSoonList[i] = 0;
}
size = m_dispatchingList.size();
for (size_t i = 0; i < size; ++i) {
if (m_dispatchingList[i] == sender)
m_dispatchingList[i] = 0;
}
}
template<typename T> void EventSender<T>::dispatchPendingEvents()
{
if (!m_dispatchingList.isEmpty())
return;
m_timer.stop();
m_dispatchingList.swap(m_dispatchSoonList);
size_t size = m_dispatchingList.size();
for (size_t i = 0; i < size; ++i) {
if (T* sender = m_dispatchingList[i]) {
m_dispatchingList[i] = 0;
sender->dispatchPendingEvent(this);
}
}
m_dispatchingList.clear();
}
}
#endif