diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 414946b038..e298f8ce6a 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -75,7 +75,8 @@ class OpenSpaceEngine { public: static void create(int argc, char** argv, std::unique_ptr windowWrapper, - std::vector& sgctArguments, bool& requestClose); + std::vector& sgctArguments, + bool& requestClose, bool consoleLog = true); static void destroy(); static OpenSpaceEngine& ref(); static bool isCreated(); @@ -180,7 +181,7 @@ private: void loadSingleAsset(const std::string& assetPath); void gatherCommandlineArguments(); void loadFonts(); - void configureLogging(); + void configureLogging(bool consoleLog); // Components std::unique_ptr _configurationManager; diff --git a/include/openspace/scene/assetloader.h b/include/openspace/scene/assetloader.h index b98293d612..c59ceb4ddb 100644 --- a/include/openspace/scene/assetloader.h +++ b/include/openspace/scene/assetloader.h @@ -46,15 +46,15 @@ class Asset; namespace assetloader { int onInitialize(lua_State* state); int onDeinitialize(lua_State* state); +int onInitializeDependency(lua_State* state); +int onDeinitializeDependency(lua_State* state); int addSynchronization(lua_State* state); int importRequiredDependency(lua_State* state); int importOptionalDependency(lua_State* state); int resolveLocalResource(lua_State* state); int resolveSyncedResource(lua_State* state); -int onFinishSynchronization(lua_State* state); int noOperation(lua_State* state); int exportAsset(lua_State* state); - } // namespace assetloader class AssetLoader { @@ -150,11 +150,13 @@ private: void pushAsset(Asset* asset); void popAsset(); void updateLuaGlobals(); - void addLuaDependencyTable(const Asset* dependant, const Asset* dependency); + void addLuaDependencyTable(Asset* dependant, Asset* dependency); // Lua functions int onInitializeLua(Asset* asset); int onDeinitializeLua(Asset* asset); + int onInitializeDependencyLua(Asset* dependant, Asset* dependency); + int onDeinitializeDependencyLua(Asset* dependant, Asset* dependency); int addSynchronizationLua(Asset* asset); int importRequiredDependencyLua(Asset* asset); int importOptionalDependencyLua(Asset* asset); @@ -166,12 +168,13 @@ private: // Friend c closures (callable from lua, and maps to lua functions above) friend int assetloader::onInitialize(lua_State* state); friend int assetloader::onDeinitialize(lua_State* state); + friend int assetloader::onInitializeDependency(lua_State* state); + friend int assetloader::onDeinitializeDependency(lua_State* state); friend int assetloader::addSynchronization(lua_State* state); friend int assetloader::importRequiredDependency(lua_State* state); friend int assetloader::importOptionalDependency(lua_State* state); friend int assetloader::resolveLocalResource(lua_State* state); friend int assetloader::resolveSyncedResource(lua_State* state); - friend int assetloader::onFinishSynchronization(lua_State* state); friend int assetloader::exportAsset(lua_State* state); std::unique_ptr _rootAsset; @@ -186,6 +189,9 @@ private: // References to lua values std::map> _onInitializationFunctionRefs; std::map> _onDeinitializationFunctionRefs; + std::map>> _onDependencyInitializationFunctionRefs; + std::map>> _onDependencyDeinitializationFunctionRefs; + int _assetsTableRef; }; diff --git a/modules/spacecraftinstruments/spacecraftinstrumentsmodule.cpp b/modules/spacecraftinstruments/spacecraftinstrumentsmodule.cpp index 22a46eacb2..a87b7c96e9 100644 --- a/modules/spacecraftinstruments/spacecraftinstrumentsmodule.cpp +++ b/modules/spacecraftinstruments/spacecraftinstrumentsmodule.cpp @@ -68,6 +68,10 @@ void SpacecraftInstrumentsModule::internalInitialize() { fDecoder->registerClass("Target"); } +void SpacecraftInstrumentsModule::internalDeinitialize() { + ImageSequencer::deinitialize(); +} + std::vector SpacecraftInstrumentsModule::documentations() const { diff --git a/modules/spacecraftinstruments/spacecraftinstrumentsmodule.h b/modules/spacecraftinstruments/spacecraftinstrumentsmodule.h index 01f0e1f5fe..19789a0e23 100644 --- a/modules/spacecraftinstruments/spacecraftinstrumentsmodule.h +++ b/modules/spacecraftinstruments/spacecraftinstrumentsmodule.h @@ -39,6 +39,7 @@ public: protected: void internalInitialize() override; + void internalDeinitialize() override; }; } // namespace openspace diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 9ab1b109ad..565d6e7ed5 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -226,7 +226,8 @@ bool OpenSpaceEngine::isCreated() { void OpenSpaceEngine::create(int argc, char** argv, std::unique_ptr windowWrapper, - std::vector& sgctArguments, bool& requestClose) + std::vector& sgctArguments, + bool& requestClose, bool consoleLog) { ghoul_assert(!_engine, "OpenSpaceEngine was already created"); ghoul_assert(windowWrapper != nullptr, "No Window Wrapper was provided"); @@ -246,7 +247,9 @@ void OpenSpaceEngine::create(int argc, char** argv, LogLevel::Debug, ghoul::logging::LogManager::ImmediateFlush::Yes ); - LogMgr.addLog(std::make_unique()); + if (consoleLog) { + LogMgr.addLog(std::make_unique()); + } #ifdef __APPLE__ ghoul::filesystem::File app(argv[0]); @@ -361,7 +364,7 @@ void OpenSpaceEngine::create(int argc, char** argv, } // Initialize the requested logs from the configuration file - _engine->configureLogging(); + _engine->configureLogging(consoleLog); LINFOC("OpenSpace Version", OPENSPACE_VERSION_MAJOR << "." << @@ -421,14 +424,6 @@ void OpenSpaceEngine::destroy() { _engine->_scene = nullptr; - for (const auto& func : _engine->_moduleCallbacks.deinitializeGL) { - func(); - } - - for (const auto& func : _engine->_moduleCallbacks.deinitialize) { - func(); - } - _engine->_syncEngine->removeSyncables(_engine->timeManager().getSyncables()); _engine->_syncEngine->removeSyncables(_engine->_renderEngine->getSyncables()); @@ -438,7 +433,9 @@ void OpenSpaceEngine::destroy() { _engine->_scriptEngine->deinitialize(); delete _engine; + _engine = nullptr; FactoryManager::deinitialize(); + TransformationManager::deinitialize(); SpiceManager::deinitialize(); ghoul::fontrendering::FontRenderer::deinitialize(); @@ -655,8 +652,16 @@ void OpenSpaceEngine::loadSingleAsset(const std::string& assetPath) { void OpenSpaceEngine::deinitialize() { LTRACE("OpenSpaceEngine::deinitialize(begin)"); + for (const auto& func : _engine->_moduleCallbacks.deinitializeGL) { + func(); + } + + for (const auto& func : _engine->_moduleCallbacks.deinitialize) { + func(); + } + _navigationHandler->deinitialize(); - _renderEngine->deinitialize(); + _renderEngine->deinitialize(); LTRACE("OpenSpaceEngine::deinitialize(end)"); } @@ -756,7 +761,7 @@ void OpenSpaceEngine::loadFonts() { } } -void OpenSpaceEngine::configureLogging() { +void OpenSpaceEngine::configureLogging(bool consoleLog) { const std::string KeyLogLevel = ConfigurationManager::KeyLogging + '.' + ConfigurationManager::PartLogLevel; const std::string KeyLogImmediateFlush = @@ -778,8 +783,9 @@ void OpenSpaceEngine::configureLogging() { level, immediateFlush ? ImmediateFlush::Yes : ImmediateFlush::No ); - - LogMgr.addLog(std::make_unique()); + if (consoleLog) { + LogMgr.addLog(std::make_unique()); + } } if (configurationManager().hasKeyAndValue(KeyLogs)) { diff --git a/src/scene/assetloader.cpp b/src/scene/assetloader.cpp index 85d3e4c201..3173a1a0c5 100644 --- a/src/scene/assetloader.cpp +++ b/src/scene/assetloader.cpp @@ -107,13 +107,8 @@ Asset* AssetLoader::loadAsset(std::string path) { throw ghoul::FileNotFoundError(path); } - try { - ghoul::lua::runScriptFile(*_luaState, path); - } catch (const ghoul::lua::LuaRuntimeException& e) { - LERROR("Lua exception" << e.what()); - } + ghoul::lua::runScriptFile(*_luaState, path); _importedAssets.emplace(asset->id(), std::move(asset)); - return rawAsset; } @@ -147,8 +142,8 @@ int AssetLoader::onInitializeLua(Asset* asset) { int nArguments = lua_gettop(*_luaState); SCRIPT_CHECK_ARGUMENTS("onInitialize", *_luaState, 1, nArguments); + lua_pushvalue(*_luaState, 1); int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX); - _onInitializationFunctionRefs[asset].push_back(referenceIndex); return 0; } @@ -157,18 +152,38 @@ int AssetLoader::onDeinitializeLua(Asset* asset) { int nArguments = lua_gettop(*_luaState); SCRIPT_CHECK_ARGUMENTS("onDeinitialize", *_luaState, 1, nArguments); + lua_pushvalue(*_luaState, 1); int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX); - _onDeinitializationFunctionRefs[asset].push_back(referenceIndex); return 0; } +int AssetLoader::onInitializeDependencyLua(Asset* dependant, Asset* dependency) { + int nArguments = lua_gettop(*_luaState); + SCRIPT_CHECK_ARGUMENTS("onInitializeDependency", *_luaState, 1, nArguments); + + lua_pushvalue(*_luaState, 1); + int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX); + _onDependencyInitializationFunctionRefs[dependant][dependency].push_back(referenceIndex); + return 0; +} + +int AssetLoader::onDeinitializeDependencyLua(Asset* dependant, Asset* dependency) { + int nArguments = lua_gettop(*_luaState); + SCRIPT_CHECK_ARGUMENTS("onDeinitializeDependency", *_luaState, 1, nArguments); + + lua_pushvalue(*_luaState, 1); + int referenceIndex = luaL_ref(*_luaState, LUA_REGISTRYINDEX); + _onDependencyDeinitializationFunctionRefs[dependant][dependency].push_back(referenceIndex); + return 0; +} + +int AssetLoader::addSynchronizationLua(Asset * asset) { + return 0; +} + Asset* AssetLoader::importRequiredDependency(const std::string& name) { Asset* asset = getAsset(name); - if (!asset) { - // TODO: Throw - return nullptr; - } Asset* dependant = _assetStack.back(); dependant->addRequiredDependency(asset); return asset; @@ -176,10 +191,6 @@ Asset* AssetLoader::importRequiredDependency(const std::string& name) { Asset* AssetLoader::importOptionalDependency(const std::string& name, bool enabled) { Asset* asset = getAsset(name); - if (!asset) { - // TODO: Throw - return nullptr; - } Asset* owner = _assetStack.back(); owner->addOptionalDependency(asset, enabled); return asset; @@ -215,12 +226,7 @@ void AssetLoader::update() { void AssetLoader::importAsset(const std::string & identifier) { ghoul_assert(_assetStack.size() == 1, "Can only import an asset from the root asset"); - try { - importOptionalDependency(identifier); - } - catch (const ghoul::RuntimeError& e) { - LERROR("Error loading asset '" << identifier << "': " << e.message); - } + importOptionalDependency(identifier); } @@ -457,11 +463,17 @@ void AssetLoader::pushAsset(Asset* asset) { lua_setfield(*_luaState, assetTableIndex, OnInitializeFunctionName); // Register onDeinitialize function - // void onInitialize(function deinitializationFunction) + // void onDeinitialize(function deinitializationFunction) lua_pushlightuserdata(*_luaState, asset); lua_pushcclosure(*_luaState, &assetloader::onDeinitialize, 1); lua_setfield(*_luaState, assetTableIndex, OnDeinitializeFunctionName); + // Register addSynchronization function + // void addSynchronization(table synchronization) + lua_pushlightuserdata(*_luaState, asset); + lua_pushcclosure(*_luaState, &assetloader::addSynchronization, 1); + lua_setfield(*_luaState, assetTableIndex, AddSynchronizationFunctionName); + // Attach asset table to asset meta table lua_setfield(*_luaState, assetMetaTableIndex, AssetTableName); @@ -483,15 +495,17 @@ void AssetLoader::popAsset() { } void AssetLoader::updateLuaGlobals() { - Asset* asset = _assetStack.back(); // Set `asset` lua global to point to the current asset table - lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef); + Asset* asset = _assetStack.back(); + if (asset == _rootAsset.get()) { lua_pushnil(*_luaState); lua_setglobal(*_luaState, AssetGlobalVariableName); return; } + + lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef); lua_getfield(*_luaState, -1, asset->id().c_str()); lua_getfield(*_luaState, -1, AssetTableName); lua_setglobal(*_luaState, AssetGlobalVariableName); @@ -511,25 +525,22 @@ int AssetLoader::importRequiredDependencyLua(Asset* dependant) { addLuaDependencyTable(dependant, dependency); - int dependencyTableRef = 0; // TODO: get the ref to the dependency - int dependencyExportsRef = 0; // TODO: get the ref to the exports + // Get the exports table + lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef); + lua_getfield(*_luaState, -1, dependency->id().c_str()); + lua_getfield(*_luaState, -1, ExportsTableName); + int exportsTableIndex = lua_gettop(*_luaState); - //lua_pushvalue(*_luaState, dependencyExportsRef); - //lua_pushvalue(*_luaState, dependencyTableRef); - return 0; - /*try { - - } - catch (const ghoul::RuntimeError& e) { - return luaL_error( - state, - "Failed to import asset '%s'. %s: %s", - assetName.c_str(), - e.message.c_str(), - e.component.c_str() - ); - }*/ + // Get the dependency table + lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef); + lua_getfield(*_luaState, -1, dependency->id().c_str()); + lua_getfield(*_luaState, -1, DependantsTableName); + lua_getfield(*_luaState, -1, dependant->id().c_str()); + int dependencyTableIndex = lua_gettop(*_luaState); + lua_pushvalue(*_luaState, exportsTableIndex); + lua_pushvalue(*_luaState, dependencyTableIndex); + return 2; } int AssetLoader::importOptionalDependencyLua(Asset* dependant) { @@ -546,12 +557,23 @@ int AssetLoader::importOptionalDependencyLua(Asset* dependant) { } addLuaDependencyTable(dependant, dependency); - int dependencyTableRef = 0; // TODO: get the ref to the dependency - int dependencyExportsRef = 0; // TODO: get the ref to the exports - //lua_pushvalue(*_luaState, dependencyExportsRef); - //lua_pushvalue(*_luaState, dependencyTableRef); - return 0; + // Get the exports table + lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef); + lua_getfield(*_luaState, -1, dependency->id().c_str()); + lua_getfield(*_luaState, -1, ExportsTableName); + int exportsTableIndex = lua_gettop(*_luaState); + + // Get the dependency table + lua_rawgeti(*_luaState, LUA_REGISTRYINDEX, _assetsTableRef); + lua_getfield(*_luaState, -1, dependency->id().c_str()); + lua_getfield(*_luaState, -1, DependantsTableName); + lua_getfield(*_luaState, -1, dependant->id().c_str()); + int dependencyTableIndex = lua_gettop(*_luaState); + + lua_pushvalue(*_luaState, exportsTableIndex); + lua_pushvalue(*_luaState, dependencyTableIndex); + return 2; } int AssetLoader::exportAssetLua(Asset* asset) { @@ -567,11 +589,11 @@ int AssetLoader::exportAssetLua(Asset* asset) { // push the second argument lua_pushvalue(*_luaState, 2); - lua_setfield(*_luaState, exportsTableIndex, exportName.c_str()); + return 0; } -void AssetLoader::addLuaDependencyTable(const Asset* dependant, const Asset* dependency) { +void AssetLoader::addLuaDependencyTable(Asset* dependant, Asset* dependency) { const std::string dependantId = dependant->id(); const std::string dependencyId = dependency->id(); @@ -587,14 +609,32 @@ void AssetLoader::addLuaDependencyTable(const Asset* dependant, const Asset* dep lua_newtable(*_luaState); const int currentDependantTableIndex = lua_gettop(*_luaState); - // Register default onDeinitialize function - lua_pushcfunction(*_luaState, &assetloader::noOperation); + // Register onDependencyInitialize function + // void onInitialize(function initializationFunction) + lua_pushlightuserdata(*_luaState, dependant); + lua_pushlightuserdata(*_luaState, dependency); + lua_pushcclosure(*_luaState, &assetloader::onInitializeDependency, 2); lua_setfield(*_luaState, currentDependantTableIndex, OnInitializeFunctionName); - // Register default onDeinitialize function - lua_pushcfunction(*_luaState, &assetloader::noOperation); + // Register onDependencyDeinitialize function + // void onDeinitialize(function deinitializationFunction) + lua_pushlightuserdata(*_luaState, dependant); + lua_pushlightuserdata(*_luaState, dependency); + lua_pushcclosure(*_luaState, &assetloader::onDeinitializeDependency, 2); lua_setfield(*_luaState, currentDependantTableIndex, OnDeinitializeFunctionName); + // Register local resource function + // string localResource(string path) + lua_pushlightuserdata(*_luaState, dependency); + lua_pushcclosure(*_luaState, &assetloader::resolveLocalResource, 1); + lua_setfield(*_luaState, currentDependantTableIndex, LocalResourceFunctionName); + + // Register synced resource function + // string syncedResource(string path) + lua_pushlightuserdata(*_luaState, dependency); + lua_pushcclosure(*_luaState, &assetloader::resolveSyncedResource, 1); + lua_setfield(*_luaState, currentDependantTableIndex, SyncedResourceFunctionName); + // duplicate the table reference on the stack, so it remains after assignment. lua_pushvalue(*_luaState, -1); diff --git a/src/scene/assetloader_lua.inl b/src/scene/assetloader_lua.inl index f1906b82f7..094d58b0d4 100644 --- a/src/scene/assetloader_lua.inl +++ b/src/scene/assetloader_lua.inl @@ -103,6 +103,31 @@ int onDeinitialize(lua_State* state) { return asset->loader()->onDeinitializeLua(asset); } +/** +* Adds a Lua function to be called when a dependency link is initialized +* Usage: void asset.onInitialize(function initFun) +*/ +int onInitializeDependency(lua_State* state) { + Asset *dependant = + reinterpret_cast(lua_touserdata(state, lua_upvalueindex(1))); + Asset *dependency = + reinterpret_cast(lua_touserdata(state, lua_upvalueindex(2))); + return dependant->loader()->onInitializeDependencyLua(dependant, dependency); +} + +/** +* Adds a Lua function to be called upon asset deinitialization +* Usage: void asset.onDeinitialize(function initFun) +*/ +int onDeinitializeDependency(lua_State* state) { + Asset *dependant = + reinterpret_cast(lua_touserdata(state, lua_upvalueindex(1))); + Asset *dependency = + reinterpret_cast(lua_touserdata(state, lua_upvalueindex(2))); + return dependant->loader()->onDeinitializeDependencyLua(dependant, dependency); +} + + /** * Imports required dependencies * Gives access to @@ -134,10 +159,10 @@ int resolveSyncedResource(lua_State* state) { return asset->loader()->resolveSyncedResourceLua(asset); } -int onFinishSynchronization(lua_State* state) { +int addSynchronization(lua_State* state) { Asset *asset = reinterpret_cast(lua_touserdata(state, lua_upvalueindex(1))); - return asset->loader()->onFinishSynchronizationLua(asset); + return asset->loader()->addSynchronizationLua(asset); } int noOperation(lua_State*) { diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 0ec7bc1fca..8e05f2dc26 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -73,7 +73,9 @@ void ScriptEngine::initialize() { initializeLuaState(_state); } -void ScriptEngine::deinitialize() {} +void ScriptEngine::deinitialize() { + _registeredLibraries.clear(); +} void ScriptEngine::initializeLuaState(lua_State* state) { LDEBUG("Create openspace base library"); diff --git a/tests/AssetLoaderTest/assetfunctionsexist.asset b/tests/AssetLoaderTest/assetfunctionsexist.asset new file mode 100644 index 0000000000..068e1e03ac --- /dev/null +++ b/tests/AssetLoaderTest/assetfunctionsexist.asset @@ -0,0 +1,8 @@ +assert(type(asset.import) == "function", "import should be function") +assert(type(asset.importOptional) == "function", "importOptional should be function") +assert(type(asset.localResource) == "function", "localResource should be function") +assert(type(asset.syncedResource) == "function", "syncedResource should be function") +assert(type(asset.export) == "function", "export should be function") +assert(type(asset.onInitialize) == "function", "onInitialize should be function") +assert(type(asset.onDeinitialize) == "function", "onDeinitialize should be function") +assert(type(asset.addSynchronization) == "function", "addSynchronization should be function") \ No newline at end of file diff --git a/tests/AssetLoaderTest/dependencyfunctionsexist.asset b/tests/AssetLoaderTest/dependencyfunctionsexist.asset new file mode 100644 index 0000000000..2a1b39e5e6 --- /dev/null +++ b/tests/AssetLoaderTest/dependencyfunctionsexist.asset @@ -0,0 +1,6 @@ +local imports, dep = asset.import('export') + +assert(type(dep.localResource) == "function", "localResource should be function") +assert(type(dep.syncedResource) == "function", "syncedResource should be function") +assert(type(dep.onInitialize) == "function", "onInitialize should be function") +assert(type(dep.onDeinitialize) == "function", "onDeinitialize should be function") \ No newline at end of file diff --git a/tests/AssetLoaderTest/export.asset b/tests/AssetLoaderTest/export.asset new file mode 100644 index 0000000000..d4730687cb --- /dev/null +++ b/tests/AssetLoaderTest/export.asset @@ -0,0 +1 @@ +asset.export("data", "foo") \ No newline at end of file diff --git a/tests/AssetLoaderTest/failassertion.asset b/tests/AssetLoaderTest/failassertion.asset new file mode 100644 index 0000000000..49cdd57ee8 --- /dev/null +++ b/tests/AssetLoaderTest/failassertion.asset @@ -0,0 +1 @@ +assert (false) \ No newline at end of file diff --git a/tests/AssetLoaderTest/import.asset b/tests/AssetLoaderTest/import.asset new file mode 100644 index 0000000000..c5e13701f7 --- /dev/null +++ b/tests/AssetLoaderTest/import.asset @@ -0,0 +1,2 @@ +local exports, dep = asset.import('export'); +assert (exports.data == 'foo') \ No newline at end of file diff --git a/tests/AssetLoaderTest/initialization.asset b/tests/AssetLoaderTest/initialization.asset new file mode 100644 index 0000000000..e5e8e20c72 --- /dev/null +++ b/tests/AssetLoaderTest/initialization.asset @@ -0,0 +1,3 @@ +asset.onInitialize(function () + passTest() +end) \ No newline at end of file diff --git a/tests/AssetLoaderTest/passassertion.asset b/tests/AssetLoaderTest/passassertion.asset new file mode 100644 index 0000000000..3acea7c194 --- /dev/null +++ b/tests/AssetLoaderTest/passassertion.asset @@ -0,0 +1 @@ +assert (true) \ No newline at end of file diff --git a/tests/main.cpp b/tests/main.cpp index a43b3aa73a..f531c687c8 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -56,7 +56,7 @@ // test files #include #include -#include +#include #include #ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED @@ -108,7 +108,20 @@ namespace { int main(int argc, char** argv) { std::vector args; bool close; - openspace::OpenSpaceEngine::create(argc, argv, std::make_unique(), args, close); + bool consoleLog = false; + + + // Workaround for Visual Studio Google Test Adapter: + // Do not try to initialize osengine if gtest is just listing tests + bool skipOsEng = false; + std::vector gtestArgs(argv, argv + argc); + if (std::find(gtestArgs.begin(), gtestArgs.end(), "--gtest_list_tests") != gtestArgs.end()) { + skipOsEng = true; + } + + if (!skipOsEng) { + openspace::OpenSpaceEngine::create(argc, argv, std::make_unique(), args, close, consoleLog); + } testing::InitGoogleTest(&argc, argv); @@ -116,8 +129,18 @@ int main(int argc, char** argv) { testing::internal::CaptureStdout(); testing::internal::CaptureStderr(); #endif - - openspace::SpiceManager::deinitialize(); + +#ifdef PRINT_OUTPUT + + // Stop capturing std out + std::string output = testing::internal::GetCapturedStdout(); + std::string error = testing::internal::GetCapturedStderr(); + + //std::cout << output; + //std::cerr << error; +#endif + + //openspace::SpiceManager::deinitialize(); bool b = RUN_ALL_TESTS(); @@ -130,8 +153,7 @@ int main(int argc, char** argv) { std::ofstream e("error.txt"); e << error; -#endif - +#endif return b; } diff --git a/tests/test_assetloader.inl b/tests/test_assetloader.inl new file mode 100644 index 0000000000..e7fc0e4a13 --- /dev/null +++ b/tests/test_assetloader.inl @@ -0,0 +1,147 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "gtest/gtest.h" +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include + +#include + + +#include +#include + +class AssetLoaderTest; + +namespace { +int passTest(lua_State* state); +} + +class AssetLoaderTest : public ::testing::Test { +public: + void pass() { + _passedTest = true; + } + + bool passed() { + return _passedTest; + } + +protected: + virtual void SetUp() { + ghoul::lua::LuaState* state = OsEng.scriptEngine().luaState(); + OsEng.scriptEngine().initialize(); + _resourceSynchronizer = std::make_unique(); + _assetLoader = std::make_unique( + *state, + *_resourceSynchronizer.get(), + "${TESTDIR}/AssetLoaderTest/", + "${TEMPORARY}/resources/"); + + _passedTest = false; + lua_pushlightuserdata(*state, this); + lua_pushcclosure(*state, &passTest, 1); + lua_setglobal(*state, "passTest"); + } + + virtual void TearDown() { + OsEng.scriptEngine().deinitialize(); + } + + openspace::Scene _scene; + std::unique_ptr _resourceSynchronizer; + std::unique_ptr _assetLoader; + bool _passedTest; +}; + +namespace { +int passTest(lua_State* state) { + AssetLoaderTest *test = + reinterpret_cast(lua_touserdata(state, lua_upvalueindex(1))); + test->pass(); + return 0; +} +} + + +TEST_F(AssetLoaderTest, Assertions) { + try { + _assetLoader->importAsset("passassertion"); + } + catch (const std::exception& e) { + EXPECT_TRUE(false) << e.what(); + } + EXPECT_THROW(_assetLoader->importAsset("failassertion"), ghoul::lua::LuaRuntimeException); +} + +TEST_F(AssetLoaderTest, BasicExportImport) { + try { + _assetLoader->importAsset("import"); + } + catch (const std::exception& e) { + EXPECT_TRUE(false) << e.what(); + } +} + +TEST_F(AssetLoaderTest, AssetFuncitons) { + try { + _assetLoader->importAsset("assetfunctionsexist"); + } catch (const std::exception& e) { + EXPECT_TRUE(false) << e.what(); + } +} + +TEST_F(AssetLoaderTest, DependencyFuncitons) { + try { + _assetLoader->importAsset("dependencyfunctionsexist"); + } + catch (const std::exception& e) { + EXPECT_TRUE(false) << e.what(); + } +} + +TEST_F(AssetLoaderTest, AssetInitialization) { + LINFOC("test", "WHAT?"); + try { + _assetLoader->loadSingleAsset("initialization"); + _assetLoader->rootAsset()->initialize(); + EXPECT_TRUE(passed()); + } + catch (const std::exception& e) { + EXPECT_TRUE(false) << e.what(); + } +} + +