2013-11-29 13:18:48 +00:00
|
|
|
/*
|
|
|
|
* OpenClonk, http://www.openclonk.org
|
|
|
|
*
|
2013-12-17 20:01:09 +00:00
|
|
|
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
|
2016-04-03 18:18:29 +00:00
|
|
|
* Copyright (c) 2009-2016, The OpenClonk Team and contributors
|
2013-11-29 13:18:48 +00:00
|
|
|
*
|
2013-12-17 20:01:09 +00:00
|
|
|
* Distributed under the terms of the ISC license; see accompanying file
|
|
|
|
* "COPYING" for details.
|
2013-11-29 13:18:48 +00:00
|
|
|
*
|
2013-12-17 20:01:09 +00:00
|
|
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
|
|
|
* See accompanying file "TRADEMARK" for details.
|
2013-11-29 13:18:48 +00:00
|
|
|
*
|
2013-12-17 20:01:09 +00:00
|
|
|
* To redistribute this file separately, substitute the full license texts
|
|
|
|
* for the above references.
|
2013-11-29 13:18:48 +00:00
|
|
|
*/
|
|
|
|
#ifndef C4INTERACTIVETHREAD_H
|
|
|
|
#define C4INTERACTIVETHREAD_H
|
|
|
|
|
2016-04-03 18:07:56 +00:00
|
|
|
#include "platform/StdScheduler.h"
|
|
|
|
#include "platform/StdSync.h"
|
2013-11-29 13:18:48 +00:00
|
|
|
|
|
|
|
// Event types
|
|
|
|
enum C4InteractiveEventType
|
|
|
|
{
|
|
|
|
Ev_None = 0,
|
|
|
|
|
|
|
|
Ev_Function,
|
|
|
|
|
|
|
|
Ev_Log,
|
|
|
|
Ev_LogSilent,
|
|
|
|
Ev_LogFatal,
|
|
|
|
Ev_LogDebug,
|
|
|
|
|
|
|
|
Ev_FileChange,
|
|
|
|
|
|
|
|
Ev_HTTP_Response,
|
|
|
|
Ev_UPNP_Response,
|
|
|
|
|
|
|
|
Ev_IRC_Message,
|
|
|
|
|
|
|
|
Ev_Net_Conn,
|
|
|
|
Ev_Net_Disconn,
|
|
|
|
Ev_Net_Packet,
|
|
|
|
|
|
|
|
Ev_Last = Ev_Net_Packet
|
|
|
|
};
|
|
|
|
|
|
|
|
class C4InteractiveThreadNotifyProc : public CStdNotifyProc
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
class C4InteractiveThread *pNotify;
|
|
|
|
public:
|
|
|
|
void SetNotify(class C4InteractiveThread *pnNotify) { pNotify = pnNotify; }
|
2017-05-07 11:50:00 +00:00
|
|
|
bool Execute(int iTimeout, pollfd * readyfds) override;
|
2013-11-29 13:18:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Collects StdSchedulerProc objects and executes them in a separate thread
|
|
|
|
// Provides an event queue for the procs to communicate with the main thread
|
|
|
|
class C4InteractiveThread
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
C4InteractiveThread();
|
|
|
|
~C4InteractiveThread();
|
|
|
|
|
|
|
|
// Event callback interface
|
|
|
|
class Callback
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual void OnThreadEvent(C4InteractiveEventType eEvent, void *pEventData) = 0;
|
2017-05-07 11:50:00 +00:00
|
|
|
virtual ~Callback() = default;
|
2013-11-29 13:18:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
// the thread itself
|
|
|
|
StdSchedulerThread Scheduler;
|
|
|
|
|
|
|
|
// event queue (signals to main thread)
|
|
|
|
struct Event
|
|
|
|
{
|
|
|
|
C4InteractiveEventType Type;
|
|
|
|
void *Data;
|
|
|
|
#ifdef _DEBUG
|
2013-12-04 12:35:07 +00:00
|
|
|
C4TimeMilliseconds Time;
|
2013-11-29 13:18:48 +00:00
|
|
|
#endif
|
|
|
|
Event *Next;
|
|
|
|
};
|
|
|
|
Event *pFirstEvent, *pLastEvent;
|
|
|
|
CStdCSec EventPushCSec, EventPopCSec;
|
|
|
|
|
|
|
|
// callback objects for events of special types
|
|
|
|
Callback *pCallbacks[Ev_Last + 1];
|
|
|
|
|
|
|
|
// proc that is added to the main thread to receive messages from our thread
|
|
|
|
C4InteractiveThreadNotifyProc NotifyProc;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
// process management
|
|
|
|
bool AddProc(StdSchedulerProc *pProc);
|
|
|
|
void RemoveProc(StdSchedulerProc *pProc);
|
|
|
|
|
|
|
|
// event queue
|
2016-11-02 23:58:02 +00:00
|
|
|
bool PushEvent(C4InteractiveEventType eEventType, void *pData = nullptr);
|
2013-11-29 13:18:48 +00:00
|
|
|
void ProcessEvents(); // by main thread
|
|
|
|
|
|
|
|
// special events
|
|
|
|
bool ThreadLog(const char *szMessage, ...) GNUC_FORMAT_ATTRIBUTE_O;
|
|
|
|
bool ThreadLogFatal(const char *szMessage, ...) GNUC_FORMAT_ATTRIBUTE_O;
|
|
|
|
bool ThreadLogS(const char *szMessage, ...) GNUC_FORMAT_ATTRIBUTE_O;
|
|
|
|
bool ThreadLogDebug(const char *szMessage, ...) GNUC_FORMAT_ATTRIBUTE_O;
|
|
|
|
|
2015-09-30 00:38:15 +00:00
|
|
|
template<typename RType = void, typename Functor>
|
2013-11-29 13:18:48 +00:00
|
|
|
bool ThreadPostAsync(Functor function)
|
|
|
|
{
|
2015-09-30 00:38:15 +00:00
|
|
|
return PushEvent(Ev_Function, new std::function<RType()>(function));
|
2013-11-29 13:18:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// event handlers
|
|
|
|
void SetCallback(C4InteractiveEventType eEvent, Callback *pnNetworkCallback)
|
|
|
|
{ pCallbacks[eEvent] = pnNetworkCallback; }
|
|
|
|
void ClearCallback(C4InteractiveEventType eEvent, Callback *pnNetworkCallback)
|
2016-11-02 23:58:02 +00:00
|
|
|
{ if (pCallbacks[eEvent] == pnNetworkCallback) pCallbacks[eEvent] = nullptr; }
|
2013-11-29 13:18:48 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
bool PopEvent(C4InteractiveEventType *pEventType, void **ppData); // by main thread
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // C4INTERACTIVETHREAD_H
|