Skip to content

Commit 5b76352

Browse files
authored
Dev pull for Version 1.11 Release (#58)
* Added 'TakeOver' Option NetImguiServerApp can now forcefully take over a connection to a client already connected to another server. A button with 'TakeOver' appear in the Client List letting the user connect despite an active connection. * Small fixes Small fixes based on PR #56 by GitHub user @pthom * Updated to Dear ImGui 1.90.6 - Server updated to latest Dear Imgui - Added compatibility tests up to that version * API version update for release
1 parent 99bef62 commit 5b76352

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3528
-1836
lines changed

Build/GenerateCompatibilityTest.bat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pushd %~dp0
77
:: SETTINGS
88
::-----------------------------------------------------------------------------------
99
:: List of offical Dear ImGui (from official depot)
10-
set VERSIONS=(v1.71 v1.72 v1.73 v1.74 v1.75 v1.76 v1.77 v1.78 v1.79, v1.80, v1.81, v1.82, v1.83, v1.84, v1.85, v1.86, v1.87, v1.88, v1.89.1, v1.89.2, v1.89.3, v1.89.4, v1.89.5, v1.89.6, v1.89.7, v1.89.7-docking, v1.89.8, v1.89.8-docking, v1.89.9, v1.89.9-docking, v1.90, v1.90-docking)
10+
set VERSIONS=(v1.71 v1.72 v1.73 v1.74 v1.75 v1.76 v1.77 v1.78 v1.79, v1.80, v1.81, v1.82, v1.83, v1.84, v1.85, v1.86, v1.87, v1.88, v1.89.1, v1.89.2, v1.89.3, v1.89.4, v1.89.5, v1.89.6, v1.89.7, v1.89.7-docking, v1.89.8, v1.89.8-docking, v1.89.9, v1.89.9-docking, v1.90, v1.90-docking, v1.90.1, v1.90.2, v1.90.3, v1.90.4, v1.90.5, v1.90.6, v1.90.6-docking)
1111

1212
:: List of custom Dear ImGui releases (from own depot)
1313
set EXTRA_VERSIONS=(dock-1-76, dock-1-80, dock-1-89)

Code/Client/NetImgui_Api.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
//! @Name : NetImgui
55
//=================================================================================================
66
//! @author : Sammy Fatnassi
7-
//! @date : 2023/12/30
8-
//! @version : v1.10.0
7+
//! @date : 2024/05/26
8+
//! @version : v1.11.0
99
//! @Details : For integration info : https://github.com/sammyfreg/netImgui/wiki
1010
//=================================================================================================
11-
#define NETIMGUI_VERSION "1.10.0" // Version 1.10 Release
12-
#define NETIMGUI_VERSION_NUM 11000
11+
#define NETIMGUI_VERSION "1.11" // Version 1.1 Release
12+
#define NETIMGUI_VERSION_NUM 11100
1313

1414

1515

@@ -62,7 +62,7 @@
6262
// (either always included in NetImgui_config.h or have it included after Imgui.h in your cpp)
6363
#if !defined(IMGUI_VERSION)
6464
#undef NETIMGUI_ENABLED
65-
#define NETIMGUI_ENABLED 0
65+
#define NETIMGUI_ENABLED 0
6666
#endif
6767

6868
#if NETIMGUI_ENABLED

Code/Client/Private/NetImgui_Api.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ bool ConnectToApp(const char* clientName, const char* ServerHost, uint32_t serve
5656
if (client.mpSocketPending.load() != nullptr)
5757
{
5858
client.ContextInitialize();
59-
threadFunction = threadFunction == nullptr ? DefaultStartCommunicationThread : threadFunction;
60-
threadFunction(Client::CommunicationsClient, &client);
59+
threadFunction = threadFunction == nullptr ? DefaultStartCommunicationThread : threadFunction;
60+
threadFunction(Client::CommunicationsConnect, &client);
6161
}
6262

6363
return client.IsActive();
@@ -81,11 +81,11 @@ bool ConnectFromApp(const char* clientName, uint32_t serverPort, ThreadFunctPtr
8181
StringCopy(client.mName, (clientName == nullptr || clientName[0] == 0 ? "Unnamed" : clientName));
8282
client.mpSocketPending = Network::ListenStart(serverPort);
8383
client.mFontCreationFunction = FontCreateFunction;
84+
client.mThreadFunction = (threadFunction == nullptr) ? DefaultStartCommunicationThread : threadFunction;
8485
if (client.mpSocketPending.load() != nullptr)
8586
{
8687
client.ContextInitialize();
87-
threadFunction = threadFunction == nullptr ? DefaultStartCommunicationThread : threadFunction;
88-
threadFunction(Client::CommunicationsHost, &client);
88+
client.mThreadFunction(Client::CommunicationsHost, &client);
8989
}
9090

9191
return client.IsActive();
@@ -149,12 +149,11 @@ bool IsDrawingRemote(void)
149149
bool NewFrame(bool bSupportFrameSkip)
150150
//=================================================================================================
151151
{
152-
if (!gpClientInfo) return false;
152+
if (!gpClientInfo || gpClientInfo->mbIsDrawing) return false;
153153

154154
Client::ClientInfo& client = *gpClientInfo;
155155
ScopedBool scopedInside(client.mbInsideNewEnd, true);
156-
assert(!client.mbIsDrawing);
157-
156+
158157
// ImGui Newframe handled by remote connection settings
159158
if( NetImgui::IsConnected() )
160159
{
@@ -727,7 +726,8 @@ bool ProcessInputData(Client::ClientInfo& client)
727726
uint16_t character;
728727
io.InputQueueCharacters.resize(0);
729728
while (client.mPendingKeyIn.ReadData(&character)){
730-
io.AddInputCharacter(character);
729+
ImWchar ConvertedKey = static_cast<ImWchar>(character);
730+
io.AddInputCharacter(ConvertedKey);
731731
}
732732

733733
static_assert(sizeof(client.mPreviousInputState.mInputDownMask) == sizeof(pCmdInput->mInputDownMask), "Array size should match");

Code/Client/Private/NetImgui_Client.cpp

Lines changed: 80 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -75,35 +75,6 @@ static void SetClipboardTextFn_NetImguiImpl(void* user_data_ctx, const char* tex
7575
}
7676
}
7777

78-
//=================================================================================================
79-
// COMMUNICATIONS INITIALIZE
80-
// Initialize a new connection to a RemoteImgui server
81-
//=================================================================================================
82-
bool Communications_Initialize(ClientInfo& client)
83-
{
84-
CmdVersion cmdVersionSend, cmdVersionRcv;
85-
StringCopy(cmdVersionSend.mClientName, client.mName);
86-
bool bResultSend = Network::DataSend(client.mpSocketPending, &cmdVersionSend, cmdVersionSend.mHeader.mSize);
87-
bool bResultRcv = Network::DataReceive(client.mpSocketPending, &cmdVersionRcv, sizeof(cmdVersionRcv));
88-
bool mbConnected = bResultRcv && bResultSend &&
89-
cmdVersionRcv.mHeader.mType == cmdVersionSend.mHeader.mType &&
90-
cmdVersionRcv.mVersion == cmdVersionSend.mVersion &&
91-
cmdVersionRcv.mWCharSize == cmdVersionSend.mWCharSize;
92-
if(mbConnected)
93-
{
94-
for(auto& texture : client.mTextures)
95-
{
96-
texture.mbSent = false;
97-
}
98-
99-
client.mbHasTextureUpdate = true; // Force sending the client textures
100-
client.mBGSettingSent.mTextureId = client.mBGSetting.mTextureId-1u; // Force sending the Background settings (by making different than current settings)
101-
client.mpSocketComs = client.mpSocketPending.exchange(nullptr);
102-
client.mFrameIndex = 0;
103-
}
104-
return client.mpSocketComs.load() != nullptr;
105-
}
106-
10778
//=================================================================================================
10879
// INCOM: INPUT
10980
// Receive new keyboard/mouse/screen resolution input to pass on to dearImgui
@@ -332,16 +303,66 @@ bool Communications_Outgoing(ClientInfo& client)
332303
}
333304

334305
//=================================================================================================
335-
// COMMUNICATIONS THREAD
306+
// COMMUNICATIONS INITIALIZE
307+
// Initialize a new connection to a RemoteImgui server
336308
//=================================================================================================
337-
void CommunicationsClient(void* pClientVoid)
338-
{
309+
bool Communications_Initialize(ClientInfo& client)
310+
{
311+
CmdVersion cmdVersionSend, cmdVersionRcv;
312+
bool bResultRcv = Network::DataReceive(client.mpSocketPending, &cmdVersionRcv, sizeof(cmdVersionRcv));
313+
bool bForceConnect = client.mServerForceConnectEnabled && (cmdVersionRcv.mFlags & static_cast<uint8_t>(CmdVersion::eFlags::ConnectForce)) != 0;
314+
bool bCanConnect = bResultRcv &&
315+
cmdVersionRcv.mHeader.mType == cmdVersionSend.mHeader.mType &&
316+
cmdVersionRcv.mVersion == cmdVersionSend.mVersion &&
317+
cmdVersionRcv.mWCharSize == cmdVersionSend.mWCharSize &&
318+
(!client.IsConnected() || bForceConnect);
319+
320+
StringCopy(cmdVersionSend.mClientName, client.mName);
321+
cmdVersionSend.mFlags = client.IsConnected() && !bCanConnect ? static_cast<uint8_t>(CmdVersion::eFlags::IsConnected): 0;
322+
cmdVersionSend.mFlags |= client.IsConnected() && !client.mServerForceConnectEnabled ? static_cast<uint8_t>(CmdVersion::eFlags::IsUnavailable) : 0;
323+
bool bResultSend = Network::DataSend(client.mpSocketPending, &cmdVersionSend, cmdVersionSend.mHeader.mSize);
324+
325+
if(bCanConnect && bResultSend)
326+
{
327+
Network::SocketInfo* pNewConnect = client.mpSocketPending.exchange(nullptr);
328+
if( client.IsConnected() )
329+
{
330+
if( bForceConnect )
331+
{
332+
client.mbDisconnectRequest = true;
333+
while( client.IsConnected() );
334+
}
335+
else
336+
{
337+
NetImgui::Internal::Network::Disconnect(pNewConnect);
338+
return false;
339+
}
340+
}
341+
342+
for(auto& texture : client.mTextures)
343+
{
344+
texture.mbSent = false;
345+
}
346+
client.mbHasTextureUpdate = true; // Force sending the client textures
347+
client.mBGSettingSent.mTextureId = client.mBGSetting.mTextureId-1u; // Force sending the Background settings (by making different than current settings)
348+
client.mpSocketComs = pNewConnect;
349+
client.mFrameIndex = 0;
350+
client.mServerForceConnectEnabled = (cmdVersionRcv.mFlags & static_cast<uint8_t>(CmdVersion::eFlags::ConnectExclusive)) == 0;
351+
}
352+
return client.mpSocketPending.load() == nullptr;
353+
}
354+
355+
//=================================================================================================
356+
// COMMUNICATIONS MAIN LOOP
357+
//=================================================================================================
358+
void Communications_Loop(void* pClientVoid)
359+
{
360+
IM_ASSERT(pClientVoid != nullptr);
339361
ClientInfo* pClient = reinterpret_cast<ClientInfo*>(pClientVoid);
340-
pClient->mbClientThreadActive = true;
341-
pClient->mbDisconnectRequest = false;
342-
Communications_Initialize(*pClient);
343362
bool bConnected = pClient->IsConnected();
344-
363+
pClient->mbDisconnectRequest = false;
364+
pClient->mbClientThreadActive = true;
365+
345366
while( bConnected && !pClient->mbDisconnectRequest )
346367
{
347368
std::this_thread::sleep_for(std::chrono::milliseconds(1));
@@ -350,11 +371,27 @@ void CommunicationsClient(void* pClientVoid)
350371
}
351372

352373
pClient->KillSocketComs();
353-
pClient->mbClientThreadActive = false;
374+
pClient->mbClientThreadActive = false;
375+
}
376+
377+
//=================================================================================================
378+
// COMMUNICATIONS CONNECT THREAD : Reach out and connect to a NetImGuiServer
379+
//=================================================================================================
380+
void CommunicationsConnect(void* pClientVoid)
381+
{
382+
IM_ASSERT(pClientVoid != nullptr);
383+
ClientInfo* pClient = reinterpret_cast<ClientInfo*>(pClientVoid);
384+
pClient->mbClientThreadActive = true;
385+
if( Communications_Initialize(*pClient) )
386+
{
387+
Communications_Loop(pClientVoid);
388+
}
389+
pClient->mbClientThreadActive = false;
354390
}
355391

356392
//=================================================================================================
357-
// COMMUNICATIONS WAIT THREAD
393+
// COMMUNICATIONS HOST THREAD : Waiting NetImGuiServer reaching out to us.
394+
// Launch a new com loop when connection is established
358395
//=================================================================================================
359396
void CommunicationsHost(void* pClientVoid)
360397
{
@@ -366,18 +403,13 @@ void CommunicationsHost(void* pClientVoid)
366403
while( pClient->mpSocketListen.load() != nullptr && !pClient->mbDisconnectRequest )
367404
{
368405
pClient->mpSocketPending = Network::ListenConnect(pClient->mpSocketListen);
369-
if( pClient->mpSocketPending.load() != nullptr )
406+
if( !pClient->mbDisconnectRequest &&
407+
pClient->mpSocketPending.load() != nullptr &&
408+
Communications_Initialize(*pClient) )
370409
{
371-
bool bConnected = Communications_Initialize(*pClient);
372-
while (bConnected && !pClient->mbDisconnectRequest)
373-
{
374-
std::this_thread::sleep_for(std::chrono::milliseconds(1));
375-
//std::this_thread::yield();
376-
bConnected = Communications_Outgoing(*pClient) && Communications_Incoming(*pClient);
377-
}
378-
pClient->KillSocketComs();
410+
pClient->mThreadFunction(Client::Communications_Loop, pClient);
379411
}
380-
std::this_thread::sleep_for(std::chrono::milliseconds(10)); // Prevents this thread from taking entire core, waiting on server connection
412+
std::this_thread::sleep_for(std::chrono::milliseconds(16)); // Prevents this thread from taking entire core, waiting on server connection
381413
}
382414
pClient->KillSocketListen();
383415
pClient->mbListenThreadActive = false;

Code/Client/Private/NetImgui_Client.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ struct ClientInfo
113113
uint8_t mClientCompressionMode = eCompressionMode::kUseServerSetting;
114114
bool mServerCompressionEnabled = false; // If Server would like compression to be enabled (mClientCompressionMode value can override this value)
115115
bool mServerCompressionSkip = false; // Force ignore compression setting for 1 frame
116-
char PADDING[1];
116+
bool mServerForceConnectEnabled = true; // If another NetImguiServer can take connection away from the one currently active
117+
ThreadFunctPtr mThreadFunction = nullptr; // Function to use when laucnhing new threads
117118
FontCreateFuncPtr mFontCreationFunction = nullptr; // Method to call to generate the remote ImGui font. By default, re-use the local font, but this doesn't handle native DPI scaling on remote server
118119
float mFontCreationScaling = 1.f; // Last font scaling used when generating the NetImgui font
119120
InputState mPreviousInputState; // Keeping track of last keyboard/mouse state
@@ -136,9 +137,9 @@ struct ClientInfo
136137
};
137138

138139
//=============================================================================
139-
// Main communication thread, that should be started in its own thread
140+
// Main communication loop threads that are run in separate threads
140141
//=============================================================================
141-
void CommunicationsClient(void* pClientVoid);
142+
void CommunicationsConnect(void* pClientVoid);
142143
void CommunicationsHost(void* pClientVoid);
143144

144145
}}} //namespace NetImgui::Internal::Client

Code/Client/Private/NetImgui_CmdPackets.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,20 @@ struct alignas(8) CmdVersion
4646
CustomTexture = 12, // Added a 'custom' texture format to let user potentially handle their how format
4747
DPIScale = 13, // Server now handle monitor DPI
4848
Clipboard = 14, // Added clipboard support between server/client
49+
ForceReconnect = 15, // Server can now take over the connection from another server
4950
// Insert new version here
5051

5152
//--------------------------------
5253
_count,
5354
_current = _count -1
5455
};
55-
56+
enum class eFlags : uint8_t
57+
{
58+
IsUnavailable = 0x01, // Client telling Server it cannot be used
59+
IsConnected = 0x02, // Client telling Server there's already a valid connection (can potentially be taken over if !IsUnavailable)
60+
ConnectForce = 0x04, // Server telling Client it want to take over connection if there's already one
61+
ConnectExclusive = 0x08, // Server telling Client that once connected, others servers should be denied access
62+
};
5663
CmdHeader mHeader = CmdHeader(CmdHeader::eCommands::Version, sizeof(CmdVersion));
5764
eVersion mVersion = eVersion::_current;
5865
char mClientName[64] = {};
@@ -61,7 +68,8 @@ struct alignas(8) CmdVersion
6168
uint32_t mImguiVerID = IMGUI_VERSION_NUM;
6269
uint32_t mNetImguiVerID = NETIMGUI_VERSION_NUM;
6370
uint8_t mWCharSize = static_cast<uint8_t>(sizeof(ImWchar));
64-
char PADDING[3];
71+
uint8_t mFlags = 0;
72+
char PADDING[2];
6573
};
6674

6775
struct alignas(8) CmdInput
@@ -189,7 +197,7 @@ struct alignas(8) CmdInput
189197
int16_t mMousePos[2] = {};
190198
float mMouseWheelVert = 0.f;
191199
float mMouseWheelHoriz = 0.f;
192-
ImWchar mKeyChars[256] = {}; // Input characters
200+
uint16_t mKeyChars[256] = {}; // Input characters
193201
uint16_t mKeyCharCount = 0; // Number of valid input characters
194202
bool mCompressionUse = false; // Server would like client to compress the communication data
195203
bool mCompressionSkip = false; // Server forcing next client's frame data to be uncompressed

Code/Client/Private/NetImgui_Shared.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class ExchangePtr
9494
inline TType* Release();
9595
inline void Assign(TType*& pNewData);
9696
inline void Free();
97+
inline bool IsNull()const { return mpData.load() != nullptr; }
9798
private:
9899
std::atomic<TType*> mpData;
99100

Code/Sample/Common/Sample.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,15 @@ void FontCreationCallback_Default(float PreviousDPIScale, float NewDPIScale)
3535
#endif
3636
}
3737

38+
namespace Sample
39+
{
40+
3841
//=================================================================================================
3942
// Constructor
4043
//-------------------------------------------------------------------------------------------------
4144
//
4245
//=================================================================================================
43-
SampleClient_Base::SampleClient_Base(const char* sampleName)
46+
Base::Base(const char* sampleName)
4447
: mSampleName(sampleName)
4548
{
4649
#if NETIMGUI_ENABLED
@@ -55,7 +58,7 @@ SampleClient_Base::SampleClient_Base(const char* sampleName)
5558
//-------------------------------------------------------------------------------------------------
5659
//
5760
//=================================================================================================
58-
bool SampleClient_Base::Startup()
61+
bool Base::Startup()
5962
{
6063
mpContextLocal = mpContextMain = ImGui::GetCurrentContext();
6164
#if NETIMGUI_ENABLED
@@ -70,7 +73,7 @@ bool SampleClient_Base::Startup()
7073
//-------------------------------------------------------------------------------------------------
7174
//
7275
//=================================================================================================
73-
void SampleClient_Base::Shutdown()
76+
void Base::Shutdown()
7477
{
7578
#if NETIMGUI_ENABLED
7679
NetImgui::Shutdown();
@@ -88,7 +91,7 @@ void SampleClient_Base::Shutdown()
8891
// to a fixed size, paired with 'ImGui::GetIO().FontGlobalScale' for the text size increase.
8992
// However, this create blurier text. See 'SampleFontDPI' for more details
9093
//=================================================================================================
91-
bool SampleClient_Base::UpdateFont(float fontScaleDPI, bool isLocal)
94+
bool Base::UpdateFont(float fontScaleDPI, bool isLocal)
9295
{
9396
IM_UNUSED(isLocal);
9497
constexpr float kFontPixelSize = 16.f;
@@ -138,7 +141,7 @@ bool SampleClient_Base::UpdateFont(float fontScaleDPI, bool isLocal)
138141
// Function called by all samples, to display the Connection Options, and some other default
139142
// MainMenu entries.
140143
//=================================================================================================
141-
void SampleClient_Base::Draw_Connect()
144+
void Base::Draw_Connect()
142145
{
143146
#if NETIMGUI_ENABLED
144147
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3,6) );
@@ -238,3 +241,5 @@ void SampleClient_Base::Draw_Connect()
238241
}
239242
#endif // #if NETIMGUI_ENABLED
240243
}
244+
245+
}; // namespace Sample

0 commit comments

Comments
 (0)