Package APIs to support multiple primary aircraft.

This (with some catalog and front-end changes) will allow packages to
supply multiple primary aircraft.
This commit is contained in:
James Turner 2017-04-04 07:04:43 +02:00
parent 9eee41d74a
commit f3e83cf020
4 changed files with 104 additions and 5 deletions

View File

@ -173,6 +173,8 @@ int parseTest()
SG_CHECK_EQUAL(thumb.path, "exterior.png");
// test variants
SG_CHECK_EQUAL(p2->parentIdForVariant(0), std::string());
try {
p2->indexOfVariant("fofofo");
SG_TEST_FAIL("lookup of non-existant variant did not throw");
@ -186,6 +188,8 @@ int parseTest()
unsigned int skisVariant = p2->indexOfVariant("c172p-skis");
SG_VERIFY(skisVariant > 0);
SG_CHECK_EQUAL(p2->parentIdForVariant(skisVariantFull), "c172p");
SG_CHECK_EQUAL(skisVariant, skisVariantFull);
SG_CHECK_EQUAL(p2->getLocalisedProp("description", skisVariant),
@ -195,6 +199,7 @@ int parseTest()
unsigned int floatsVariant = p2->indexOfVariant("c172p-floats");
SG_VERIFY(floatsVariant > 0);
SG_CHECK_EQUAL(p2->parentIdForVariant(floatsVariant), "c172p");
SG_CHECK_EQUAL(p2->getLocalisedProp("description", floatsVariant),
"A plane with floats");
@ -215,6 +220,19 @@ int parseTest()
SG_CHECK_EQUAL(thumb2.url, "http://foo.bar.com/thumb-floats.png");
SG_CHECK_EQUAL(thumb2.path, "thumb-floats.png");
// test multiple primary
unsigned int rVariant = p2->indexOfVariant("c172r");
SG_VERIFY(rVariant > 0);
SG_CHECK_EQUAL(p2->parentIdForVariant(rVariant), std::string());
unsigned int rFloatVariant = p2->indexOfVariant("c172r-floats");
SG_VERIFY(rFloatVariant > 0);
SG_CHECK_EQUAL(p2->parentIdForVariant(rFloatVariant), std::string("c172r"));
string_list primaries = {"c172p", "c172r"};
SG_VERIFY(p2->primaryVariants() == primaries);
// test filtering / searching too
string_set tags(p2->tags());
SG_CHECK_EQUAL(tags.size(), 4);

View File

@ -291,7 +291,7 @@ string_list Package::downloadUrls() const
return r;
}
BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("url")) {
for (auto dl : m_props->getChildren("url")) {
r.push_back(dl->getStringValue());
}
return r;
@ -412,7 +412,38 @@ SGPropertyNode_ptr Package::propsForVariant(const unsigned int vIndex, const cha
return m_props;
}
throw sg_exception("Unknow variant in package " + id());
throw sg_exception("Unknown variant in package " + id());
}
std::string Package::parentIdForVariant(unsigned int variantIndex) const
{
const std::string parentId = propsForVariant(variantIndex)->getStringValue("variant-of");
if ((variantIndex == 0) || (parentId == "_package_")) {
return std::string();
}
if (parentId.empty()) {
// this is a variant without a variant-of, so assume its parent is
// the first primary
return m_variants.front();
}
assert(indexOfVariant(parentId) >= 0);
return parentId;
}
string_list Package::primaryVariants() const
{
string_list result;
for (unsigned int v = 0; v < m_variants.size(); ++v) {
const auto pr = parentIdForVariant(v);
if (pr.empty()) {
result.push_back(m_variants.at(v));
}
}
assert(!result.empty());
assert(result.front() == id());
return result;
}
Package::Thumbnail Package::thumbnailForVariant(unsigned int vIndex) const

View File

@ -63,14 +63,24 @@ public:
bool isInstalled() const;
/**
* package ID
*/
std::string id() const;
/**
* Variant IDs. Note the primary ID will always be included as
* variants()[0], to simplify enumerating all variants
* Variant IDs
*/
string_list variants() const;
/**
* All variants without a parent, i.e top-level variants in this package.
* Often this is a single-element list matching id() above, but when
* packages contain multiple primary aircraft, this will have multiple
* elements.
*/
string_list primaryVariants() const;
/**
* Fully-qualified ID, including our catalog'd ID
*/
@ -89,6 +99,8 @@ public:
/**
* human-readable name - note this is probably not localised,
* although this is not ruled out for the future.
*
* Deprecated - please use nameForVariant
*/
std::string name() const;
@ -101,6 +113,9 @@ public:
/**
* syntactic sugar to get the localised description
*
* Deprecated - please use getLocalisedProp to get the variant-specific
* description.
*/
std::string description() const;
@ -182,6 +197,15 @@ public:
* same as the primary ID, depending on the aircraft author
*/
std::string dirName() const;
/**
* Return the parent variant of a variant. This will be the emtpy string if
* the variant is primary (top-level), otherwise the local (non-qualified)
* ID. This allows establishing a heirarchy of variants within the package.
* Note at present most code assumes a maxiumum two-level deep heirarchy
* (parents and children)
*/
std::string parentIdForVariant(unsigned int variantIndex) const;
private:
SGPath pathOnDisk() const;

View File

@ -99,6 +99,8 @@
<name>C172 with skis</name>
<description>A plane with skis</description>
<variant-of>c172p</variant-of>
<preview>
<type>exterior</type>
<path>thumb-exterior-skis.png</path>
@ -112,6 +114,30 @@
</preview>
</variant>
<variant>
<id>c172r</id>
<name>C172R</name>
<description>Equally good version of the C172</description>
<variant-of>_package_</variant-of>
<preview>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</preview>
</variant>
<variant>
<id>c172r-floats</id>
<name>C172R-floats</name>
<description>Equally good version of the C172 with floats</description>
<variant-of>c172r</variant-of>
<preview>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</preview>
</variant>
<md5>ec0e2ffdf98d6a5c05c77445e5447ff5</md5>
<url>http://localhost:2000/catalogTest1/c172p.zip</url>