Skip to content

Commit

Permalink
Resources|libdoomsday: Multiple package folders via Config
Browse files Browse the repository at this point in the history
Improved management of data bundle links, with the capability to
recreate and re-identify all the bundles.

A new audience was added for observing the completion of the bundle
identifying operation.
  • Loading branch information
skyjake committed Jun 24, 2016
1 parent 04f22a7 commit c2a8199
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 51 deletions.
21 changes: 9 additions & 12 deletions doomsday/apps/libdoomsday/include/doomsday/doomsdayapp.h
Expand Up @@ -45,19 +45,13 @@ class Games;
class LIBDOOMSDAY_PUBLIC DoomsdayApp
{
public:
/**
* Notified before the current game is unloaded.
*/
/// Notified before the current game is unloaded.
DENG2_DEFINE_AUDIENCE2(GameUnload, void aboutToUnloadGame(Game const &gameBeingUnloaded))

/**
* Notified after the current game has been changed.
*/
/// Notified after the current game has been changed.
DENG2_DEFINE_AUDIENCE2(GameChange, void currentGameChanged(Game const &newGame))

/**
* Notified when console variables and commands should be registered.
*/
/// Notified when console variables and commands should be registered.
DENG2_DEFINE_AUDIENCE2(ConsoleRegistration, void consoleRegistration())

struct GameChangeParameters
Expand All @@ -69,6 +63,8 @@ class LIBDOOMSDAY_PUBLIC DoomsdayApp
public:
DoomsdayApp(Players::Constructor playerConstructor);

void determineGlobalPaths();

/**
* Initialize application state.
*/
Expand All @@ -80,9 +76,10 @@ class LIBDOOMSDAY_PUBLIC DoomsdayApp
*/
void initWadFolders();

void identifyDataBundles();

void determineGlobalPaths();
/**
* Initializes the /local/packs folder.
*/
void initPackageFolders();

enum Behavior
{
Expand Down
@@ -0,0 +1,43 @@
/** @file bundlelinkfeed.h FS feed for managing data bundle links.
*
* @authors Copyright (c) 2016 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#ifndef LIBDOOMSDAY_BUNDLELINKFEED_H
#define LIBDOOMSDAY_BUNDLELINKFEED_H

#include <de/Feed>

namespace res {

/**
* FS feed for maanging data bundle links.
*
* The main responsibility of the feed is to prune broken links.
*/
class BundleLinkFeed : public de::Feed
{
public:
BundleLinkFeed();

de::String description() const override;
void populate(de::Folder &folder) override;
bool prune(de::File &file) const override;
};

} // namespace res

#endif // LIBDOOMSDAY_BUNDLELINKFEED_H
Expand Up @@ -40,6 +40,9 @@ 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(Refresh, void dataBundlesRefreshed())

DENG2_ERROR(InvalidError);

struct LIBDOOMSDAY_PUBLIC MatchResult
Expand Down Expand Up @@ -69,8 +72,10 @@ class LIBDOOMSDAY_PUBLIC Bundles
* packages under the /sys/bundles folder.
*
* @see res::DataBundle::identifyPackages()
*
* @return @c true, if one or more bundles were identified.
*/
void identify();
bool identify();

/**
* Finds a matching entry in the registry for a given data bundle.
Expand Down
Expand Up @@ -72,8 +72,9 @@ class LIBDOOMSDAY_PUBLIC DataBundle : public de::IByteArray

/**
* Generates appropriate packages according to the contents of the data bundle.
* @return @c true, if the bundle was identid and linked as a package.
*/
void identifyPackages() const;
bool identifyPackages() const;

/**
* Determines if the data bundle has been identified and now available as a package
Expand Down
21 changes: 20 additions & 1 deletion doomsday/apps/libdoomsday/src/doomsdayapp.cpp
Expand Up @@ -24,6 +24,7 @@
#include "doomsday/filesys/fs_util.h"
#include "doomsday/resource/resources.h"
#include "doomsday/resource/bundles.h"
#include "doomsday/resource/bundlelinkfeed.h"
#include "doomsday/filesys/fs_main.h"
#include "doomsday/filesys/datafile.h"
#include "doomsday/filesys/datafolder.h"
Expand Down Expand Up @@ -294,6 +295,12 @@ DENG2_PIMPL(DoomsdayApp)
}
}

// Configured via GUI.
for (String path : App::config().getStringList("resource.packageFolder"))
{
attachPacksFeed("user-selected", path);
}

packs.populate();
}

Expand Down Expand Up @@ -369,7 +376,8 @@ void DoomsdayApp::initialize()

// "/sys/bundles" has package-like symlinks to files that are not in
// Doomsday 2 format but can be loaded as packages.
fs.makeFolder("/sys/bundles", FS::DontInheritFeeds);
fs.makeFolder("/sys/bundles", FS::DontInheritFeeds)
.attach(new res::BundleLinkFeed); // prunes expired symlinks

d->initialized = true;

Expand All @@ -388,6 +396,17 @@ void DoomsdayApp::initWadFolders()
}
}

void DoomsdayApp::initPackageFolders()
{
d->initPackageFolders();
d->dataBundles.identify();

if (d->initialized)
{
games().checkReadiness();
}
}

void DoomsdayApp::determineGlobalPaths()
{
d->determineGlobalPaths();
Expand Down
50 changes: 50 additions & 0 deletions doomsday/apps/libdoomsday/src/resource/bundlelinkfeed.cpp
@@ -0,0 +1,50 @@
/** @file bundlelinkfeed.cpp
*
* @authors Copyright (c) 2016 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#include "doomsday/resource/bundlelinkfeed.h"

#include <de/LinkFile>

using namespace de;

namespace res {

BundleLinkFeed::BundleLinkFeed()
{}

String BundleLinkFeed::description() const
{
return "data bundle links";
}

void BundleLinkFeed::populate(Folder &)
{
// Links are populated by DataBundle when files are identified.
}

bool BundleLinkFeed::prune(File &file) const
{
if (LinkFile const *link = file.maybeAs<LinkFile>())
{
// Broken links must be removed.
return link->isBroken();
}
return false;
}

} // namespace res
24 changes: 18 additions & 6 deletions doomsday/apps/libdoomsday/src/resource/bundles.cpp
Expand Up @@ -58,21 +58,26 @@ DENG2_PIMPL(Bundles)
}
}

void identifyAddedDataBundles()
bool identifyAddedDataBundles()
{
DENG2_ASSERT(App::rootFolder().has("/sys/bundles"));

bool wasIdentified = false;
Time startedAt;

LOG_RES_MSG("Identifying %i data bundles") << bundlesToIdentify.size();
for (DataBundle const *bundle : bundlesToIdentify)
{
DENG2_ASSERT(bundle);
bundle->identifyPackages();
if (bundle->identifyPackages())
{
wasIdentified = true;
}
}
bundlesToIdentify.clear();

LOG_RES_MSG("Data bundle identification took %.1f seconds") << startedAt.since();
return wasIdentified;
}

void parseRegistry()
Expand Down Expand Up @@ -117,8 +122,12 @@ DENG2_PIMPL(Bundles)
formatEntries[bundleFormat].append(&block);
}
}

DENG2_PIMPL_AUDIENCE(Refresh)
};

DENG2_AUDIENCE_METHOD(Bundles, Refresh)

Bundles::Bundles()
: d(new Instance(this))
{}
Expand All @@ -135,11 +144,14 @@ Bundles::BlockElements Bundles::formatEntries(DataBundle::Format format) const
return d->formatEntries[format];
}

void Bundles::identify()
bool Bundles::identify()
{
d->identifyAddedDataBundles();

//qDebug() << App::rootFolder().locate<Folder const>("/sys/bundles").contentsAsText();
bool const identified = d->identifyAddedDataBundles();
DENG2_FOR_AUDIENCE2(Refresh, i)
{
i->dataBundlesRefreshed();
}
return identified;
}

Bundles::MatchResult Bundles::match(DataBundle const &bundle) const
Expand Down

0 comments on commit c2a8199

Please sign in to comment.