Skip to content

Commit

Permalink
Resources|libdoomsday: Handling of .box contents
Browse files Browse the repository at this point in the history
Contained data bundles are now divided to three categories:
required, recommended, and extra. These are taken into account
(and checked for configured preferences) when a .box is loaded.
  • Loading branch information
skyjake committed Jul 5, 2016
1 parent f110dea commit 586cb84
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 18 deletions.
4 changes: 2 additions & 2 deletions doomsday/apps/libdoomsday/include/doomsday/resource/bundles.h
Expand Up @@ -40,8 +40,8 @@ class LIBDOOMSDAY_PUBLIC Bundles
public:
typedef QList<de::Info::BlockElement const *> BlockElements;

/// Notified when a data bundle refresh/identification has been made.
DENG2_DEFINE_AUDIENCE2(Identify, void dataBundlesIdentified(bool wereIdentified))
/// Notified when a data bundle refresh/identification has been completed.
DENG2_DEFINE_AUDIENCE2(Identify, void dataBundlesIdentified())

DENG2_ERROR(InvalidError);

Expand Down
Expand Up @@ -136,6 +136,8 @@ class LIBDOOMSDAY_PUBLIC DataBundle : public de::IByteArray
*/
static Format packageBundleFormat(de::String const &packageId);

static DataBundle const *bundleForPackage(de::String const &packageId);

protected:
void setFormat(Format format);

Expand Down
2 changes: 1 addition & 1 deletion doomsday/apps/libdoomsday/src/games.cpp
Expand Up @@ -122,7 +122,7 @@ DENG2_PIMPL(Games)
return nullptr;
}

void dataBundlesIdentified(bool)
void dataBundlesIdentified()
{
if (!mainCall)
{
Expand Down
62 changes: 57 additions & 5 deletions doomsday/apps/libdoomsday/src/resource/bundles.cpp
Expand Up @@ -21,6 +21,8 @@
#include "doomsday/filesys/datafolder.h"

#include <de/App>
#include <de/Config>
#include <de/DictionaryValue>
#include <de/PackageLoader>
#include <de/LinkFile>
#include <de/Loop>
Expand Down Expand Up @@ -191,10 +193,14 @@ void Bundles::identify()
{
d->tasks.start([this] ()
{
bool const identified = d->identifyAddedDataBundles();
DENG2_FOR_AUDIENCE2(Identify, i)
d->identifyAddedDataBundles();

if (isEverythingIdentified())
{
i->dataBundlesIdentified(identified);
DENG2_FOR_AUDIENCE2(Identify, i)
{
i->dataBundlesIdentified();
}
}
});
}
Expand Down Expand Up @@ -346,14 +352,60 @@ Bundles::MatchResult Bundles::match(DataBundle const &bundle) const

QList<DataBundle const *> Bundles::loaded() const
{
auto &loader = PackageLoader::get();
QList<DataBundle const *> loadedBundles;

// Collection contents enabled/disabled for use.
DictionaryValue const &selPkgs = Config::get()["resource.selectedPackages"].value<DictionaryValue>();

// Check all the loaded packages to see which ones are data bundles.
for (auto *f : App::packageLoader().loadedPackagesAsFilesInPackageOrder())
for (auto *f : loader.loadedPackagesAsFilesInPackageOrder())
{
if (DataBundle const *bundle = f->maybeAs<DataBundle>())
{
loadedBundles << bundle;
if (bundle->format() == DataBundle::Collection)
{
// Instead of adding the collection, check which contained packages are
// selected for loading.

auto isSelected = [bundle, &selPkgs] (TextValue const &id, bool byDefault) -> bool
{
TextValue const key(bundle->packageId());
if (selPkgs.contains(key)) {
auto const &sels = selPkgs.element(key).as<DictionaryValue>();
if (sels.contains(id)) {
return sels.element(id).isTrue();
}
}
return byDefault;
};

auto addToLoaded = [&loadedBundles] (String const &id)
{
if (DataBundle const *b = DataBundle::bundleForPackage(id)) {
loadedBundles << b;
}
};

Record const &meta = bundle->packageMetadata();
for (auto const *id : meta.geta("requires").elements())
{
addToLoaded(id->asText());
}
for (auto const *id : meta.geta("recommends").elements())
{
if (isSelected(id->asText(), true)) addToLoaded(id->asText());
}
for (auto const *id : meta.geta("extras").elements())
{
if (isSelected(id->asText(), false)) addToLoaded(id->asText());
}
}
else
{
// Non-collection data files are loaded as-is.
loadedBundles << bundle;
}
}
}

Expand Down
55 changes: 45 additions & 10 deletions doomsday/apps/libdoomsday/src/resource/databundle.cpp
Expand Up @@ -44,6 +44,10 @@ static String const VAR_AUTHOR ("author");
static String const VAR_TAGS ("tags");
static String const VAR_DATA_FILES ("dataFiles");
static String const VAR_BUNDLE_SCORE("bundleScore");
static String const VAR_REQUIRES ("requires");
static String const VAR_RECOMMENDS ("recommends");
static String const VAR_EXTRAS ("extras");
static String const VAR_CATEGORY ("category");

namespace internal
{
Expand All @@ -61,7 +65,7 @@ namespace internal
};
}

DENG2_PIMPL(DataBundle)
DENG2_PIMPL(DataBundle), public Lockable
{
bool ignored = false;
SafePtr<File> source;
Expand All @@ -76,6 +80,7 @@ DENG2_PIMPL(DataBundle)

~Impl()
{
DENG2_GUARD(this);
delete pkgLink.get();
}

Expand Down Expand Up @@ -134,6 +139,8 @@ DENG2_PIMPL(DataBundle)
*/
bool identify()
{
DENG2_GUARD(this);

// It is sufficient to identify each bundle only once.
if (ignored || !packageId.isEmpty()) return false;

Expand Down Expand Up @@ -187,6 +194,11 @@ DENG2_PIMPL(DataBundle)
else
{
meta.addArray(VAR_DATA_FILES);

// Collections have a number of subsets.
meta.addArray(VAR_REQUIRES);
meta.addArray(VAR_RECOMMENDS);
meta.addArray(VAR_EXTRAS);
}

if (isAutoLoaded())
Expand Down Expand Up @@ -383,12 +395,19 @@ DENG2_PIMPL(DataBundle)
container->isLinkedAsPackage() &&
container->format() == Collection)
{
if (isAutoLoaded()) /*||
Package::matchTags(container->d->pkgLink, "\\b(hidden|core|gamedata)\\b"))*/
//File &containerFile = *container->d->pkgLink;

String subset = VAR_RECOMMENDS;
String parentFolder = dataFilePath.fileNamePath().fileName();
if (!parentFolder.compareWithoutCase(QStringLiteral("Extra")))
{
subset = VAR_EXTRAS;
}
else if (!parentFolder.compareWithoutCase(QStringLiteral("Required")))
{
// Autoloaded data files are hidden.
metadata.appendUniqueWord(VAR_TAGS, "hidden");
subset = VAR_REQUIRES;
}
container->packageMetadata().appendToArray(subset, new TextValue(versionedPackageId));

/*
qDebug() << container->d->versionedPackageId
Expand All @@ -399,7 +418,7 @@ DENG2_PIMPL(DataBundle)
<< "from" << dataFilePath;
*/

Package::addRequiredPackage(*container->d->pkgLink, versionedPackageId);
//Package::addRequiredPackage(containerFile, versionedPackageId);
}
return true;
}
Expand Down Expand Up @@ -491,7 +510,6 @@ DENG2_PIMPL(DataBundle)
if (!component.compareWithoutCase("game-jdoom"))
{
meta.appendUniqueWord(VAR_TAGS, "doom");
meta.appendUniqueWord(VAR_TAGS, "doom2");
}
else if (!component.compareWithoutCase("game-jheretic"))
{
Expand All @@ -503,6 +521,13 @@ DENG2_PIMPL(DataBundle)
}
}

String category = rootBlock.keyValue("category");
if (!category.isEmpty())
{
meta.appendUniqueWord(VAR_TAGS, category);
meta.set(VAR_CATEGORY, category);
}

if (Info::BlockElement const *english = rootBlock.findAs<Info::BlockElement>("english"))
{
if(english->blockType() == "language")
Expand Down Expand Up @@ -762,16 +787,26 @@ Record const &DataBundle::objectNamespace() const
return asFile().objectNamespace().subrecord(QStringLiteral("package"));
}

DataBundle::Format DataBundle::packageBundleFormat(String const &packageId)
DataBundle::Format DataBundle::packageBundleFormat(String const &packageId) // static
{
if (auto const *bundle = bundleForPackage(packageId))
{
Guard g(bundle->d);
return bundle->format();
}
return Unknown;
}

DataBundle const *DataBundle::bundleForPackage(String const &packageId) // static
{
if (File const *file = PackageLoader::get().select(packageId))
{
if (auto const *bundle = file->target().maybeAs<DataBundle>())
{
return bundle->format();
return bundle;
}
}
return Unknown;
return nullptr;
}

void DataBundle::setFormat(Format format)
Expand Down

0 comments on commit 586cb84

Please sign in to comment.