Skip to content

Commit

Permalink
Dev pull for Version 1.11 Release (#58)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
sammyfreg authored May 27, 2024
1 parent 99bef62 commit 5b76352
Show file tree
Hide file tree
Showing 44 changed files with 3,528 additions and 1,836 deletions.
2 changes: 1 addition & 1 deletion Build/GenerateCompatibilityTest.bat
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pushd %~dp0
:: SETTINGS
::-----------------------------------------------------------------------------------
:: List of offical Dear ImGui (from official depot)
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)
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)

:: List of custom Dear ImGui releases (from own depot)
set EXTRA_VERSIONS=(dock-1-76, dock-1-80, dock-1-89)
Expand Down
10 changes: 5 additions & 5 deletions Code/Client/NetImgui_Api.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
//! @Name : NetImgui
//=================================================================================================
//! @author : Sammy Fatnassi
//! @date : 2023/12/30
//! @version : v1.10.0
//! @date : 2024/05/26
//! @version : v1.11.0
//! @Details : For integration info : https://github.com/sammyfreg/netImgui/wiki
//=================================================================================================
#define NETIMGUI_VERSION "1.10.0" // Version 1.10 Release
#define NETIMGUI_VERSION_NUM 11000
#define NETIMGUI_VERSION "1.11" // Version 1.1 Release
#define NETIMGUI_VERSION_NUM 11100



Expand Down Expand Up @@ -62,7 +62,7 @@
// (either always included in NetImgui_config.h or have it included after Imgui.h in your cpp)
#if !defined(IMGUI_VERSION)
#undef NETIMGUI_ENABLED
#define NETIMGUI_ENABLED 0
#define NETIMGUI_ENABLED 0
#endif

#if NETIMGUI_ENABLED
Expand Down
16 changes: 8 additions & 8 deletions Code/Client/Private/NetImgui_Api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ bool ConnectToApp(const char* clientName, const char* ServerHost, uint32_t serve
if (client.mpSocketPending.load() != nullptr)
{
client.ContextInitialize();
threadFunction = threadFunction == nullptr ? DefaultStartCommunicationThread : threadFunction;
threadFunction(Client::CommunicationsClient, &client);
threadFunction = threadFunction == nullptr ? DefaultStartCommunicationThread : threadFunction;
threadFunction(Client::CommunicationsConnect, &client);
}

return client.IsActive();
Expand All @@ -81,11 +81,11 @@ bool ConnectFromApp(const char* clientName, uint32_t serverPort, ThreadFunctPtr
StringCopy(client.mName, (clientName == nullptr || clientName[0] == 0 ? "Unnamed" : clientName));
client.mpSocketPending = Network::ListenStart(serverPort);
client.mFontCreationFunction = FontCreateFunction;
client.mThreadFunction = (threadFunction == nullptr) ? DefaultStartCommunicationThread : threadFunction;
if (client.mpSocketPending.load() != nullptr)
{
client.ContextInitialize();
threadFunction = threadFunction == nullptr ? DefaultStartCommunicationThread : threadFunction;
threadFunction(Client::CommunicationsHost, &client);
client.mThreadFunction(Client::CommunicationsHost, &client);
}

return client.IsActive();
Expand Down Expand Up @@ -149,12 +149,11 @@ bool IsDrawingRemote(void)
bool NewFrame(bool bSupportFrameSkip)
//=================================================================================================
{
if (!gpClientInfo) return false;
if (!gpClientInfo || gpClientInfo->mbIsDrawing) return false;

Client::ClientInfo& client = *gpClientInfo;
ScopedBool scopedInside(client.mbInsideNewEnd, true);
assert(!client.mbIsDrawing);


// ImGui Newframe handled by remote connection settings
if( NetImgui::IsConnected() )
{
Expand Down Expand Up @@ -727,7 +726,8 @@ bool ProcessInputData(Client::ClientInfo& client)
uint16_t character;
io.InputQueueCharacters.resize(0);
while (client.mPendingKeyIn.ReadData(&character)){
io.AddInputCharacter(character);
ImWchar ConvertedKey = static_cast<ImWchar>(character);
io.AddInputCharacter(ConvertedKey);
}

static_assert(sizeof(client.mPreviousInputState.mInputDownMask) == sizeof(pCmdInput->mInputDownMask), "Array size should match");
Expand Down
128 changes: 80 additions & 48 deletions Code/Client/Private/NetImgui_Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,35 +75,6 @@ static void SetClipboardTextFn_NetImguiImpl(void* user_data_ctx, const char* tex
}
}

//=================================================================================================
// COMMUNICATIONS INITIALIZE
// Initialize a new connection to a RemoteImgui server
//=================================================================================================
bool Communications_Initialize(ClientInfo& client)
{
CmdVersion cmdVersionSend, cmdVersionRcv;
StringCopy(cmdVersionSend.mClientName, client.mName);
bool bResultSend = Network::DataSend(client.mpSocketPending, &cmdVersionSend, cmdVersionSend.mHeader.mSize);
bool bResultRcv = Network::DataReceive(client.mpSocketPending, &cmdVersionRcv, sizeof(cmdVersionRcv));
bool mbConnected = bResultRcv && bResultSend &&
cmdVersionRcv.mHeader.mType == cmdVersionSend.mHeader.mType &&
cmdVersionRcv.mVersion == cmdVersionSend.mVersion &&
cmdVersionRcv.mWCharSize == cmdVersionSend.mWCharSize;
if(mbConnected)
{
for(auto& texture : client.mTextures)
{
texture.mbSent = false;
}

client.mbHasTextureUpdate = true; // Force sending the client textures
client.mBGSettingSent.mTextureId = client.mBGSetting.mTextureId-1u; // Force sending the Background settings (by making different than current settings)
client.mpSocketComs = client.mpSocketPending.exchange(nullptr);
client.mFrameIndex = 0;
}
return client.mpSocketComs.load() != nullptr;
}

//=================================================================================================
// INCOM: INPUT
// Receive new keyboard/mouse/screen resolution input to pass on to dearImgui
Expand Down Expand Up @@ -332,16 +303,66 @@ bool Communications_Outgoing(ClientInfo& client)
}

//=================================================================================================
// COMMUNICATIONS THREAD
// COMMUNICATIONS INITIALIZE
// Initialize a new connection to a RemoteImgui server
//=================================================================================================
void CommunicationsClient(void* pClientVoid)
{
bool Communications_Initialize(ClientInfo& client)
{
CmdVersion cmdVersionSend, cmdVersionRcv;
bool bResultRcv = Network::DataReceive(client.mpSocketPending, &cmdVersionRcv, sizeof(cmdVersionRcv));
bool bForceConnect = client.mServerForceConnectEnabled && (cmdVersionRcv.mFlags & static_cast<uint8_t>(CmdVersion::eFlags::ConnectForce)) != 0;
bool bCanConnect = bResultRcv &&
cmdVersionRcv.mHeader.mType == cmdVersionSend.mHeader.mType &&
cmdVersionRcv.mVersion == cmdVersionSend.mVersion &&
cmdVersionRcv.mWCharSize == cmdVersionSend.mWCharSize &&
(!client.IsConnected() || bForceConnect);

StringCopy(cmdVersionSend.mClientName, client.mName);
cmdVersionSend.mFlags = client.IsConnected() && !bCanConnect ? static_cast<uint8_t>(CmdVersion::eFlags::IsConnected): 0;
cmdVersionSend.mFlags |= client.IsConnected() && !client.mServerForceConnectEnabled ? static_cast<uint8_t>(CmdVersion::eFlags::IsUnavailable) : 0;
bool bResultSend = Network::DataSend(client.mpSocketPending, &cmdVersionSend, cmdVersionSend.mHeader.mSize);

if(bCanConnect && bResultSend)
{
Network::SocketInfo* pNewConnect = client.mpSocketPending.exchange(nullptr);
if( client.IsConnected() )
{
if( bForceConnect )
{
client.mbDisconnectRequest = true;
while( client.IsConnected() );
}
else
{
NetImgui::Internal::Network::Disconnect(pNewConnect);
return false;
}
}

for(auto& texture : client.mTextures)
{
texture.mbSent = false;
}
client.mbHasTextureUpdate = true; // Force sending the client textures
client.mBGSettingSent.mTextureId = client.mBGSetting.mTextureId-1u; // Force sending the Background settings (by making different than current settings)
client.mpSocketComs = pNewConnect;
client.mFrameIndex = 0;
client.mServerForceConnectEnabled = (cmdVersionRcv.mFlags & static_cast<uint8_t>(CmdVersion::eFlags::ConnectExclusive)) == 0;
}
return client.mpSocketPending.load() == nullptr;
}

//=================================================================================================
// COMMUNICATIONS MAIN LOOP
//=================================================================================================
void Communications_Loop(void* pClientVoid)
{
IM_ASSERT(pClientVoid != nullptr);
ClientInfo* pClient = reinterpret_cast<ClientInfo*>(pClientVoid);
pClient->mbClientThreadActive = true;
pClient->mbDisconnectRequest = false;
Communications_Initialize(*pClient);
bool bConnected = pClient->IsConnected();

pClient->mbDisconnectRequest = false;
pClient->mbClientThreadActive = true;

while( bConnected && !pClient->mbDisconnectRequest )
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
Expand All @@ -350,11 +371,27 @@ void CommunicationsClient(void* pClientVoid)
}

pClient->KillSocketComs();
pClient->mbClientThreadActive = false;
pClient->mbClientThreadActive = false;
}

//=================================================================================================
// COMMUNICATIONS CONNECT THREAD : Reach out and connect to a NetImGuiServer
//=================================================================================================
void CommunicationsConnect(void* pClientVoid)
{
IM_ASSERT(pClientVoid != nullptr);
ClientInfo* pClient = reinterpret_cast<ClientInfo*>(pClientVoid);
pClient->mbClientThreadActive = true;
if( Communications_Initialize(*pClient) )
{
Communications_Loop(pClientVoid);
}
pClient->mbClientThreadActive = false;
}

//=================================================================================================
// COMMUNICATIONS WAIT THREAD
// COMMUNICATIONS HOST THREAD : Waiting NetImGuiServer reaching out to us.
// Launch a new com loop when connection is established
//=================================================================================================
void CommunicationsHost(void* pClientVoid)
{
Expand All @@ -366,18 +403,13 @@ void CommunicationsHost(void* pClientVoid)
while( pClient->mpSocketListen.load() != nullptr && !pClient->mbDisconnectRequest )
{
pClient->mpSocketPending = Network::ListenConnect(pClient->mpSocketListen);
if( pClient->mpSocketPending.load() != nullptr )
if( !pClient->mbDisconnectRequest &&
pClient->mpSocketPending.load() != nullptr &&
Communications_Initialize(*pClient) )
{
bool bConnected = Communications_Initialize(*pClient);
while (bConnected && !pClient->mbDisconnectRequest)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
//std::this_thread::yield();
bConnected = Communications_Outgoing(*pClient) && Communications_Incoming(*pClient);
}
pClient->KillSocketComs();
pClient->mThreadFunction(Client::Communications_Loop, pClient);
}
std::this_thread::sleep_for(std::chrono::milliseconds(10)); // Prevents this thread from taking entire core, waiting on server connection
std::this_thread::sleep_for(std::chrono::milliseconds(16)); // Prevents this thread from taking entire core, waiting on server connection
}
pClient->KillSocketListen();
pClient->mbListenThreadActive = false;
Expand Down
7 changes: 4 additions & 3 deletions Code/Client/Private/NetImgui_Client.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ struct ClientInfo
uint8_t mClientCompressionMode = eCompressionMode::kUseServerSetting;
bool mServerCompressionEnabled = false; // If Server would like compression to be enabled (mClientCompressionMode value can override this value)
bool mServerCompressionSkip = false; // Force ignore compression setting for 1 frame
char PADDING[1];
bool mServerForceConnectEnabled = true; // If another NetImguiServer can take connection away from the one currently active
ThreadFunctPtr mThreadFunction = nullptr; // Function to use when laucnhing new threads
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
float mFontCreationScaling = 1.f; // Last font scaling used when generating the NetImgui font
InputState mPreviousInputState; // Keeping track of last keyboard/mouse state
Expand All @@ -136,9 +137,9 @@ struct ClientInfo
};

//=============================================================================
// Main communication thread, that should be started in its own thread
// Main communication loop threads that are run in separate threads
//=============================================================================
void CommunicationsClient(void* pClientVoid);
void CommunicationsConnect(void* pClientVoid);
void CommunicationsHost(void* pClientVoid);

}}} //namespace NetImgui::Internal::Client
Expand Down
14 changes: 11 additions & 3 deletions Code/Client/Private/NetImgui_CmdPackets.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,20 @@ struct alignas(8) CmdVersion
CustomTexture = 12, // Added a 'custom' texture format to let user potentially handle their how format
DPIScale = 13, // Server now handle monitor DPI
Clipboard = 14, // Added clipboard support between server/client
ForceReconnect = 15, // Server can now take over the connection from another server
// Insert new version here

//--------------------------------
_count,
_current = _count -1
};

enum class eFlags : uint8_t
{
IsUnavailable = 0x01, // Client telling Server it cannot be used
IsConnected = 0x02, // Client telling Server there's already a valid connection (can potentially be taken over if !IsUnavailable)
ConnectForce = 0x04, // Server telling Client it want to take over connection if there's already one
ConnectExclusive = 0x08, // Server telling Client that once connected, others servers should be denied access
};
CmdHeader mHeader = CmdHeader(CmdHeader::eCommands::Version, sizeof(CmdVersion));
eVersion mVersion = eVersion::_current;
char mClientName[64] = {};
Expand All @@ -61,7 +68,8 @@ struct alignas(8) CmdVersion
uint32_t mImguiVerID = IMGUI_VERSION_NUM;
uint32_t mNetImguiVerID = NETIMGUI_VERSION_NUM;
uint8_t mWCharSize = static_cast<uint8_t>(sizeof(ImWchar));
char PADDING[3];
uint8_t mFlags = 0;
char PADDING[2];
};

struct alignas(8) CmdInput
Expand Down Expand Up @@ -189,7 +197,7 @@ struct alignas(8) CmdInput
int16_t mMousePos[2] = {};
float mMouseWheelVert = 0.f;
float mMouseWheelHoriz = 0.f;
ImWchar mKeyChars[256] = {}; // Input characters
uint16_t mKeyChars[256] = {}; // Input characters
uint16_t mKeyCharCount = 0; // Number of valid input characters
bool mCompressionUse = false; // Server would like client to compress the communication data
bool mCompressionSkip = false; // Server forcing next client's frame data to be uncompressed
Expand Down
1 change: 1 addition & 0 deletions Code/Client/Private/NetImgui_Shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class ExchangePtr
inline TType* Release();
inline void Assign(TType*& pNewData);
inline void Free();
inline bool IsNull()const { return mpData.load() != nullptr; }
private:
std::atomic<TType*> mpData;

Expand Down
15 changes: 10 additions & 5 deletions Code/Sample/Common/Sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,15 @@ void FontCreationCallback_Default(float PreviousDPIScale, float NewDPIScale)
#endif
}

namespace Sample
{

//=================================================================================================
// Constructor
//-------------------------------------------------------------------------------------------------
//
//=================================================================================================
SampleClient_Base::SampleClient_Base(const char* sampleName)
Base::Base(const char* sampleName)
: mSampleName(sampleName)
{
#if NETIMGUI_ENABLED
Expand All @@ -55,7 +58,7 @@ SampleClient_Base::SampleClient_Base(const char* sampleName)
//-------------------------------------------------------------------------------------------------
//
//=================================================================================================
bool SampleClient_Base::Startup()
bool Base::Startup()
{
mpContextLocal = mpContextMain = ImGui::GetCurrentContext();
#if NETIMGUI_ENABLED
Expand All @@ -70,7 +73,7 @@ bool SampleClient_Base::Startup()
//-------------------------------------------------------------------------------------------------
//
//=================================================================================================
void SampleClient_Base::Shutdown()
void Base::Shutdown()
{
#if NETIMGUI_ENABLED
NetImgui::Shutdown();
Expand All @@ -88,7 +91,7 @@ void SampleClient_Base::Shutdown()
// to a fixed size, paired with 'ImGui::GetIO().FontGlobalScale' for the text size increase.
// However, this create blurier text. See 'SampleFontDPI' for more details
//=================================================================================================
bool SampleClient_Base::UpdateFont(float fontScaleDPI, bool isLocal)
bool Base::UpdateFont(float fontScaleDPI, bool isLocal)
{
IM_UNUSED(isLocal);
constexpr float kFontPixelSize = 16.f;
Expand Down Expand Up @@ -138,7 +141,7 @@ bool SampleClient_Base::UpdateFont(float fontScaleDPI, bool isLocal)
// Function called by all samples, to display the Connection Options, and some other default
// MainMenu entries.
//=================================================================================================
void SampleClient_Base::Draw_Connect()
void Base::Draw_Connect()
{
#if NETIMGUI_ENABLED
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3,6) );
Expand Down Expand Up @@ -238,3 +241,5 @@ void SampleClient_Base::Draw_Connect()
}
#endif // #if NETIMGUI_ENABLED
}

}; // namespace Sample
Loading

0 comments on commit 5b76352

Please sign in to comment.