Skip to content

Commit

Permalink
libcore|FS: Keeping track of the version of loaded packages
Browse files Browse the repository at this point in the history
The version is kept in Package for querying later. Both the file name
and the metadata are checked.
  • Loading branch information
skyjake committed Jan 20, 2017
1 parent 81e43cc commit d3eb057
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 5 deletions.
7 changes: 7 additions & 0 deletions doomsday/sdk/libcore/include/de/filesys/package.h
Expand Up @@ -121,6 +121,12 @@ class DENG2_PUBLIC Package : public IObject
*/
String identifier() const;

/**
* Version of the loaded package. The version can be specified either in the
* file name (following an underscore) or in the metadata.
*/
Version version() const;

/**
* Composes a list of assets contained in the package.
*
Expand Down Expand Up @@ -236,6 +242,7 @@ class DENG2_PUBLIC Package : public IObject
static String const VAR_PACKAGE_TITLE;
static String const VAR_ID;
static String const VAR_TITLE;
static String const VAR_VERSION;

private:
DENG2_PRIVATE(d)
Expand Down
36 changes: 33 additions & 3 deletions doomsday/sdk/libcore/src/filesys/package.cpp
Expand Up @@ -27,6 +27,8 @@
#include "de/ScriptedInfo"
#include "de/TimeValue"

#include <QRegularExpression>

namespace de {

String const Package::VAR_PACKAGE ("package");
Expand All @@ -35,6 +37,7 @@ String const Package::VAR_PACKAGE_ALIAS("package.alias");
String const Package::VAR_PACKAGE_TITLE("package.title");
String const Package::VAR_ID ("ID");
String const Package::VAR_TITLE ("title");
String const Package::VAR_VERSION ("version");

static String const PACKAGE_ORDER ("package.__order__");
static String const PACKAGE_IMPORT_PATH("package.importPath");
Expand All @@ -45,6 +48,7 @@ static String const PACKAGE_TAGS ("package.tags");

static String const VAR_ID ("ID");
static String const VAR_PATH("path");
static String const VAR_TAGS("tags");

Package::Asset::Asset(Record const &rec) : RecordAccessor(rec) {}

Expand All @@ -66,12 +70,23 @@ DENG2_PIMPL(Package)
, DENG2_OBSERVES(File, Deletion)
{
File const *file;
Version version; // version of the loaded package

Impl(Public *i, File const *f)
: Base(i)
, file(f)
{
if (file) file->audienceForDeletion() += this;
if (file)
{
file->audienceForDeletion() += this;

// Check the file name first, then metadata.
version = split(versionedIdentifierForFile(*file)).second;
if (!version.isValid())
{
version = Version(metadata(*file).gets(VAR_VERSION, String()));
}
}
}

void fileBeingDeleted(File const &)
Expand Down Expand Up @@ -153,9 +168,14 @@ String Package::identifier() const
return identifierForFile(*d->file);
}

Version Package::version() const
{
return d->version;
}

Package::Assets Package::assets() const
{
return ScriptedInfo::allBlocksOfType("asset", d->packageInfo());
return ScriptedInfo::allBlocksOfType(QStringLiteral("asset"), d->packageInfo());
}

bool Package::executeFunction(String const &name)
Expand Down Expand Up @@ -309,7 +329,7 @@ void Package::validateMetadata(Record const &packageInfo)
.arg(packageInfo.gets("path")));
}

static String const required[] = { "title", "version", "license", "tags" };
static String const required[] = { "title", "version", "license", VAR_TAGS };
for (auto const &req : required)
{
if (!packageInfo.has(req))
Expand All @@ -320,6 +340,16 @@ void Package::validateMetadata(Record const &packageInfo)
.arg(req));
}
}

static QRegularExpression const regexReservedTags("\\b(loaded)\\b");
auto match = regexReservedTags.match(packageInfo.gets(VAR_TAGS));
if (match.hasMatch())
{
throw ValidationError("Package::validateMetadata",
QString("Package \"%1\" has a tag that is reserved for internal use (%2)")
.arg(packageInfo.gets("path"))
.arg(match.captured(1)));
}
}

Record &Package::initializeMetadata(File &packageFile, String const &id)
Expand Down
12 changes: 10 additions & 2 deletions doomsday/sdk/libcore/src/filesys/packageloader.cpp
Expand Up @@ -39,7 +39,7 @@ static String const VAR_PACKAGE_VERSION("package.version");

DENG2_PIMPL(PackageLoader)
{
LoadedPackages loaded;
LoadedPackages loaded; ///< Identifiers are unversioned; only one version can be loaded at a time.
int loadCounter;

Impl(Public *i) : Base(i), loadCounter(0)
Expand Down Expand Up @@ -464,7 +464,15 @@ void PackageLoader::unloadAll()

bool PackageLoader::isLoaded(String const &packageId) const
{
return d->loaded.contains(packageId);
// Split ID, check version too if specified.
auto const id_ver = Package::split(packageId);
auto found = d->loaded.constFind(id_ver.first);
if (found == d->loaded.constEnd())
{
return false;
}
return (!id_ver.second.isValid() /* no valid version provided in argumnet */ ||
id_ver.second == found.value()->version());
}

bool PackageLoader::isLoaded(File const &file) const
Expand Down

0 comments on commit d3eb057

Please sign in to comment.