diff --git a/src/MultiPlayer/multiplaymgr.cxx b/src/MultiPlayer/multiplaymgr.cxx index 68ca3c245..9bbb4aaac 100644 --- a/src/MultiPlayer/multiplaymgr.cxx +++ b/src/MultiPlayer/multiplaymgr.cxx @@ -32,6 +32,7 @@ #endif #include +#include #include #include @@ -58,7 +59,7 @@ const char sMULTIPLAYMGR_HID[] = MULTIPLAYTXMGR_HID; // This should be extendable dynamically for every specific aircraft ... // For now only that static list FGMultiplayMgr::IdPropertyList -FGMultiplayMgr::sIdPropertyList[] = { +const FGMultiplayMgr::sIdPropertyList[] = { {100, "surface-positions/left-aileron-pos-norm", SGPropertyNode::FLOAT}, {101, "surface-positions/right-aileron-pos-norm", SGPropertyNode::FLOAT}, {102, "surface-positions/elevator-pos-norm", SGPropertyNode::FLOAT}, @@ -220,11 +221,47 @@ FGMultiplayMgr::sIdPropertyList[] = { {10317, "sim/multiplay/generic/int[17]", SGPropertyNode::INT}, {10318, "sim/multiplay/generic/int[18]", SGPropertyNode::INT}, {10319, "sim/multiplay/generic/int[19]", SGPropertyNode::INT}, - - /// termination - {0, 0, SGPropertyNode::UNSPECIFIED} }; +const unsigned +FGMultiplayMgr::numProperties = (sizeof(FGMultiplayMgr::sIdPropertyList) + / sizeof(FGMultiplayMgr::sIdPropertyList[0])); + +// Look up a property ID using binary search. +namespace +{ + struct ComparePropertyId + { + bool operator()(const FGMultiplayMgr::IdPropertyList& lhs, + const FGMultiplayMgr::IdPropertyList& rhs) + { + return lhs.id < rhs.id; + } + bool operator()(const FGMultiplayMgr::IdPropertyList& lhs, + unsigned id) + { + return lhs.id < id; + } + bool operator()(unsigned id, + const FGMultiplayMgr::IdPropertyList& rhs) + { + return id < rhs.id; + } + }; + +} +const FGMultiplayMgr::IdPropertyList* FGMultiplayMgr::findProperty(unsigned id) +{ + std::pair result + = std::equal_range(sIdPropertyList, sIdPropertyList + numProperties, id, + ComparePropertyId()); + if (result.first == result.second) { + return 0; + } else { + return result.first; + } +} + ////////////////////////////////////////////////////////////////////// // // MultiplayMgr constructor @@ -685,21 +722,11 @@ FGMultiplayMgr::ProcessPosMsg(const char *Msg, netAddress & SenderAddress, xdr++; // Check the ID actually exists and get the type - unsigned i = 0; - bool found = false; - while (FGMultiplayMgr::sIdPropertyList[i].name) - { - if (sIdPropertyList[i].id == pData->id) - { - found = true; - pData->type = sIdPropertyList[i].type; - } - - i++; - } + const IdPropertyList* plist = findProperty(pData->id); - if (found == true) + if (plist) { + pData->type = plist->type; // How we decode the remainder of the property depends on the type switch (pData->type) { case SGPropertyNode::INT: @@ -770,7 +797,8 @@ FGMultiplayMgr::ProcessPosMsg(const char *Msg, netAddress & SenderAddress, else { // We failed to find the property. We'll try the next packet immediately. - //cout << " Unknown\n"; + SG_LOG(SG_NETWORK, SG_WARN, "FGMultiplayMgr::ProcessPosMsg - " + << "found unknown property id" << pData->id); } } @@ -852,11 +880,8 @@ FGMultiplayMgr::addMultiplayer(const std::string& callsign, aiMgr->attach(mp); /// FIXME: that must follow the attach ATM ... - unsigned i = 0; - while (sIdPropertyList[i].name) { + for (unsigned i = 0; i < numProperties; ++i) mp->addPropertyId(sIdPropertyList[i].id, sIdPropertyList[i].name); - ++i; - } } return mp; diff --git a/src/MultiPlayer/multiplaymgr.hxx b/src/MultiPlayer/multiplaymgr.hxx index 61cd2c49c..2cca356c5 100644 --- a/src/MultiPlayer/multiplaymgr.hxx +++ b/src/MultiPlayer/multiplaymgr.hxx @@ -60,8 +60,11 @@ public: const char* name; SGPropertyNode::Type type; }; - static IdPropertyList sIdPropertyList[]; + static const IdPropertyList sIdPropertyList[]; + static const unsigned numProperties; + static const IdPropertyList* findProperty(unsigned id); + FGMultiplayMgr(); ~FGMultiplayMgr(); bool init(void); diff --git a/src/Network/multiplay.cxx b/src/Network/multiplay.cxx index 44af02ad5..cea4e8ab4 100644 --- a/src/Network/multiplay.cxx +++ b/src/Network/multiplay.cxx @@ -101,13 +101,12 @@ bool FGMultiplay::open() { SGPropertyNode* root = globals->get_props(); /// Build up the id to property map - unsigned i = 0; - while (FGMultiplayMgr::sIdPropertyList[i].name) { + + 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; - ++i; } return is_enabled();