mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-21 12:29:04 -06:00
Asset work in progress
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
#include <openspace/util/taskloader.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/resourcesynchronization.h>
|
||||
#include <openspace/util/task.h>
|
||||
#include <openspace/scene/translation.h>
|
||||
#include <openspace/scene/rotation.h>
|
||||
@@ -91,7 +92,7 @@ void performTasks(const std::string& path) {
|
||||
);
|
||||
ProgressBar progressBar(100);
|
||||
auto onProgress = [&progressBar](float progress) {
|
||||
progressBar.print(progress * 100);
|
||||
progressBar.print(static_cast<int>(progress * 100.f));
|
||||
};
|
||||
task.perform(onProgress);
|
||||
}
|
||||
@@ -145,13 +146,28 @@ int main(int argc, char** argv) {
|
||||
std::make_unique<ghoul::TemplateFactory<Scale>>(),
|
||||
"Scale"
|
||||
);
|
||||
FactoryManager::ref().addFactory(
|
||||
std::make_unique<ghoul::TemplateFactory<ResourceSynchronization>>(),
|
||||
"ResourceSynchronization"
|
||||
);
|
||||
|
||||
|
||||
openspace::ConfigurationManager configuration;
|
||||
std::string configurationFile = configuration.findConfiguration(ConfigurationFile);
|
||||
configuration.loadFromFile(configurationFile);
|
||||
|
||||
ghoul::Dictionary moduleConfigurations;
|
||||
if (configuration.hasKeyAndValue<ghoul::Dictionary>(
|
||||
ConfigurationManager::KeyModuleConfigurations))
|
||||
{
|
||||
configuration.getValue<ghoul::Dictionary>(
|
||||
ConfigurationManager::KeyModuleConfigurations,
|
||||
moduleConfigurations
|
||||
);
|
||||
}
|
||||
|
||||
ModuleEngine moduleEngine;
|
||||
moduleEngine.initialize();
|
||||
moduleEngine.initialize(moduleConfigurations);
|
||||
LINFO("Initialization done.");
|
||||
|
||||
// Parse commandline arguments
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
dofile(openspace.absPath('${SCRIPTS}/bind_common_keys.lua'));
|
||||
asset.onInitialize(function()
|
||||
dofile(openspace.absPath('${SCRIPTS}/bind_common_keys.lua'));
|
||||
end)
|
||||
@@ -120,8 +120,6 @@ public:
|
||||
static const std::string KeyRenderingMethod;
|
||||
/// The key that determines whether a new cache folder is used for each scene file
|
||||
static const std::string KeyPerSceneCache;
|
||||
// The key that stores the list of urls to http resource sync repositories
|
||||
static const std::string KeyHttpSynchronizationRepositories;
|
||||
/// The key that stores the http proxy settings for the downloadmanager
|
||||
static const std::string KeyHttpProxy;
|
||||
/// The key that stores the address of the http proxy
|
||||
@@ -168,6 +166,8 @@ public:
|
||||
/// The part of the key storing whether the loading screen should contain a progress
|
||||
/// bar
|
||||
static const std::string PartShowProgressbar;
|
||||
/// The key used to specify module specific configurations
|
||||
static const std::string KeyModuleConfigurations;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
* \throw ghoul::RuntimeError If two modules in the default modules have the same
|
||||
* name
|
||||
*/
|
||||
void initialize();
|
||||
void initialize(const ghoul::Dictionary& moduleConfigurations);
|
||||
|
||||
/**
|
||||
* Deinitializes all of the contained OpenSpaceModule%s by calling the
|
||||
@@ -72,7 +72,8 @@ public:
|
||||
* previously
|
||||
* \pre \p module must not be nullptr
|
||||
*/
|
||||
void registerModule(std::unique_ptr<OpenSpaceModule> module);
|
||||
void registerModule(std::unique_ptr<OpenSpaceModule> module,
|
||||
const ghoul::Dictionary& configuration);
|
||||
|
||||
/**
|
||||
* Returns a list of all registered OpenSpaceModule%s that have been registered with
|
||||
|
||||
@@ -99,7 +99,8 @@ public:
|
||||
bool cancelAllSynchronizations();
|
||||
bool cancelUnwantedSynchronizations();
|
||||
bool restartAllSynchronizations();
|
||||
float synchronizationProgress();
|
||||
float requestedSynchronizationProgress();
|
||||
float requiredSynchronizationProgress();
|
||||
|
||||
// Init
|
||||
bool hasInitializedParent() const;
|
||||
|
||||
@@ -189,6 +189,8 @@ protected:
|
||||
bool initDownload() override;
|
||||
bool deinitDownload() override;
|
||||
size_t handleData(HttpRequest::Data d) override;
|
||||
|
||||
static std::mutex _directoryCreationMutex;
|
||||
private:
|
||||
std::string _destination;
|
||||
std::ofstream _file;
|
||||
|
||||
@@ -34,9 +34,13 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ghoul { class Dictionary; }
|
||||
|
||||
namespace openspace {
|
||||
namespace documentation { struct Documentation; }
|
||||
|
||||
class ModuleEngine;
|
||||
|
||||
/**
|
||||
* This class is the base class for an OpenSpace module. A module groups functionality
|
||||
* into a useful granularity to be mostly used self-sufficiently. Each OpenSpaceModule
|
||||
@@ -61,7 +65,8 @@ public:
|
||||
* is set in the OpenSpaceModule constructor. This method will call the
|
||||
* internalInitialize method for further customization for each subclass.
|
||||
*/
|
||||
void initialize();
|
||||
void initialize(const ModuleEngine* moduleEngine,
|
||||
const ghoul::Dictionary& configuration);
|
||||
|
||||
/**
|
||||
* Empty deinitialization method that will call the internalDeinitialize method for
|
||||
@@ -96,6 +101,12 @@ protected:
|
||||
*/
|
||||
virtual void internalInitialize();
|
||||
|
||||
/**
|
||||
* Customization point for each derived class. The internalInitialize method is called
|
||||
* by the initiailze method.
|
||||
*/
|
||||
virtual void internalInitialize(const ghoul::Dictionary& configuration);
|
||||
|
||||
/**
|
||||
* Customization point for each derived class. The internalDeinitialize method is
|
||||
* called by the deinitialize method.
|
||||
@@ -107,6 +118,14 @@ protected:
|
||||
* path tokens.
|
||||
*/
|
||||
std::string modulePath() const;
|
||||
|
||||
/**
|
||||
* Returns a const pointer to the module engine
|
||||
*/
|
||||
const ModuleEngine* moduleEngine() const;
|
||||
|
||||
private:
|
||||
const ModuleEngine* _moduleEngine;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -36,6 +36,12 @@
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct SynchronizationConfiguration {
|
||||
std::string syncRoot;
|
||||
std::vector<std::string> httpRepositories;
|
||||
bool allowSynchronization;
|
||||
};
|
||||
|
||||
class ResourceSynchronization
|
||||
: public std::enable_shared_from_this<ResourceSynchronization>
|
||||
{
|
||||
@@ -55,6 +61,7 @@ public:
|
||||
const ghoul::Dictionary& dictionary);
|
||||
|
||||
ResourceSynchronization();
|
||||
void configure(std::shared_ptr<SynchronizationConfiguration> config);
|
||||
virtual ~ResourceSynchronization();
|
||||
virtual std::string directory() = 0;
|
||||
virtual void start() = 0;
|
||||
|
||||
@@ -100,7 +100,7 @@ void GuiAssetComponent::renderTree(const std::shared_ptr<openspace::Asset> asset
|
||||
|
||||
if (asset->state() == Asset::State::Synchronizing) {
|
||||
assetText += " (" + std::to_string(
|
||||
static_cast<int>(asset->synchronizationProgress() * 100)
|
||||
static_cast<int>(asset->requiredSynchronizationProgress() * 100)
|
||||
) + "%%)";
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/torrentclient.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/syncs/httpsynchronization.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/syncs/torrentsynchronization.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/syncassettask.h
|
||||
)
|
||||
source_group("Header Files" FILES ${HEADER_FILES})
|
||||
|
||||
@@ -37,6 +38,7 @@ set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/torrentclient.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/syncs/httpsynchronization.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/syncs/torrentsynchronization.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/syncassettask.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <modules/sync/syncs/httpsynchronization.h>
|
||||
#include <modules/sync/syncs/torrentsynchronization.h>
|
||||
|
||||
#include <modules/sync/tasks/syncassettask.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
@@ -39,36 +41,73 @@
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
namespace {
|
||||
const char* KeyHttpSynchronizationRepositories = "HttpSynchronizationRepositories";
|
||||
const char* KeySynchronizationRoot = "SynchronizationRoot";
|
||||
|
||||
const char* _loggerCat = "SyncModule";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
SyncModule::SyncModule()
|
||||
: OpenSpaceModule(Name)
|
||||
{}
|
||||
|
||||
void SyncModule::internalInitialize() {
|
||||
void SyncModule::internalInitialize(const ghoul::Dictionary& configuration) {
|
||||
|
||||
if (configuration.hasKey(KeyHttpSynchronizationRepositories))
|
||||
{
|
||||
ghoul::Dictionary dictionary = configuration.value<ghoul::Dictionary>(
|
||||
KeyHttpSynchronizationRepositories);
|
||||
|
||||
for (std::string key : dictionary.keys()) {
|
||||
_httpSynchronizationRepositories.push_back(
|
||||
dictionary.value<std::string>(key)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (configuration.hasKey(KeySynchronizationRoot)) {
|
||||
_synchronizationRoot = configuration.value<std::string>(KeySynchronizationRoot);
|
||||
} else {
|
||||
LWARNING("No synchronization root specified. Resource synchronization will be disabled.");
|
||||
//_synchronizationEnabled = false;
|
||||
// TODO: Make it possible to disable synchronization manyally.
|
||||
// Group root and enabled into a sync config object that can be passed to syncs.
|
||||
}
|
||||
|
||||
auto fSynchronization = FactoryManager::ref().factory<ResourceSynchronization>();
|
||||
ghoul_assert(fSynchronization, "ResourceSynchronization factory was not created");
|
||||
|
||||
fSynchronization->registerClass<HttpSynchronization>("HttpSynchronization");
|
||||
fSynchronization->registerClass<TorrentSynchronization>("TorrentSynchronization");
|
||||
|
||||
_synchronizationRoot = FileSys.absPath("${SYNC}");
|
||||
_torrentClient.initialize();
|
||||
|
||||
if (!OsEng.configurationManager().hasKey(
|
||||
ConfigurationManager::KeyHttpSynchronizationRepositories))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ghoul::Dictionary dictionary = OsEng.configurationManager().value<ghoul::Dictionary>(
|
||||
ConfigurationManager::KeyHttpSynchronizationRepositories
|
||||
);
|
||||
for (std::string key : dictionary.keys()) {
|
||||
_httpSynchronizationRepositories.push_back(
|
||||
dictionary.value<std::string>(key)
|
||||
fSynchronization->registerClass(
|
||||
"HttpSynchronization",
|
||||
[this](bool, const ghoul::Dictionary& dictionary) {
|
||||
return new HttpSynchronization(
|
||||
dictionary,
|
||||
_synchronizationRoot,
|
||||
_httpSynchronizationRepositories
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
fSynchronization->registerClass(
|
||||
"TorrentSynchronization",
|
||||
[this](bool, const ghoul::Dictionary& dictionary) {
|
||||
return new TorrentSynchronization(
|
||||
dictionary,
|
||||
_synchronizationRoot,
|
||||
&_torrentClient
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
auto fTask = FactoryManager::ref().factory<Task>();
|
||||
ghoul_assert(fTask, "No task factory existed");
|
||||
fTask->registerClass<SyncAssetTask>("SyncAssetTask");
|
||||
|
||||
_torrentClient.initialize();
|
||||
}
|
||||
|
||||
std::vector<documentation::Documentation> SyncModule::documentations() const {
|
||||
@@ -83,6 +122,10 @@ std::string SyncModule::synchronizationRoot() const
|
||||
return _synchronizationRoot;
|
||||
}
|
||||
|
||||
void SyncModule::addHttpSynchronizationRepository(const std::string& repository) {
|
||||
_httpSynchronizationRepositories.push_back(repository);
|
||||
}
|
||||
|
||||
std::vector<std::string> SyncModule::httpSynchronizationRepositories() const {
|
||||
return _httpSynchronizationRepositories;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*****************************************************************************************
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
@@ -38,10 +38,11 @@ public:
|
||||
virtual ~SyncModule() = default;
|
||||
std::vector<documentation::Documentation> documentations() const override;
|
||||
std::string synchronizationRoot() const;
|
||||
void addHttpSynchronizationRepository(const std::string& repository);
|
||||
std::vector<std::string> httpSynchronizationRepositories() const;
|
||||
TorrentClient* torrentClient();
|
||||
protected:
|
||||
void internalInitialize() override;
|
||||
void internalInitialize(const ghoul::Dictionary& configuration) override;
|
||||
private:
|
||||
TorrentClient _torrentClient;
|
||||
std::vector<std::string> _httpSynchronizationRepositories;
|
||||
|
||||
@@ -52,8 +52,14 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
HttpSynchronization::HttpSynchronization(const ghoul::Dictionary& dict)
|
||||
HttpSynchronization::HttpSynchronization(
|
||||
const ghoul::Dictionary& dict,
|
||||
const std::string& synchronizationRoot,
|
||||
const std::vector<std::string>& synchronizationRepositories
|
||||
)
|
||||
: openspace::ResourceSynchronization()
|
||||
, _synchronizationRoot(synchronizationRoot)
|
||||
, _synchronizationRepositories(synchronizationRepositories)
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
@@ -63,13 +69,6 @@ HttpSynchronization::HttpSynchronization(const ghoul::Dictionary& dict)
|
||||
|
||||
_identifier = dict.value<std::string>(KeyIdentifier);
|
||||
_version = static_cast<int>(dict.value<double>(KeyVersion));
|
||||
|
||||
// Configure synchronization based on global settings in SyncModule
|
||||
// TODO: For testability and decreaing deps, make it possible to inject this instead.
|
||||
// For example, allow this configuration to be done by the TemplateFactory.
|
||||
const SyncModule* syncModule = OsEng.moduleEngine().module<SyncModule>();
|
||||
_synchronizationRoot = syncModule->synchronizationRoot();
|
||||
_synchronizationRepositories = syncModule->httpSynchronizationRepositories();
|
||||
}
|
||||
|
||||
HttpSynchronization::~HttpSynchronization() {
|
||||
|
||||
@@ -34,7 +34,12 @@ namespace openspace {
|
||||
|
||||
class HttpSynchronization : public ResourceSynchronization {
|
||||
public:
|
||||
HttpSynchronization(const ghoul::Dictionary& dict);
|
||||
HttpSynchronization(
|
||||
const ghoul::Dictionary& dict,
|
||||
const std::string& synchronizationRoot,
|
||||
const std::vector<std::string>& synchronizationRepositories
|
||||
);
|
||||
|
||||
virtual ~HttpSynchronization();
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
@@ -54,9 +59,9 @@ private:
|
||||
bool hasSyncFile();
|
||||
void createSyncFile();
|
||||
|
||||
std::atomic_bool _nTotalBytesKnown;
|
||||
std::atomic_size_t _nTotalBytes;
|
||||
std::atomic_size_t _nSynchronizedBytes;
|
||||
std::atomic_bool _nTotalBytesKnown = false;
|
||||
std::atomic_size_t _nTotalBytes = 0;
|
||||
std::atomic_size_t _nSynchronizedBytes = 0;
|
||||
|
||||
std::atomic_bool _shouldCancel = false;
|
||||
std::string _identifier;
|
||||
|
||||
@@ -45,8 +45,12 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
TorrentSynchronization::TorrentSynchronization(const ghoul::Dictionary& dict)
|
||||
TorrentSynchronization::TorrentSynchronization(const ghoul::Dictionary& dict,
|
||||
const std::string& synchronizationRoot,
|
||||
TorrentClient* torrentClient)
|
||||
: openspace::ResourceSynchronization()
|
||||
, _synchronizationRoot(synchronizationRoot)
|
||||
, _torrentClient(torrentClient)
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
@@ -56,13 +60,10 @@ TorrentSynchronization::TorrentSynchronization(const ghoul::Dictionary& dict)
|
||||
|
||||
_identifier = dict.value<std::string>(KeyIdentifier);
|
||||
_magnetLink = dict.value<std::string>(KeyMagnet);
|
||||
}
|
||||
|
||||
// Configure synchronization based on global settings in SyncModule
|
||||
// TODO: For testability and decreaing deps, make it possible to inject this instead.
|
||||
// For example, allow this configuration to be done by the TemplateFactory.
|
||||
SyncModule* syncModule = OsEng.moduleEngine().module<SyncModule>();
|
||||
_synchronizationRoot = syncModule->synchronizationRoot();
|
||||
_torrentClient = syncModule->torrentClient();
|
||||
TorrentSynchronization::~TorrentSynchronization() {
|
||||
cancel();
|
||||
}
|
||||
|
||||
documentation::Documentation TorrentSynchronization::Documentation() {
|
||||
@@ -160,18 +161,22 @@ void TorrentSynchronization::createSyncFile() {
|
||||
}
|
||||
|
||||
size_t TorrentSynchronization::nSynchronizedBytes() {
|
||||
std::lock_guard<std::mutex> g(_progressMutex);
|
||||
return _progress.nDownloadedBytes;
|
||||
}
|
||||
|
||||
size_t TorrentSynchronization::nTotalBytes() {
|
||||
std::lock_guard<std::mutex> g(_progressMutex);
|
||||
return _progress.nTotalBytes;
|
||||
}
|
||||
|
||||
bool TorrentSynchronization::nTotalBytesIsKnown() {
|
||||
std::lock_guard<std::mutex> g(_progressMutex);
|
||||
return _progress.nTotalBytesKnown;
|
||||
}
|
||||
|
||||
void TorrentSynchronization::updateTorrentProgress(TorrentClient::TorrentProgress progress) {
|
||||
std::lock_guard<std::mutex> g(_progressMutex);
|
||||
_progress = progress;
|
||||
if (progress.finished && state() == State::Syncing) {
|
||||
createSyncFile();
|
||||
|
||||
@@ -43,7 +43,12 @@ class TorrentSynchronizationJob;
|
||||
|
||||
class TorrentSynchronization : public ResourceSynchronization {
|
||||
public:
|
||||
TorrentSynchronization(const ghoul::Dictionary& dict);
|
||||
TorrentSynchronization(const ghoul::Dictionary& dict,
|
||||
const std::string& synchronizationRoot,
|
||||
TorrentClient* client);
|
||||
|
||||
|
||||
virtual ~TorrentSynchronization();
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
std::string directory() override;
|
||||
@@ -64,6 +69,7 @@ private:
|
||||
std::atomic_bool _enabled = false;
|
||||
size_t _torrentId;
|
||||
TorrentClient::TorrentProgress _progress;
|
||||
std::mutex _progressMutex;
|
||||
std::string _identifier;
|
||||
std::string _magnetLink;
|
||||
std::string _synchronizationRoot;
|
||||
|
||||
@@ -91,7 +91,7 @@ void TorrentClient::pollAlerts() {
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
_session->pop_alerts(&alerts);
|
||||
}
|
||||
|
||||
|
||||
for (lt::alert const* a : alerts) {
|
||||
//LINFO(a->message());
|
||||
// if we receive the finished alert or an error, we're done
|
||||
|
||||
@@ -112,6 +112,10 @@ TouchModule::TouchModule()
|
||||
addPropertySubOwner(touch);
|
||||
addPropertySubOwner(markers);
|
||||
|
||||
if (!OpenSpaceEngine::isCreated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
OsEng.registerModuleCallback(
|
||||
OpenSpaceEngine::CallbackOption::InitializeGL,
|
||||
[&]() {
|
||||
|
||||
@@ -95,8 +95,13 @@ return {
|
||||
-- PerSceneCache = true,
|
||||
-- DisableRenderingOnMaster = true,
|
||||
-- DisableSceneOnMaster = true,
|
||||
HttpSynchronizationRepositories = {
|
||||
"data.openspaceproject.com/request"
|
||||
ModuleConfigurations = {
|
||||
Sync = {
|
||||
SynchronizationRoot = "${SYNC}",
|
||||
HttpSynchronizationRepositories = {
|
||||
"data.openspaceproject.com/request"
|
||||
}
|
||||
}
|
||||
},
|
||||
RenderingMethod = "Framebuffer",
|
||||
OpenGLDebugContext = {
|
||||
|
||||
@@ -86,8 +86,6 @@ const string ConfigurationManager::KeyRenderingMethod = "RenderingMethod";
|
||||
|
||||
const string ConfigurationManager::KeyOnScreenTextScaling = "OnScreenTextScaling";
|
||||
|
||||
const string ConfigurationManager::KeyHttpSynchronizationRepositories = "HttpSynchronizationRepositories";
|
||||
|
||||
const string ConfigurationManager::KeyHttpProxy = "HttpProxy";
|
||||
const string ConfigurationManager::PartHttpProxyAddress = "Address";
|
||||
const string ConfigurationManager::PartHttpProxyPort = "Port";
|
||||
@@ -114,6 +112,8 @@ const string ConfigurationManager::PartShowMessage = "ShowMessage";
|
||||
const string ConfigurationManager::PartShowNodeNames = "ShowNodeNames";
|
||||
const string ConfigurationManager::PartShowProgressbar = "ShowProgressbar";
|
||||
|
||||
const string ConfigurationManager::KeyModuleConfigurations = "ModuleConfigurations";
|
||||
|
||||
string ConfigurationManager::findConfiguration(const string& filename) {
|
||||
using ghoul::filesystem::Directory;
|
||||
|
||||
|
||||
@@ -284,13 +284,6 @@ documentation::Documentation ConfigurationManager::Documentation() {
|
||||
"interaction and it is thus desired to disable the transformation. The "
|
||||
"default is false."
|
||||
},
|
||||
{
|
||||
ConfigurationManager::KeyHttpSynchronizationRepositories,
|
||||
new StringListVerifier("URLs to http synchronization repositories"),
|
||||
Optional::Yes,
|
||||
"Configures the list of http synchronization repositories to load "
|
||||
"resources from. The first URL will be tried first."
|
||||
},
|
||||
{
|
||||
ConfigurationManager::KeyHttpProxy,
|
||||
new TableVerifier({
|
||||
@@ -462,6 +455,12 @@ documentation::Documentation ConfigurationManager::Documentation() {
|
||||
Optional::Yes,
|
||||
"Values in this table describe the behavior of the loading screen that is "
|
||||
"displayed while the scene graph is created and initialized."
|
||||
},
|
||||
{
|
||||
ConfigurationManager::KeyModuleConfigurations,
|
||||
new TableVerifier,
|
||||
Optional::Yes,
|
||||
"Configurations for each module"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -40,9 +41,14 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
void ModuleEngine::initialize() {
|
||||
void ModuleEngine::initialize(const ghoul::Dictionary& moduleConfigurations) {
|
||||
for (OpenSpaceModule* m : AllModules()) {
|
||||
registerModule(std::unique_ptr<OpenSpaceModule>(m));
|
||||
const std::string name = m->name();
|
||||
ghoul::Dictionary configuration;
|
||||
if (moduleConfigurations.hasKey(name)) {
|
||||
moduleConfigurations.getValue(name, configuration);
|
||||
}
|
||||
registerModule(std::unique_ptr<OpenSpaceModule>(m), configuration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +62,9 @@ void ModuleEngine::deinitialize() {
|
||||
LDEBUG("Finished destroying modules");
|
||||
}
|
||||
|
||||
void ModuleEngine::registerModule(std::unique_ptr<OpenSpaceModule> m) {
|
||||
void ModuleEngine::registerModule(std::unique_ptr<OpenSpaceModule> m,
|
||||
const ghoul::Dictionary& configuration)
|
||||
{
|
||||
ghoul_assert(m, "Module must not be nullptr");
|
||||
|
||||
auto it = std::find_if(
|
||||
@@ -74,7 +82,7 @@ void ModuleEngine::registerModule(std::unique_ptr<OpenSpaceModule> m) {
|
||||
}
|
||||
|
||||
LDEBUG("Registering module '" << m->name() << "'");
|
||||
m->initialize();
|
||||
m->initialize(this, configuration);
|
||||
LDEBUG("Registered module '" << m->name() << "'");
|
||||
_modules.push_back(std::move(m));
|
||||
}
|
||||
|
||||
@@ -375,8 +375,18 @@ void OpenSpaceEngine::create(int argc, char** argv,
|
||||
" (" << OPENSPACE_VERSION_STRING << ")"
|
||||
);
|
||||
|
||||
ghoul::Dictionary moduleConfigurations;
|
||||
if (_engine->configurationManager().hasKeyAndValue<ghoul::Dictionary>(
|
||||
ConfigurationManager::KeyModuleConfigurations))
|
||||
{
|
||||
_engine->configurationManager().getValue<ghoul::Dictionary>(
|
||||
ConfigurationManager::KeyModuleConfigurations,
|
||||
moduleConfigurations
|
||||
);
|
||||
}
|
||||
|
||||
// Register modules
|
||||
_engine->_moduleEngine->initialize();
|
||||
_engine->_moduleEngine->initialize(moduleConfigurations);
|
||||
|
||||
// After registering the modules, the documentations for the available classes
|
||||
// can be added as well
|
||||
|
||||
@@ -32,6 +32,31 @@
|
||||
|
||||
namespace {
|
||||
const char* _loggerCat = "Asset";
|
||||
|
||||
float syncProgress(std::vector<std::shared_ptr<openspace::Asset>> assets) {
|
||||
size_t nTotalBytes = 0;
|
||||
size_t nSyncedBytes = 0;
|
||||
|
||||
for (const auto& a : assets) {
|
||||
const std::vector<std::shared_ptr<openspace::ResourceSynchronization>> syncs =
|
||||
a->ownSynchronizations();
|
||||
|
||||
for (const auto& sync : syncs) {
|
||||
if (sync->nTotalBytesIsKnown()) {
|
||||
nTotalBytes += sync->nTotalBytes();
|
||||
nSyncedBytes += sync->nSynchronizedBytes();
|
||||
} else if (sync->isSyncing()) {
|
||||
// A resource is still synchronizing but its size is unknown.
|
||||
// Impossible to know the global progress.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nTotalBytes == 0) {
|
||||
return 0.f;
|
||||
}
|
||||
return static_cast<float>(nSyncedBytes) / static_cast<float>(nTotalBytes);
|
||||
}
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
@@ -96,6 +121,9 @@ void Asset::setState(Asset::State state) {
|
||||
}
|
||||
|
||||
void Asset::requiredAssetChangedState(std::shared_ptr<Asset> child) {
|
||||
ghoul_assert(!isInitialized(),
|
||||
"Required asset changing state while parent asset is initialized");
|
||||
|
||||
State childState = child->state();
|
||||
if (childState == State::SyncResolved) {
|
||||
if (isSyncResolveReady()) {
|
||||
@@ -135,6 +163,9 @@ void Asset::addSynchronization(std::shared_ptr<ResourceSynchronization> synchron
|
||||
void Asset::syncStateChanged(std::shared_ptr<ResourceSynchronization> synchronization,
|
||||
ResourceSynchronization::State state)
|
||||
{
|
||||
ghoul_assert(!isInitialized(),
|
||||
"Synchronization changing state while asset is initialized");
|
||||
|
||||
if (state == ResourceSynchronization::State::Resolved) {
|
||||
if (!isSynchronized() && isSyncResolveReady()) {
|
||||
setState(State::SyncResolved);
|
||||
@@ -317,7 +348,7 @@ bool Asset::startSynchronizations() {
|
||||
foundUnresolved = true;
|
||||
}
|
||||
}
|
||||
for (auto& child : requiredAssets()) {
|
||||
for (auto& child : requestedAssets()) {
|
||||
child->startSynchronizations();
|
||||
}
|
||||
|
||||
@@ -385,29 +416,15 @@ bool Asset::restartAllSynchronizations() {
|
||||
return startSynchronizations();
|
||||
}
|
||||
|
||||
float Asset::synchronizationProgress() {
|
||||
float Asset::requiredSynchronizationProgress() {
|
||||
std::vector<std::shared_ptr<Asset>> assets = requiredSubTreeAssets();
|
||||
return syncProgress(assets);
|
||||
|
||||
size_t nTotalBytes = 0;
|
||||
size_t nSyncedBytes = 0;
|
||||
}
|
||||
|
||||
for (const auto& a : assets) {
|
||||
const std::vector<std::shared_ptr<ResourceSynchronization>> syncs =
|
||||
a->ownSynchronizations();
|
||||
|
||||
for (const auto& sync : syncs) {
|
||||
if (sync->nTotalBytesIsKnown()) {
|
||||
nTotalBytes += sync->nTotalBytes();
|
||||
nSyncedBytes += sync->nSynchronizedBytes();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nTotalBytes == 0) {
|
||||
return 1.f;
|
||||
}
|
||||
return static_cast<float>(nSyncedBytes) / static_cast<float>(nTotalBytes);
|
||||
float Asset::requestedSynchronizationProgress() {
|
||||
std::vector<std::shared_ptr<Asset>> assets = subTreeAssets();
|
||||
return syncProgress(assets);
|
||||
}
|
||||
|
||||
void Asset::load() {
|
||||
@@ -706,13 +723,23 @@ void Asset::request(std::shared_ptr<Asset> child) {
|
||||
if (!child->isLoaded()) {
|
||||
child->load();
|
||||
}
|
||||
|
||||
if (isSynchronized() && child->isLoaded() && !child->isSynchronized()) {
|
||||
child->startSynchronizations();
|
||||
if (!child->isLoaded()) {
|
||||
unrequest(child);
|
||||
}
|
||||
|
||||
if (isInitialized() && child->isSynchronized() && !child->isInitialized()) {
|
||||
child->initialize();
|
||||
if (isSynchronized()) {
|
||||
if (child->isLoaded() && !child->isSynchronized()) {
|
||||
child->startSynchronizations();
|
||||
}
|
||||
}
|
||||
|
||||
if (isInitialized()) {
|
||||
if (child->isSynchronized() && !child->isInitialized()) {
|
||||
child->initialize();
|
||||
}
|
||||
if (!child->isInitialized()) {
|
||||
unrequest(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -733,8 +760,8 @@ void Asset::unrequest(std::shared_ptr<Asset> child) {
|
||||
child->_requestingAssets.begin(),
|
||||
child->_requestingAssets.end(),
|
||||
[this](std::weak_ptr<Asset> a) {
|
||||
return a.lock().get() == this;
|
||||
}
|
||||
return a.lock().get() == this;
|
||||
}
|
||||
);
|
||||
|
||||
if (parentIt == child->_requestingAssets.end()) {
|
||||
|
||||
@@ -291,8 +291,12 @@ bool HttpFileDownload::initDownload() {
|
||||
|
||||
ghoul::filesystem::File destinationFile = _destination;
|
||||
ghoul::filesystem::Directory d = destinationFile.directoryName();
|
||||
if (!FileSys.directoryExists(d)) {
|
||||
FileSys.createDirectory(d, ghoul::filesystem::Directory::Recursive::Yes);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> g(_directoryCreationMutex);
|
||||
if (!FileSys.directoryExists(d)) {
|
||||
FileSys.createDirectory(d, ghoul::filesystem::Directory::Recursive::Yes);
|
||||
}
|
||||
}
|
||||
|
||||
_file = std::ofstream(_destination, std::ofstream::binary);
|
||||
@@ -314,6 +318,8 @@ size_t HttpFileDownload::handleData(HttpRequest::Data d) {
|
||||
return d.size;
|
||||
}
|
||||
|
||||
std::mutex HttpFileDownload::_directoryCreationMutex;
|
||||
|
||||
SyncHttpMemoryDownload::SyncHttpMemoryDownload(std::string url)
|
||||
: SyncHttpDownload(std::move(url))
|
||||
, HttpMemoryDownload()
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <ghoul/filesystem/filesystem>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
#include <openspace/modulepath.h>
|
||||
|
||||
@@ -44,7 +45,9 @@ OpenSpaceModule::OpenSpaceModule(std::string name)
|
||||
: properties::PropertyOwner({ std::move(name) })
|
||||
{}
|
||||
|
||||
void OpenSpaceModule::initialize() {
|
||||
void OpenSpaceModule::initialize(const ModuleEngine* moduleEngine,
|
||||
const ghoul::Dictionary& configuration)
|
||||
{
|
||||
std::string upperName = name();
|
||||
std::transform(
|
||||
upperName.begin(),
|
||||
@@ -63,7 +66,8 @@ void OpenSpaceModule::initialize() {
|
||||
LDEBUG("Registering module path: " << moduleToken << ": " << path);
|
||||
FileSys.registerPathToken(moduleToken, path);
|
||||
|
||||
internalInitialize();
|
||||
_moduleEngine = moduleEngine;
|
||||
internalInitialize(configuration);
|
||||
}
|
||||
|
||||
void OpenSpaceModule::deinitialize() {
|
||||
@@ -111,7 +115,17 @@ std::string OpenSpaceModule::modulePath() const {
|
||||
);
|
||||
}
|
||||
|
||||
const ModuleEngine* OpenSpaceModule::moduleEngine() const
|
||||
{
|
||||
return _moduleEngine;
|
||||
}
|
||||
|
||||
void OpenSpaceModule::internalInitialize() {}
|
||||
|
||||
void OpenSpaceModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
internalInitialize();
|
||||
}
|
||||
|
||||
void OpenSpaceModule::internalDeinitialize() {}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
|
||||
#include <exception>
|
||||
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/wrapper/windowwrapper.h>
|
||||
|
||||
@@ -79,7 +78,6 @@ protected:
|
||||
}
|
||||
|
||||
openspace::Scene _scene;
|
||||
std::unique_ptr<openspace::ResourceSynchronizer> _resourceSynchronizer;
|
||||
std::unique_ptr<openspace::AssetLoader> _assetLoader;
|
||||
bool _passedTest;
|
||||
};
|
||||
@@ -96,17 +94,17 @@ int passTest(lua_State* state) {
|
||||
|
||||
TEST_F(AssetLoaderTest, Assertions) {
|
||||
try {
|
||||
_assetLoader->loadAsset("passassertion");
|
||||
_assetLoader->add("passassertion");
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
EXPECT_TRUE(false) << e.what();
|
||||
}
|
||||
EXPECT_THROW(_assetLoader->loadAsset("failassertion"), ghoul::lua::LuaRuntimeException);
|
||||
EXPECT_THROW(_assetLoader->add("failassertion"), ghoul::lua::LuaRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(AssetLoaderTest, BasicExportImport) {
|
||||
try {
|
||||
_assetLoader->loadAsset("import");
|
||||
_assetLoader->add("import");
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
EXPECT_TRUE(false) << e.what();
|
||||
@@ -115,7 +113,7 @@ TEST_F(AssetLoaderTest, BasicExportImport) {
|
||||
|
||||
TEST_F(AssetLoaderTest, AssetFuncitons) {
|
||||
try {
|
||||
_assetLoader->loadAsset("assetfunctionsexist");
|
||||
_assetLoader->add("assetfunctionsexist");
|
||||
} catch (const std::exception& e) {
|
||||
EXPECT_TRUE(false) << e.what();
|
||||
}
|
||||
@@ -123,7 +121,7 @@ TEST_F(AssetLoaderTest, AssetFuncitons) {
|
||||
|
||||
TEST_F(AssetLoaderTest, DependencyFuncitons) {
|
||||
try {
|
||||
_assetLoader->loadAsset("dependencyfunctionsexist");
|
||||
_assetLoader->add("dependencyfunctionsexist");
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
EXPECT_TRUE(false) << e.what();
|
||||
@@ -132,7 +130,7 @@ TEST_F(AssetLoaderTest, DependencyFuncitons) {
|
||||
|
||||
TEST_F(AssetLoaderTest, AssetInitialization) {
|
||||
try {
|
||||
std::shared_ptr<openspace::Asset> asset = _assetLoader->loadAsset("initialization");
|
||||
std::shared_ptr<openspace::Asset> asset = _assetLoader->add("initialization");
|
||||
asset->initialize();
|
||||
EXPECT_TRUE(passed());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user