From 2d77aa2461b670813b772de61409a04d26b95d49 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Thu, 1 May 2025 14:28:14 +0200 Subject: [PATCH] Fix issue multiple local participants --- Participant.cpp | 126 +++++++++++++++++++------------- Participant.h | 31 +++++--- Participants/ParticipantUDP.cpp | 37 ++++------ Participants/SiteServer.cpp | 7 +- Thing.h | 1 - 5 files changed, 110 insertions(+), 92 deletions(-) diff --git a/Participant.cpp b/Participant.cpp index e423608..e8d33f8 100644 --- a/Participant.cpp +++ b/Participant.cpp @@ -4,7 +4,9 @@ namespace RoboidControl { -std::list Participant::participants; +#pragma region Participant + +ParticipantRegistry Participant::registry; Participant::Participant(const char* ipAddress, int port) { // make a copy of the ip address string @@ -24,6 +26,7 @@ Participant::Participant(const char* ipAddress, int port) { } Participant::~Participant() { + registry.Remove(this); delete[] this->ipAddress; } @@ -34,56 +37,6 @@ void Participant::Update(unsigned long currentTimeMs) { } } -Participant* Participant::GetParticipant(const char* ipAddress, - unsigned int port) { - for (Participant* participant : Participant::participants) { - if (participant == nullptr) - continue; - if (strcmp(participant->ipAddress, ipAddress) == 0 && - participant->port == port) - return participant; - } - // std::cout << "Could not find participant " << ipAddress << ":" << (int)port - // << std::endl; - return nullptr; -} - -Participant* Participant::GetParticipant(unsigned char participantId) { - for (Participant* participant : Participant::participants) { - if (participant == nullptr) - continue; - if (participant->networkId == participantId) - return participant; - } - // std::cout << "Could not find participant " << (int)participantId << std::endl; - return nullptr; -} - -Participant* Participant::AddParticipant(const char* ipAddress, unsigned int port) { - Participant* participant = new Participant(ipAddress, port); - Participant::AddParticipant(participant); - return participant; -} - -void Participant::AddParticipant(Participant* participant) { - Participant* foundParticipant = - Participant::GetParticipant(participant->ipAddress, participant->port); - if (foundParticipant == nullptr) { -#if defined(NO_STD) - this->things[this->thingCount++] = thing; -#else - Participant::participants.push_back(participant); -#endif - std::cout << "Add participant " << participant->ipAddress << ":" - << participant->port << "[" << (int)participant->networkId - << "]\n"; - } else { - std::cout << "Did not add, existing participant " << participant->ipAddress << ":" - << participant->port << "[" << (int)participant->networkId - << "]\n"; - } -} - Thing* Participant::Get(unsigned char thingId) { for (Thing* thing : this->things) { if (thing->id == thingId) @@ -154,4 +107,75 @@ void Participant::Remove(Thing* thing) { #endif } +#pragma endregion + +#pragma region ParticipantRegistry + +Participant* ParticipantRegistry::GetParticipant(const char* ipAddress, + unsigned int port) { + for (Participant* participant : ParticipantRegistry::participants) { + if (participant == nullptr) + continue; + if (strcmp(participant->ipAddress, ipAddress) == 0 && + participant->port == port) { + std::cout << "found participant " << participant->ipAddress << ":" + << (int)participant->port << std::endl; + return participant; + } + } + std::cout << "Could not find participant " << ipAddress << ":" << (int)port + << std::endl; + return nullptr; +} + +Participant* ParticipantRegistry::GetParticipant(unsigned char participantId) { + for (Participant* participant : ParticipantRegistry::participants) { + if (participant == nullptr) + continue; + if (participant->networkId == participantId) + return participant; + } + std::cout << "Could not find participant " << (int)participantId << std::endl; + return nullptr; +} + +Participant* ParticipantRegistry::AddParticipant(const char* ipAddress, + unsigned int port) { + Participant* participant = new Participant(ipAddress, port); + AddParticipant(participant); + return participant; +} + +void ParticipantRegistry::AddParticipant(Participant* participant) { + Participant* foundParticipant = + GetParticipant(participant->ipAddress, participant->port); + + if (foundParticipant == nullptr) { +#if defined(NO_STD) + this->things[this->thingCount++] = thing; +#else + ParticipantRegistry::participants.push_back(participant); +#endif + std::cout << "Add participant " << participant->ipAddress << ":" + << participant->port << "[" << (int)participant->networkId + << "]\n"; + std::cout << "participants " << ParticipantRegistry::participants.size() + << "\n"; + } else { + std::cout << "Did not add, existing participant " << participant->ipAddress + << ":" << participant->port << "[" << (int)participant->networkId + << "]\n"; + } +} + +void ParticipantRegistry::Remove(Participant* participant) { + // participants.remove(participant); +} + +const std::list& ParticipantRegistry::GetAll() const { + return ParticipantRegistry::participants; +} + +#pragma endregion ParticipantRegistry + } // namespace RoboidControl diff --git a/Participant.h b/Participant.h index 2facd6b..4bf393d 100644 --- a/Participant.h +++ b/Participant.h @@ -5,6 +5,24 @@ namespace RoboidControl { constexpr int MAX_THING_COUNT = 256; +class ParticipantRegistry { + public: + Participant* GetParticipant(const char* ipAddress, unsigned int port); + Participant* GetParticipant(unsigned char participantId); + Participant* AddParticipant(const char* ipAddress, unsigned int port); + void AddParticipant(Participant* participant); + + void Remove(Participant* participant); + + const std::list& GetAll() const; + private: + #if defined(NO_STD) + #else + /// @brief The list of known participants + std::list participants; + #endif + }; + /// @brief A participant is a device which manages things. /// It can communicate with other participant to synchronise the state of /// things. This class is used to register the things the participant is @@ -52,17 +70,8 @@ class Participant { /// @param currentTimeMs The current time in milliseconds (optional) virtual void Update(unsigned long currentTimeMs = 0); - public: -#if defined(NO_STD) -#else - /// @brief The list of known participants - static std::list participants; -#endif - static Participant* GetParticipant(const char* ipAddress, unsigned int port); - static Participant* GetParticipant(unsigned char participantId); - static Participant* AddParticipant(const char* ipAddress, unsigned int port); - static void AddParticipant(Participant* participant); - +public: + static ParticipantRegistry registry; }; } // namespace RoboidControl diff --git a/Participants/ParticipantUDP.cpp b/Participants/ParticipantUDP.cpp index cab013d..a4d5859 100644 --- a/Participants/ParticipantUDP.cpp +++ b/Participants/ParticipantUDP.cpp @@ -4,32 +4,18 @@ #include "Arduino/ArduinoParticipant.h" #include "EspIdf/EspIdfParticipant.h" - -#if defined(_WIN32) || defined(_WIN64) -#include -#include #include "Windows/WindowsParticipant.h" -#pragma comment(lib, "ws2_32.lib") - -#elif defined(__unix__) || defined(__APPLE__) -#include -#include // For fcntl -#include -#include -#include -#include #include "Posix/PosixParticipant.h" -#endif #include namespace RoboidControl { -ParticipantUDP::ParticipantUDP(int port) : Participant("0.0.0.0", port) { +ParticipantUDP::ParticipantUDP(int port) : Participant("127.0.0.1", port) { this->remoteSite = nullptr; if (this->port == 0) this->isIsolated = true; - Participant::AddParticipant(this); + Participant::registry.AddParticipant(this); } ParticipantUDP::ParticipantUDP(const char* ipAddress, int port, int localPort) @@ -38,7 +24,7 @@ ParticipantUDP::ParticipantUDP(const char* ipAddress, int port, int localPort) this->isIsolated = true; else this->remoteSite = new Participant(ipAddress, port); - Participant::AddParticipant(this); + Participant::registry.AddParticipant(this); } static ParticipantUDP* isolatedParticipant = nullptr; @@ -50,7 +36,7 @@ ParticipantUDP* ParticipantUDP::Isolated() { } void ParticipantUDP::begin() { - if (this->isIsolated) + if (this->isIsolated || this->remoteSite == nullptr) return; SetupUDP(this->port, this->remoteSite->ipAddress, this->remoteSite->port); @@ -157,11 +143,14 @@ void ParticipantUDP::UpdateMyThings(unsigned long currentTimeMs = 0) { } void ParticipantUDP::UpdateOtherThings(unsigned long currentTimeMs = 0) { - for (Participant* participant : Participant::participants) { + for (Participant* participant : Participant::registry.GetAll()) { if (participant == nullptr || participant == this) continue; - participant->Update(currentTimeMs); + // Call only the Participant version of the Update. + // This is to deal with the function where one of the (remote) + // participants is actually a local participant + participant->Participant::Update(currentTimeMs); if (this->isIsolated) continue; @@ -301,9 +290,9 @@ void ParticipantUDP::ReceiveData(unsigned char packetSize, unsigned int senderPort) { // std::cout << "Receive data from " << senderIpAddress << ":" << senderPort // << std::endl; - Participant* sender = this->GetParticipant(senderIpAddress, senderPort); + Participant* sender = this->registry.GetParticipant(senderIpAddress, senderPort); if (sender == nullptr) { - sender = this->AddParticipant(senderIpAddress, senderPort); + sender = this->registry.AddParticipant(senderIpAddress, senderPort); #if !defined(NO_STD) std::cout << "New remote participant " << sender->ipAddress << ":" << sender->port << std::endl; @@ -456,7 +445,7 @@ void ParticipantUDP::Process(Participant* sender, PoseMsg* msg) { std::cout << this->name << ": process PoseMsg [" << (int)this->networkId << "/" << (int)msg->networkId << "] " << (int)msg->poseType << "\n"; #endif - Participant* owner = Participant::GetParticipant(msg->networkId); + Participant* owner = Participant::registry.GetParticipant(msg->networkId); if (owner == nullptr) return; @@ -480,7 +469,7 @@ void ParticipantUDP::Process(Participant* sender, BinaryMsg* msg) { << "/" << (int)msg->thingId << "]\n"; #endif - Participant* owner = Participant::GetParticipant(msg->networkId); + Participant* owner = Participant::registry.GetParticipant(msg->networkId); if (owner != nullptr) { Thing* thing = owner->Get(msg->thingId); if (thing != nullptr) diff --git a/Participants/SiteServer.cpp b/Participants/SiteServer.cpp index 18b5d6b..fd0fed3 100644 --- a/Participants/SiteServer.cpp +++ b/Participants/SiteServer.cpp @@ -11,13 +11,10 @@ namespace RoboidControl { #pragma region Init -SiteServer::SiteServer(int port) { +SiteServer::SiteServer(int port) : ParticipantUDP(port) { this->name = "Site Server"; this->publishInterval = 0; - this->ipAddress = "0.0.0.0"; - this->port = port; - SetupUDP(port, ipAddress, 0); } @@ -34,7 +31,7 @@ void SiteServer::UpdateMyThings(unsigned long currentTimeMs) { if (this->isIsolated == false) { // Send to all other participants - for (Participant* participant : Participant::participants) { + for (Participant* participant : Participant::registry.GetAll()) { if (participant == nullptr || participant == this) continue; diff --git a/Thing.h b/Thing.h index ebc546c..691b6f5 100644 --- a/Thing.h +++ b/Thing.h @@ -66,7 +66,6 @@ class Thing { public: /// @brief Terminated things are no longer updated - void Terminate(); bool terminate = false; #pragma region Properties