Moving more documentation to use codegen (#1549)

- Make use of more codegen in more classes
- Fix verifier for Color4Verifier
This commit is contained in:
Alexander Bock
2021-03-29 21:50:26 +02:00
committed by GitHub
parent a49c1f435f
commit 612b9bbc7f
44 changed files with 1877 additions and 3279 deletions
+15 -29
View File
@@ -38,39 +38,29 @@
namespace {
constexpr const char* _loggerCat = "HttpSynchronization";
constexpr const char* KeyIdentifier = "Identifier";
constexpr const char* KeyVersion = "Version";
constexpr const char* TempSuffix = ".tmp";
constexpr const char* QueryKeyIdentifier = "identifier";
constexpr const char* QueryKeyFileVersion = "file_version";
constexpr const char* QueryKeyApplicationVersion = "application_version";
constexpr const int ApplicationVersion = 1;
struct [[codegen::Dictionary(HttpSynchronization)]] Parameters {
// A unique identifier for this resource
std::string identifier;
// The version of this resource
int version;
};
#include "httpsynchronization_codegen.cpp"
} // namespace
namespace openspace {
documentation::Documentation HttpSynchronization::Documentation() {
using namespace openspace::documentation;
return {
"HttpSynchronization",
"http_synchronization",
{
{
KeyIdentifier,
new StringVerifier,
Optional::No,
"A unique identifier for this resource"
},
{
KeyVersion,
new IntVerifier,
Optional::No,
"The version of this resource"
}
}
};
documentation::Documentation doc = codegen::doc<Parameters>();
doc.id = "http_synchronization";
return doc;
}
HttpSynchronization::HttpSynchronization(const ghoul::Dictionary& dict,
@@ -81,14 +71,10 @@ HttpSynchronization::HttpSynchronization(const ghoul::Dictionary& dict,
, _synchronizationRoot(std::move(synchronizationRoot))
, _synchronizationRepositories(std::move(synchronizationRepositories))
{
documentation::testSpecificationAndThrow(
Documentation(),
dict,
"HttpSynchronization"
);
const Parameters p = codegen::bake<Parameters>(dict);
_identifier = dict.value<std::string>(KeyIdentifier);
_version = static_cast<int>(dict.value<double>(KeyVersion));
_identifier = p.identifier;
_version = p.version;
}
HttpSynchronization::~HttpSynchronization() {
+49 -77
View File
@@ -37,6 +37,8 @@
#include <fstream>
#include <numeric>
#include <memory>
#include <optional>
#include <variant>
namespace {
constexpr const char* KeyUrl = "Url";
@@ -46,61 +48,44 @@ namespace {
constexpr const char* KeyFilename = "Filename";
constexpr const char* TempSuffix = ".tmp";
struct [[codegen::Dictionary(UrlSynchronization)]] Parameters {
// The URL or urls from where the files are downloaded. If multiple URLs are
// provided, all files will be downloaded to the same directory
std::variant<std::string, std::vector<std::string>> url;
// This optional identifier will be part of the used folder structure and, if
// provided, can be used to manually find the downloaded folder in the
// synchronization folder. If this value is not specified, 'UseHash' has to be set
// to 'true'
std::optional<std::string> identifier;
// If this value is set to 'true' and it is not overwritten by the global
// settings, the file(s) pointed to by this URLSynchronization will always be
// downloaded, thus overwriting the local files. This is useful for files that are
// updated regularly remotely and should be fetch at every startup
std::optional<bool> forceOverride [[codegen::key("override")]];
// If this value is set to 'true' (the default), the hash of the URL is appended
// to the directory name to produce a unique directory under all circumstances. If
// this is not desired, the URLSynchronization use the bare directory name alone
// if this value is 'false'. If this value is 'false', the identifier has to be
// specified
std::optional<bool> useHash;
// Optional to provide filename to override the one which is otherwise
// automatically created from the url
std::optional<std::string> filename;
};
#include "urlsynchronization_codegen.cpp"
} // namespace
namespace openspace {
documentation::Documentation UrlSynchronization::Documentation() {
using namespace openspace::documentation;
return {
"Url Synchronization",
"sync_synchronization_url",
{
{
KeyUrl,
new OrVerifier({ new StringVerifier, new StringListVerifier }),
Optional::No,
"The URL or urls from where the files are downloaded. If multiple URLs "
"are provided, all files will be downloaded to the same directory."
},
{
KeyIdentifier,
new StringVerifier,
Optional::Yes,
"This optional identifier will be part of the used folder structure and, "
"if provided, can be used to manually find the downloaded folder in the "
"synchronization folder. If this value is not specified, 'UseHash' has "
"to be set to 'true'."
},
{
KeyOverride,
new BoolVerifier,
Optional::Yes,
"If this value is set to 'true' and it is not overwritten by the global "
"settings, the file(s) pointed to by this URLSynchronization will always "
"be downloaded, thus overwriting the local files. This is useful for "
"files that are updated regularly remotely and should be fetch at every "
"startup."
},
{
KeyUseHash,
new BoolVerifier,
Optional::Yes,
"If this value is set to 'true' (the default), the hash of the URL is "
"appended to the directory name to produce a unique directory under all "
"circumstances. If this is not desired, the URLSynchronization use the "
"bare directory name alone if this value is 'false'. If this value is "
"'false', the identifier has to be specified."
},
{
KeyFilename,
new StringVerifier,
Optional::Yes,
"Optional to provide filename to override the one which is otherwise "
"automatically created from the url. "
}
}
};
documentation::Documentation doc = codegen::doc<Parameters>();
doc.id = "sync_synchronization_url";
return doc;
}
UrlSynchronization::UrlSynchronization(const ghoul::Dictionary& dict,
@@ -108,43 +93,33 @@ UrlSynchronization::UrlSynchronization(const ghoul::Dictionary& dict,
: ResourceSynchronization(dict)
, _synchronizationRoot(std::move(synchronizationRoot))
{
documentation::testSpecificationAndThrow(
Documentation(),
dict,
"UrlSynchroniztion"
);
const Parameters p = codegen::bake<Parameters>(dict);
if (dict.hasValue<std::string>(KeyUrl)) {
_urls.push_back(dict.value<std::string>(KeyUrl));
if (std::holds_alternative<std::string>(p.url)) {
_urls.push_back(std::get<std::string>(p.url));
}
else if (std::holds_alternative<std::vector<std::string>>(p.url)) {
_urls = std::get<std::vector<std::string>>(p.url);
}
else {
ghoul::Dictionary urls = dict.value<ghoul::Dictionary>(KeyUrl);
for (size_t i = 1; i <= urls.size(); ++i) {
std::string url = urls.value<std::string>(std::to_string(i));
_urls.push_back(std::move(url));
}
throw ghoul::MissingCaseException();
}
if (dict.hasValue<std::string>(KeyFilename)) {
_filename = dict.value<std::string>(KeyFilename);
}
_filename = p.filename.value_or(_filename);
bool useHash = true;
if (dict.hasValue<bool>(KeyUseHash)) {
useHash = dict.value<bool>(KeyUseHash);
}
bool useHash = p.useHash.value_or(true);
// We just merge all of the URLs together to generate a hash, it's not as stable to
// reordering URLs, but every other solution would be more error prone
std::string urlConcat = std::accumulate(_urls.begin(), _urls.end(), std::string());
size_t hash = std::hash<std::string>{}(urlConcat);
if (dict.hasValue<std::string>(KeyIdentifier)) {
std::string ident = dict.value<std::string>(KeyIdentifier);
if (p.identifier.has_value()) {
if (useHash) {
_identifier = std::move(ident) + "(" + std::to_string(hash) + ")";
_identifier = *p.identifier + "(" + std::to_string(hash) + ")";
}
else {
_identifier = std::move(ident);
_identifier = *p.identifier;
}
}
else {
@@ -162,9 +137,7 @@ UrlSynchronization::UrlSynchronization(const ghoul::Dictionary& dict,
}
}
if (dict.hasValue<bool>(KeyOverride)) {
_forceOverride = dict.value<bool>(KeyOverride);
}
_forceOverride = p.forceOverride.value_or(_forceOverride);
}
UrlSynchronization::~UrlSynchronization() {
@@ -193,7 +166,6 @@ void UrlSynchronization::start() {
std::vector<std::unique_ptr<AsyncHttpFileDownload>> downloads;
for (const std::string& url : _urls) {
if (_filename.empty()) {
const size_t lastSlash = url.find_last_of('/');
std::string lastPartOfUrl = url.substr(lastSlash + 1);