deskflow/src/lib/base/EventQueue.h

194 lines
5.7 KiB
C
Raw Normal View History

2012-06-10 16:50:54 +00:00
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012 Synergy Si Ltd.
* Copyright (C) 2004 Chris Schoeneman
2012-06-10 16:50:54 +00:00
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
2012-06-10 16:50:54 +00:00
#include "mt/CondVar.h"
#include "arch/IArchMultithread.h"
#include "base/IEventQueue.h"
#include "base/Event.h"
#include "base/PriorityQueue.h"
#include "base/Stopwatch.h"
#include "common/stdmap.h"
#include "common/stdset.h"
2012-06-10 16:50:54 +00:00
#include <queue>
2014-11-11 13:51:47 +00:00
class Mutex;
2012-06-10 16:50:54 +00:00
//! Event queue
/*!
An event queue that implements the platform independent parts and
delegates the platform dependent parts to a subclass.
*/
2014-11-11 13:51:47 +00:00
class EventQueue : public IEventQueue {
2012-06-10 16:50:54 +00:00
public:
2014-11-11 13:51:47 +00:00
EventQueue();
virtual ~EventQueue();
2012-06-10 16:50:54 +00:00
// IEventQueue overrides
virtual void loop();
2012-06-10 16:50:54 +00:00
virtual void adoptBuffer(IEventQueueBuffer*);
2014-11-11 13:51:47 +00:00
virtual bool getEvent(Event& event, double timeout = -1.0);
virtual bool dispatchEvent(const Event& event);
virtual void addEvent(const Event& event);
virtual EventQueueTimer*
2012-06-10 16:50:54 +00:00
newTimer(double duration, void* target);
2014-11-11 13:51:47 +00:00
virtual EventQueueTimer*
2012-06-10 16:50:54 +00:00
newOneShotTimer(double duration, void* target);
2014-11-11 13:51:47 +00:00
virtual void deleteTimer(EventQueueTimer*);
virtual void adoptHandler(Event::Type type,
2012-06-10 16:50:54 +00:00
void* target, IEventJob* handler);
2014-11-11 13:51:47 +00:00
virtual void removeHandler(Event::Type type, void* target);
2012-06-10 16:50:54 +00:00
virtual void removeHandlers(void* target);
2014-11-11 13:51:47 +00:00
virtual Event::Type
registerTypeOnce(Event::Type& type, const char* name);
2012-06-10 16:50:54 +00:00
virtual bool isEmpty() const;
2014-11-11 13:51:47 +00:00
virtual IEventJob* getHandler(Event::Type type, void* target) const;
virtual const char* getTypeName(Event::Type type);
virtual Event::Type
getRegisteredType(const String& name) const;
void* getSystemTarget();
virtual void waitForReady() const;
2012-06-10 16:50:54 +00:00
private:
2014-11-11 13:51:47 +00:00
UInt32 saveEvent(const Event& event);
Event removeEvent(UInt32 eventID);
bool hasTimerExpired(Event& event);
2012-06-10 16:50:54 +00:00
double getNextTimerTimeout() const;
2014-11-11 13:51:47 +00:00
void addEventToBuffer(const Event& event);
2012-06-10 16:50:54 +00:00
private:
2014-11-11 13:51:47 +00:00
class Timer {
2012-06-10 16:50:54 +00:00
public:
2014-11-11 13:51:47 +00:00
Timer(EventQueueTimer*, double timeout, double initialTime,
2012-06-10 16:50:54 +00:00
void* target, bool oneShot);
2014-11-11 13:51:47 +00:00
~Timer();
2012-06-10 16:50:54 +00:00
void reset();
2014-11-11 13:51:47 +00:00
Timer& operator-=(double);
2012-06-10 16:50:54 +00:00
operator double() const;
bool isOneShot() const;
2014-11-11 13:51:47 +00:00
EventQueueTimer*
2012-06-10 16:50:54 +00:00
getTimer() const;
void* getTarget() const;
2014-11-11 13:51:47 +00:00
void fillEvent(TimerEvent&) const;
2012-06-10 16:50:54 +00:00
2014-11-11 13:51:47 +00:00
bool operator<(const Timer&) const;
2012-06-10 16:50:54 +00:00
private:
2014-11-11 13:51:47 +00:00
EventQueueTimer* m_timer;
2012-06-10 16:50:54 +00:00
double m_timeout;
void* m_target;
bool m_oneShot;
double m_time;
};
2014-11-11 13:51:47 +00:00
typedef std::set<EventQueueTimer*> Timers;
typedef PriorityQueue<Timer> TimerQueue;
typedef std::map<UInt32, Event> EventTable;
typedef std::vector<UInt32> EventIDList;
typedef std::map<Event::Type, const char*> TypeMap;
typedef std::map<String, Event::Type> NameMap;
typedef std::map<Event::Type, IEventJob*> TypeHandlerTable;
typedef std::map<void*, TypeHandlerTable> HandlerTable;
2012-06-10 16:50:54 +00:00
int m_systemTarget;
2014-11-11 13:51:47 +00:00
ArchMutex m_mutex;
2012-06-10 16:50:54 +00:00
// registered events
2014-11-11 13:51:47 +00:00
Event::Type m_nextType;
TypeMap m_typeMap;
NameMap m_nameMap;
2012-06-10 16:50:54 +00:00
// buffer of events
IEventQueueBuffer* m_buffer;
// saved events
2014-11-11 13:51:47 +00:00
EventTable m_events;
EventIDList m_oldEventIDs;
2012-06-10 16:50:54 +00:00
// timers
2014-11-11 13:51:47 +00:00
Stopwatch m_time;
Timers m_timers;
TimerQueue m_timerQueue;
TimerEvent m_timerEvent;
2012-06-10 16:50:54 +00:00
// event handlers
2014-11-11 13:51:47 +00:00
HandlerTable m_handlers;
public:
//
// Event type providers.
//
2014-11-11 13:51:47 +00:00
ClientEvents& forClient();
IStreamEvents& forIStream();
2014-11-11 13:51:47 +00:00
IpcClientEvents& forIpcClient();
IpcClientProxyEvents& forIpcClientProxy();
IpcServerEvents& forIpcServer();
IpcServerProxyEvents& forIpcServerProxy();
IDataSocketEvents& forIDataSocket();
IListenSocketEvents& forIListenSocket();
ISocketEvents& forISocket();
2014-11-11 13:51:47 +00:00
OSXScreenEvents& forOSXScreen();
ClientListenerEvents& forClientListener();
ClientProxyEvents& forClientProxy();
ClientProxyUnknownEvents& forClientProxyUnknown();
ServerEvents& forServer();
ServerAppEvents& forServerApp();
IKeyStateEvents& forIKeyState();
IPrimaryScreenEvents& forIPrimaryScreen();
IScreenEvents& forIScreen();
private:
2014-11-11 13:51:47 +00:00
ClientEvents* m_typesForClient;
IStreamEvents* m_typesForIStream;
2014-11-11 13:51:47 +00:00
IpcClientEvents* m_typesForIpcClient;
IpcClientProxyEvents* m_typesForIpcClientProxy;
IpcServerEvents* m_typesForIpcServer;
IpcServerProxyEvents* m_typesForIpcServerProxy;
IDataSocketEvents* m_typesForIDataSocket;
IListenSocketEvents* m_typesForIListenSocket;
ISocketEvents* m_typesForISocket;
2014-11-11 13:51:47 +00:00
OSXScreenEvents* m_typesForOSXScreen;
ClientListenerEvents* m_typesForClientListener;
ClientProxyEvents* m_typesForClientProxy;
ClientProxyUnknownEvents* m_typesForClientProxyUnknown;
ServerEvents* m_typesForServer;
ServerAppEvents* m_typesForServerApp;
IKeyStateEvents* m_typesForIKeyState;
IPrimaryScreenEvents* m_typesForIPrimaryScreen;
IScreenEvents* m_typesForIScreen;
2014-11-11 13:51:47 +00:00
Mutex* m_readyMutex;
CondVar<bool>* m_readyCondVar;
std::queue<Event> m_pending;
2012-06-10 16:50:54 +00:00
};
#define EVENT_TYPE_ACCESSOR(type_) \
type_##Events& \
2014-11-11 13:51:47 +00:00
EventQueue::for##type_() { \
if (m_typesFor##type_ == NULL) { \
m_typesFor##type_ = new type_##Events(); \
m_typesFor##type_->setEvents(dynamic_cast<IEventQueue*>(this)); \
} \
return *m_typesFor##type_; \
}