mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
340 lines
6.6 KiB
C++
340 lines
6.6 KiB
C++
#pragma once
|
|
|
|
#ifndef BP_NOINC
|
|
#include "../Common.h"
|
|
#include "CritSect.h"
|
|
#endif
|
|
|
|
#include "Dictionary.h"
|
|
#include "TLSingleton.h"
|
|
|
|
#ifdef BF_PLATFORM_WINDOWS
|
|
#include <winsock.h>
|
|
#else
|
|
#include <sys/types.h> /* See NOTES */
|
|
#include <sys/socket.h>
|
|
typedef int SOCKET;
|
|
#endif
|
|
|
|
enum BpConnectState
|
|
{
|
|
BpConnectState_NotConnected,
|
|
BpConnectState_Connecting,
|
|
BpConnectState_Connected,
|
|
BpConnectState_Failed
|
|
};
|
|
|
|
#ifndef BP_DISABLED
|
|
|
|
NS_BF_BEGIN
|
|
|
|
class Buffer
|
|
{
|
|
public:
|
|
uint8* mPtr;
|
|
int mBufSize;
|
|
int mDataSize;
|
|
|
|
public:
|
|
Buffer();
|
|
~Buffer();
|
|
uint8* Alloc(int size);
|
|
void Free();
|
|
void Clear();
|
|
};
|
|
|
|
class CircularBuffer
|
|
{
|
|
public:
|
|
// Either points to an internal segment of the CircularBuffer, or if the range is discontinuous then
|
|
// it presents a temporary pointer that is later committed
|
|
class View
|
|
{
|
|
public:
|
|
uint8* mPtr;
|
|
int mSrcIdx;
|
|
int mSrcSize;
|
|
uint8* mTempBuf;
|
|
int mTempBufSize;
|
|
|
|
CircularBuffer* mCircularBuffer;
|
|
|
|
public:
|
|
View();
|
|
~View();
|
|
|
|
void Commit(int size = -1);
|
|
};
|
|
|
|
public:
|
|
uint8* mBuffer;
|
|
int mTail;
|
|
int mDataSize;
|
|
int mBufSize;
|
|
|
|
public:
|
|
CircularBuffer();
|
|
~CircularBuffer();
|
|
|
|
void Clear();
|
|
void Resize(int newSize);
|
|
void GrowReserve(int addSize);
|
|
void Grow(int addSize);
|
|
void GrowFront(int addSize);
|
|
int GetSize();
|
|
void MapView(int idx, int len, View& view);
|
|
void Read(void* ptr, int idx, int len);
|
|
void Write(void* ptr, int idx, int len);
|
|
|
|
void RemoveFront(int len);
|
|
};
|
|
|
|
class BpContext
|
|
{
|
|
|
|
};
|
|
|
|
enum BpResult
|
|
{
|
|
BpResult_Ok = 0,
|
|
BpResult_InternalError,
|
|
BpResult_AlreadyInitialized
|
|
};
|
|
|
|
#define BP_CHUNKSIZE 4096
|
|
#define BP_NUMCHUNKS 8
|
|
|
|
#define BP_CLIENT_VERSION 2
|
|
|
|
enum BpCmd
|
|
{
|
|
BpCmd_Init,
|
|
BpCmd_Enter,
|
|
BpCmd_EnterDyn,
|
|
BpCmd_Leave,
|
|
BpCmd_LODSmallEntry,
|
|
BpCmd_StrEntry,
|
|
BpCmd_ThreadAdd,
|
|
BpCmd_ThreadRemove,
|
|
BpCmd_SetThread,
|
|
BpCmd_ThreadName,
|
|
BpCmd_Tick,
|
|
BpCmd_PrevTick,
|
|
BpCmd_KeepAlive,
|
|
BpCmd_ClockInfo,
|
|
BpCmd_StreamSplitInfo,
|
|
BpCmd_Event,
|
|
BpCmd_LODEvent,
|
|
BpCmd_Cmd
|
|
};
|
|
|
|
class BpCmdTarget
|
|
{
|
|
public:
|
|
CritSect mCritSect;
|
|
Buffer mOutBuffer;
|
|
char* mThreadName;
|
|
|
|
int mCurDynStrIdx;
|
|
const char* mDynStrs[64];
|
|
|
|
int mCurDepth;
|
|
|
|
public:
|
|
BpCmdTarget();
|
|
void Disable();
|
|
// Note: returned "const char*" is actually an index into a temporary string table
|
|
const char* DynamicString(const char* str);
|
|
const char* ToStrPtr(const char* str);
|
|
|
|
void Enter(const char* name);
|
|
void Enter(const char* name, va_list vargs);
|
|
void EnterF(const char* name, ...);
|
|
void Leave();
|
|
|
|
void Event(const char* name, const char* details);
|
|
};
|
|
|
|
class BpRootCmdTarget : public BpCmdTarget
|
|
{
|
|
public:
|
|
void Init();
|
|
void Tick();
|
|
void KeepAlive();
|
|
void AddThread(int threadId, BfpThreadId nativeThreadId);
|
|
};
|
|
|
|
class BpThreadInfo : public BpCmdTarget
|
|
{
|
|
public:
|
|
BfpThreadId mNativeThreadId;
|
|
int mThreadId;
|
|
bool mReadyToSend;
|
|
bool mHasTerminated;
|
|
|
|
public:
|
|
BpThreadInfo();
|
|
~BpThreadInfo();
|
|
void SetThreadName(const char* name);
|
|
void RemoveThread();
|
|
};
|
|
|
|
struct BpZoneName
|
|
{
|
|
public:
|
|
int mIdx;
|
|
int mSize;
|
|
};
|
|
|
|
class BpManager
|
|
{
|
|
public:
|
|
#ifdef BF_PLATFORM_WINDOWS
|
|
HANDLE mMutex;
|
|
HANDLE mSharedMemoryFile;
|
|
#endif
|
|
SOCKET mSocket;
|
|
BfpThread* mThread;
|
|
BfpThreadId mThreadId;
|
|
String mServerName;
|
|
String mSessionName;
|
|
String mSessionID;
|
|
BpRootCmdTarget mRootCmdTarget;
|
|
BpConnectState mConnectState;
|
|
SyncEvent mShutdownEvent;
|
|
CritSect mCritSect;
|
|
Array<BpThreadInfo*> mThreadInfos;
|
|
String mClientName;
|
|
TLSDtor mTLSDtor;
|
|
bool mCollectData;
|
|
bool mThreadRunning;
|
|
int64 mInitTimeStamp;
|
|
uint mInitTickCount;
|
|
int mPauseCount;
|
|
int mInitCount;
|
|
|
|
CircularBuffer mOutBuffer;
|
|
int mOutBlockSizeLeft;
|
|
int mCurThreadId;
|
|
|
|
Dictionary<const char*, BpZoneName> mZoneNameMap;
|
|
|
|
BF_TLS_DECLSPEC static BpThreadInfo* sBpThreadInfo;
|
|
static BpManager* sBpManager;
|
|
|
|
int64 mCurTick;
|
|
|
|
protected:
|
|
bool Connect();
|
|
void FinishWorkThread();
|
|
void ThreadProc();
|
|
static void BFP_CALLTYPE ThreadProcThunk(void* ptr);
|
|
uint8* StartCmd(uint8 cmd, CircularBuffer::View& view, int maxLen);
|
|
void EndCmd(CircularBuffer::View& view, uint8* ptr);
|
|
void TrySendData();
|
|
void LostConnection();
|
|
virtual BpThreadInfo* SlowGetCurThreadInfo();
|
|
|
|
public:
|
|
virtual void* AllocBytes(int size);
|
|
virtual void FreeBytes(void*);
|
|
|
|
public:
|
|
BpManager();
|
|
~BpManager();
|
|
|
|
void Clear();
|
|
|
|
void SetClientName(const StringImpl& clientName);
|
|
BpResult Init(const char* serverName, const char* sessionName);
|
|
void RetryConnect();
|
|
void Pause();
|
|
void Unpause();
|
|
void Shutdown();
|
|
bool IsDisconnected();
|
|
|
|
BpContext* CreateContext(const char* name);
|
|
void CloseContext();
|
|
void Tick();
|
|
|
|
static BpThreadInfo* GetCurThreadInfo();
|
|
static BpManager* Get();
|
|
};
|
|
|
|
NS_BF_END
|
|
|
|
class BpAutoZone
|
|
{
|
|
public:
|
|
BpAutoZone(const char* name)
|
|
{
|
|
Beefy::BpManager::GetCurThreadInfo()->Enter(name);
|
|
}
|
|
|
|
~BpAutoZone()
|
|
{
|
|
Beefy::BpManager::sBpThreadInfo->Leave();
|
|
}
|
|
};
|
|
|
|
class BpAutoZoneF
|
|
{
|
|
public:
|
|
BpAutoZoneF(const char* name, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, name);
|
|
Beefy::BpManager::GetCurThreadInfo()->Enter(name, args);
|
|
}
|
|
|
|
~BpAutoZoneF()
|
|
{
|
|
Beefy::BpManager::sBpThreadInfo->Leave();
|
|
}
|
|
};
|
|
|
|
#define BP_ENTER(zoneName) BpEnter(name)
|
|
|
|
#define BP_DYN_STR(str) BpDynStr(str)
|
|
|
|
// We purposely 'incorrectly' define BP_ZONE as a variadic macro so compilation will fail rather than warn if we attempt to add params
|
|
#define BP_TOKENPASTE(x, y) x ## y
|
|
#define BP_TOKENPASTE2(x, y) BP_TOKENPASTE(x, y)
|
|
|
|
#define BP_ZONE(zoneName, ...) BpAutoZone BP_TOKENPASTE2(bpZone_, __COUNTER__)(zoneName, ##__VA_ARGS__)
|
|
#define BP_ZONE_F(zoneName, ...) BpAutoZoneF BP_TOKENPASTE2(bpZone_, __COUNTER__)(zoneName, ##__VA_ARGS__)
|
|
#define BP_SHUTDOWN() BpShutdown()
|
|
|
|
#else
|
|
|
|
#define BP_ENTER(zoneName) do { } while (0)
|
|
#define BP_DYN_STR(str) str
|
|
|
|
#define BP_ZONE(zoneName, ...) do { } while (0)
|
|
#define BP_ZONE_F(zoneName, ...) do { } while (0)
|
|
#define BP_SHUTDOWN() do { } while (0)
|
|
|
|
#endif
|
|
|
|
#if (defined BP_DYNAMIC) || (!defined BF_PLATFORM_WINDOWS)
|
|
#define BP_EXPORT BF_EXPORT
|
|
#define BP_CALLTYPE BF_CALLTYPE
|
|
#else
|
|
#define BP_EXPORT extern "C"
|
|
#define BP_CALLTYPE
|
|
#endif
|
|
|
|
BP_EXPORT void BP_CALLTYPE BpInit(const char* serverName, const char* sessionName);
|
|
BP_EXPORT void BP_CALLTYPE BpShutdown();
|
|
BP_EXPORT BpConnectState BP_CALLTYPE BpGetConnectState();
|
|
BP_EXPORT void BP_CALLTYPE BpRetryConnect();
|
|
BP_EXPORT void BP_CALLTYPE BpPause();
|
|
BP_EXPORT void BP_CALLTYPE BpUnpause();
|
|
BP_EXPORT void BP_CALLTYPE BpSetClientName(const char* clientName);
|
|
BP_EXPORT void BP_CALLTYPE BpSetThreadName(const char* threadName);
|
|
BP_EXPORT void BP_CALLTYPE BpEnter(const char* zoneName);
|
|
BP_EXPORT void BP_CALLTYPE BpEnterF(const char* zoneName, ...);
|
|
BP_EXPORT void BP_CALLTYPE BpLeave();
|
|
BP_EXPORT void BP_CALLTYPE BpFrameTick();
|
|
BP_EXPORT void BP_CALLTYPE BpEvent(const char* name, const char* details);
|
|
BP_EXPORT const char* BP_CALLTYPE BpDynStr(const char* str);
|