mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
[glass] NetworkTablesSettings: Don't block GUI (#3226)
On some systems, StopClient et al can take a long time to execute. Instead run these on a separate thread to avoid blocking the GUI. Also add option to get IP from DS (default on).
This commit is contained in:
@@ -17,14 +17,78 @@
|
||||
|
||||
using namespace glass;
|
||||
|
||||
void NetworkTablesSettings::Thread::Main() {
|
||||
while (m_active) {
|
||||
// wait to be woken up
|
||||
std::unique_lock lock(m_mutex);
|
||||
m_cond.wait(lock, [&] { return !m_active || m_restart; });
|
||||
if (!m_active) {
|
||||
break;
|
||||
}
|
||||
|
||||
// clear restart flag
|
||||
m_restart = false;
|
||||
|
||||
int mode;
|
||||
bool dsClient;
|
||||
|
||||
do {
|
||||
mode = m_mode;
|
||||
dsClient = m_dsClient;
|
||||
|
||||
// release lock while stopping to avoid blocking GUI
|
||||
lock.unlock();
|
||||
|
||||
// if just changing servers in client mode, no need to stop and restart
|
||||
unsigned int curMode = nt::GetNetworkMode(m_inst);
|
||||
if (mode != 1 || (curMode & NT_NET_MODE_SERVER) != 0) {
|
||||
nt::StopClient(m_inst);
|
||||
nt::StopServer(m_inst);
|
||||
nt::StopLocal(m_inst);
|
||||
}
|
||||
|
||||
if (m_mode != 1 || !dsClient) {
|
||||
nt::StopDSClient(m_inst);
|
||||
}
|
||||
|
||||
lock.lock();
|
||||
} while (mode != m_mode || dsClient != m_dsClient);
|
||||
|
||||
if (m_mode == 1) {
|
||||
wpi::StringRef serverTeam{m_serverTeam};
|
||||
unsigned int team;
|
||||
if (!serverTeam.contains('.') && !serverTeam.getAsInteger(10, team)) {
|
||||
nt::StartClientTeam(m_inst, team, NT_DEFAULT_PORT);
|
||||
} else {
|
||||
wpi::SmallVector<wpi::StringRef, 4> serverNames;
|
||||
wpi::SmallVector<std::pair<wpi::StringRef, unsigned int>, 4> servers;
|
||||
serverTeam.split(serverNames, ',', -1, false);
|
||||
for (auto&& serverName : serverNames) {
|
||||
servers.emplace_back(serverName, NT_DEFAULT_PORT);
|
||||
}
|
||||
nt::StartClient(m_inst, servers);
|
||||
}
|
||||
|
||||
if (m_dsClient) {
|
||||
nt::StartDSClient(m_inst, NT_DEFAULT_PORT);
|
||||
}
|
||||
} else if (m_mode == 2) {
|
||||
nt::StartServer(m_inst, m_iniName.c_str(), m_listenAddress.c_str(),
|
||||
NT_DEFAULT_PORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NetworkTablesSettings::NetworkTablesSettings(NT_Inst inst,
|
||||
const char* storageName)
|
||||
: m_inst{inst} {
|
||||
const char* storageName) {
|
||||
auto& storage = glass::GetStorage(storageName);
|
||||
m_pMode = storage.GetIntRef("mode");
|
||||
m_pIniName = storage.GetStringRef("iniName", "networktables.ini");
|
||||
m_pServerTeam = storage.GetStringRef("serverTeam");
|
||||
m_pListenAddress = storage.GetStringRef("listenAddress");
|
||||
m_pDsClient = storage.GetBoolRef("dsClient", true);
|
||||
|
||||
m_thread.Start(inst);
|
||||
}
|
||||
|
||||
void NetworkTablesSettings::Update() {
|
||||
@@ -32,27 +96,16 @@ void NetworkTablesSettings::Update() {
|
||||
return;
|
||||
}
|
||||
m_restart = false;
|
||||
nt::StopClient(m_inst);
|
||||
nt::StopServer(m_inst);
|
||||
nt::StopLocal(m_inst);
|
||||
if (*m_pMode == 1) {
|
||||
wpi::StringRef serverTeam{*m_pServerTeam};
|
||||
unsigned int team;
|
||||
if (!serverTeam.contains('.') && !serverTeam.getAsInteger(10, team)) {
|
||||
nt::StartClientTeam(m_inst, team, NT_DEFAULT_PORT);
|
||||
} else {
|
||||
wpi::SmallVector<wpi::StringRef, 4> serverNames;
|
||||
wpi::SmallVector<std::pair<wpi::StringRef, unsigned int>, 4> servers;
|
||||
serverTeam.split(serverNames, ',', -1, false);
|
||||
for (auto&& serverName : serverNames) {
|
||||
servers.emplace_back(serverName, NT_DEFAULT_PORT);
|
||||
}
|
||||
nt::StartClient(m_inst, servers);
|
||||
}
|
||||
} else if (*m_pMode == 2) {
|
||||
nt::StartServer(m_inst, m_pIniName->c_str(), m_pListenAddress->c_str(),
|
||||
NT_DEFAULT_PORT);
|
||||
}
|
||||
|
||||
// do actual operation on thread
|
||||
auto thr = m_thread.GetThread();
|
||||
thr->m_restart = true;
|
||||
thr->m_mode = *m_pMode;
|
||||
thr->m_iniName = *m_pIniName;
|
||||
thr->m_serverTeam = *m_pServerTeam;
|
||||
thr->m_listenAddress = *m_pListenAddress;
|
||||
thr->m_dsClient = *m_pDsClient;
|
||||
thr->m_cond.notify_one();
|
||||
}
|
||||
|
||||
bool NetworkTablesSettings::Display() {
|
||||
@@ -61,6 +114,7 @@ bool NetworkTablesSettings::Display() {
|
||||
switch (*m_pMode) {
|
||||
case 1:
|
||||
ImGui::InputText("Team/IP", m_pServerTeam);
|
||||
ImGui::Checkbox("Get Address from DS", m_pDsClient);
|
||||
break;
|
||||
case 2:
|
||||
ImGui::InputText("Listen Address", m_pListenAddress);
|
||||
|
||||
Reference in New Issue
Block a user