FGMultiplayMgr: use binary search to find a property by id
This commit is contained in:
parent
473bf5f731
commit
e108eddc22
3 changed files with 53 additions and 26 deletions
|
@ -32,6 +32,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
#include <plib/netSocket.h>
|
#include <plib/netSocket.h>
|
||||||
|
|
||||||
#include <simgear/misc/stdint.hxx>
|
#include <simgear/misc/stdint.hxx>
|
||||||
|
@ -58,7 +59,7 @@ const char sMULTIPLAYMGR_HID[] = MULTIPLAYTXMGR_HID;
|
||||||
// This should be extendable dynamically for every specific aircraft ...
|
// This should be extendable dynamically for every specific aircraft ...
|
||||||
// For now only that static list
|
// For now only that static list
|
||||||
FGMultiplayMgr::IdPropertyList
|
FGMultiplayMgr::IdPropertyList
|
||||||
FGMultiplayMgr::sIdPropertyList[] = {
|
const FGMultiplayMgr::sIdPropertyList[] = {
|
||||||
{100, "surface-positions/left-aileron-pos-norm", SGPropertyNode::FLOAT},
|
{100, "surface-positions/left-aileron-pos-norm", SGPropertyNode::FLOAT},
|
||||||
{101, "surface-positions/right-aileron-pos-norm", SGPropertyNode::FLOAT},
|
{101, "surface-positions/right-aileron-pos-norm", SGPropertyNode::FLOAT},
|
||||||
{102, "surface-positions/elevator-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},
|
{10317, "sim/multiplay/generic/int[17]", SGPropertyNode::INT},
|
||||||
{10318, "sim/multiplay/generic/int[18]", SGPropertyNode::INT},
|
{10318, "sim/multiplay/generic/int[18]", SGPropertyNode::INT},
|
||||||
{10319, "sim/multiplay/generic/int[19]", 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<const IdPropertyList*, const IdPropertyList*> result
|
||||||
|
= std::equal_range(sIdPropertyList, sIdPropertyList + numProperties, id,
|
||||||
|
ComparePropertyId());
|
||||||
|
if (result.first == result.second) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return result.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// MultiplayMgr constructor
|
// MultiplayMgr constructor
|
||||||
|
@ -685,21 +722,11 @@ FGMultiplayMgr::ProcessPosMsg(const char *Msg, netAddress & SenderAddress,
|
||||||
xdr++;
|
xdr++;
|
||||||
|
|
||||||
// Check the ID actually exists and get the type
|
// Check the ID actually exists and get the type
|
||||||
unsigned i = 0;
|
const IdPropertyList* plist = findProperty(pData->id);
|
||||||
bool found = false;
|
|
||||||
while (FGMultiplayMgr::sIdPropertyList[i].name)
|
|
||||||
{
|
|
||||||
if (sIdPropertyList[i].id == pData->id)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
pData->type = sIdPropertyList[i].type;
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
if (plist)
|
||||||
}
|
|
||||||
|
|
||||||
if (found == true)
|
|
||||||
{
|
{
|
||||||
|
pData->type = plist->type;
|
||||||
// How we decode the remainder of the property depends on the type
|
// How we decode the remainder of the property depends on the type
|
||||||
switch (pData->type) {
|
switch (pData->type) {
|
||||||
case SGPropertyNode::INT:
|
case SGPropertyNode::INT:
|
||||||
|
@ -770,7 +797,8 @@ FGMultiplayMgr::ProcessPosMsg(const char *Msg, netAddress & SenderAddress,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We failed to find the property. We'll try the next packet immediately.
|
// 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);
|
aiMgr->attach(mp);
|
||||||
|
|
||||||
/// FIXME: that must follow the attach ATM ...
|
/// FIXME: that must follow the attach ATM ...
|
||||||
unsigned i = 0;
|
for (unsigned i = 0; i < numProperties; ++i)
|
||||||
while (sIdPropertyList[i].name) {
|
|
||||||
mp->addPropertyId(sIdPropertyList[i].id, sIdPropertyList[i].name);
|
mp->addPropertyId(sIdPropertyList[i].id, sIdPropertyList[i].name);
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mp;
|
return mp;
|
||||||
|
|
|
@ -60,7 +60,10 @@ public:
|
||||||
const char* name;
|
const char* name;
|
||||||
SGPropertyNode::Type type;
|
SGPropertyNode::Type type;
|
||||||
};
|
};
|
||||||
static IdPropertyList sIdPropertyList[];
|
static const IdPropertyList sIdPropertyList[];
|
||||||
|
static const unsigned numProperties;
|
||||||
|
|
||||||
|
static const IdPropertyList* findProperty(unsigned id);
|
||||||
|
|
||||||
FGMultiplayMgr();
|
FGMultiplayMgr();
|
||||||
~FGMultiplayMgr();
|
~FGMultiplayMgr();
|
||||||
|
|
|
@ -101,13 +101,12 @@ bool FGMultiplay::open() {
|
||||||
SGPropertyNode* root = globals->get_props();
|
SGPropertyNode* root = globals->get_props();
|
||||||
|
|
||||||
/// Build up the id to property map
|
/// 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;
|
const char* name = FGMultiplayMgr::sIdPropertyList[i].name;
|
||||||
SGPropertyNode* pNode = root->getNode(name);
|
SGPropertyNode* pNode = root->getNode(name);
|
||||||
if (pNode)
|
if (pNode)
|
||||||
mPropertyMap[FGMultiplayMgr::sIdPropertyList[i].id] = pNode;
|
mPropertyMap[FGMultiplayMgr::sIdPropertyList[i].id] = pNode;
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return is_enabled();
|
return is_enabled();
|
||||||
|
|
Loading…
Add table
Reference in a new issue