From 6251814604a2395d66dc28fbe0cde8ce99e7be2c Mon Sep 17 00:00:00 2001 From: James Turner Date: Mon, 18 Oct 2010 00:58:35 +0100 Subject: [PATCH] Use a property listener on the root, to observe property creation, and thus lazily update the MP property map. Fixes bug 164, and probably many latent MP missing-property issues. --- src/Network/multiplay.cxx | 65 +++++++++++++++++++++++++++++++-------- src/Network/multiplay.hxx | 8 +++++ 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/Network/multiplay.cxx b/src/Network/multiplay.cxx index eb8a52c08..e7991e6b8 100644 --- a/src/Network/multiplay.cxx +++ b/src/Network/multiplay.cxx @@ -49,6 +49,24 @@ using std::string; const char sFG_MULTIPLAY_BID[] = "$Id$"; const char sFG_MULTIPLAY_HID[] = FG_MULTIPLAY_HID; +typedef std::set string_set; + +class MPPropertyListener : public SGPropertyChangeListener +{ +public: + MPPropertyListener(FGMultiplay* mp) : + _multiplay(mp) + { + } + + virtual void childAdded(SGPropertyNode*, SGPropertyNode*) + { + _multiplay->setPropertiesChanged(); + } + +private: + FGMultiplay* _multiplay; +}; /****************************************************************** * Name: FGMultiplay @@ -73,6 +91,7 @@ FGMultiplay::FGMultiplay (const string &dir, const int rate, const string &host, } + mPropertiesChanged = true; } @@ -97,19 +116,38 @@ bool FGMultiplay::open() { } set_enabled(true); - - SGPropertyNode* root = globals->get_props(); - - /// Build up the id to property map - for (unsigned i = 0; i < FGMultiplayMgr::numProperties; ++i) { + mPropertiesChanged = true; + + MPPropertyListener* pl = new MPPropertyListener(this); + globals->get_props()->addChangeListener(pl, false); + return is_enabled(); +} + +void FGMultiplay::findProperties() +{ + if (!mPropertiesChanged) { + return; + } + + mPropertiesChanged = false; + + for (unsigned i = 0; i < FGMultiplayMgr::numProperties; ++i) { const char* name = FGMultiplayMgr::sIdPropertyList[i].name; - SGPropertyNode* pNode = root->getNode(name); - if (pNode) - mPropertyMap[FGMultiplayMgr::sIdPropertyList[i].id] = pNode; + SGPropertyNode* pNode = globals->get_props()->getNode(name); + if (!pNode) { + continue; + } + + int id = FGMultiplayMgr::sIdPropertyList[i].id; + if (mPropertyMap.find(id) != mPropertyMap.end()) { + continue; // already activated + } + + mPropertyMap[id] = pNode; + SG_LOG(SG_NETWORK, SG_INFO, "activating MP property:" << pNode->getPath()); } - return is_enabled(); } @@ -121,7 +159,8 @@ bool FGMultiplay::open() { bool FGMultiplay::process() { using namespace simgear; if (get_direction() == SG_IO_OUT) { - + findProperties(); + // check if we have left initialization phase. That will not provide // interresting data, also the freeze in simulation time hurts the // multiplayer clients @@ -270,8 +309,10 @@ bool FGMultiplay::process() { * Description: Closes the multiplayer mgrs to stop any further * network processing ******************************************************************/ -bool FGMultiplay::close() { - +bool FGMultiplay::close() +{ + mPropertyMap.clear(); + FGMultiplayMgr* mgr = (FGMultiplayMgr*) globals->get_subsystem("mp"); if (mgr == 0) { diff --git a/src/Network/multiplay.hxx b/src/Network/multiplay.hxx index 0d5563c0e..f596ea0eb 100644 --- a/src/Network/multiplay.hxx +++ b/src/Network/multiplay.hxx @@ -78,7 +78,15 @@ public: */ bool close(); + void setPropertiesChanged() + { + mPropertiesChanged = true; + } private: + bool mPropertiesChanged; + + void findProperties(); + // Map between the property id's from the multiplayers network packets // and the property nodes typedef std::map > PropertyMap; -- 2.39.5