diff --git a/include/openspace/scene/profile.h b/include/openspace/scene/profile.h index 4cf257e609..eb9c7f61b3 100644 --- a/include/openspace/scene/profile.h +++ b/include/openspace/scene/profile.h @@ -114,7 +114,7 @@ public: double longitude; std::optional altitude; }; - using CameraType = std::variant; + using CameraType = std::variant; enum class AssetEventType { Add, @@ -159,7 +159,7 @@ public: static scripting::LuaLibrary luaLibrary(); private: - static constexpr const Version CurrentVersion = Version{ 1, 0, 0 }; + static constexpr const Version CurrentVersion = Version { 1, 0, 0 }; Version version = CurrentVersion; std::vector modules; std::vector assets; @@ -169,7 +169,6 @@ private: CameraType camera; std::vector markNodes; - bool _ignoreUpdates = false; }; diff --git a/src/scene/profile.cpp b/src/scene/profile.cpp index 88b6616fce..5f206479b3 100644 --- a/src/scene/profile.cpp +++ b/src/scene/profile.cpp @@ -341,7 +341,7 @@ namespace { throw ProfileParsingError(lineNumber, "No values specified for Camera location"); } Profile::CameraType camera = [&](const std::string& type) -> - std::variant + std::variant { if (type == Profile::CameraNavState::Type) { if (fields.size() != 8) { @@ -580,45 +580,57 @@ std::string Profile::serialize() const { ); } } - - output += fmt::format("\n{}\n", headerTime); - { - const std::string type = [](Time::Type t) { - switch (t) { + + if (time.type != Time::Type::None) { + output += fmt::format("\n{}\n", headerTime); + { + const std::string type = [](Time::Type t) { + switch (t) { case Time::Type::Absolute: return "absolute"; case Time::Type::Relative: return "relative"; default: throw ghoul::MissingCaseException(); - } - }(time.type); - output += fmt::format("{}\t{}\n", type, time.time); + } + }(time.type); + output += fmt::format("{}\t{}\n", type, time.time); + } } - output += fmt::format("\n{}\n", headerCamera); - output += std::visit( - overloaded{ - [](const CameraNavState& camera) { - return fmt::format( - "{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\n", - CameraNavState::Type, - camera.anchor, camera.aim, camera.referenceFrame, camera.position, - camera.up, camera.yaw, camera.pitch - ); - }, - [](const Profile::CameraGoToGeo& camera) { - std::string altitude; - if (camera.altitude.has_value()) { - altitude = std::to_string(*camera.altitude); + if (!std::holds_alternative(camera)) { + output += fmt::format("\n{}\n", headerCamera); + output += std::visit( + overloaded{ + [](const std::monostate&) { + return std::string(); + }, + [](const CameraNavState& camera) { + return fmt::format( + "{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\n", + CameraNavState::Type, + camera.anchor, camera.aim, camera.referenceFrame, camera.position, + camera.up, camera.yaw, camera.pitch + ); + }, + [](const Profile::CameraGoToGeo& camera) { + if (camera.altitude.has_value()) { + return fmt::format( + "{}\t{}\t{}\t{}\t{}\n", + CameraGoToGeo::Type, + camera.anchor, camera.latitude, camera.longitude, + *camera.altitude + ); + } + else { + return fmt::format( + "{}\t{}\t{}\t{}\t\n", + CameraGoToGeo::Type, + camera.anchor, camera.latitude, camera.longitude + ); + } } - - return fmt::format( - "{}\t{}\t{}\t{}\t{}\n", - CameraGoToGeo::Type, - camera.anchor, camera.latitude, camera.longitude, altitude - ); - } - }, - camera - ); + }, + camera + ); + } if (!markNodes.empty()) { output += fmt::format("\n{}\n", headerMarkNodes); @@ -633,7 +645,6 @@ std::string Profile::serialize() const { Profile::Profile(const std::vector& content) { Section currentSection = Section::None; bool foundVersion = false; - bool foundCamera = false; for (int lineNum = 1; lineNum <= static_cast(content.size()); ++lineNum) { std::string line = content[lineNum - 1]; @@ -643,52 +654,51 @@ Profile::Profile(const std::vector& content) { } switch (currentSection) { - case Section::None: - currentSection = parseSection(line, lineNum); - break; - case Section::Version: - version = parseVersion(line, lineNum); - foundVersion = true; - break; - case Section::Module: - { - Module m = parseModule(line, lineNum); - modules.push_back(std::move(m)); - break; - } - case Section::Asset: - { - Asset a = parseAsset(line, lineNum); - assets.push_back(std::move(a)); - break; - } - case Section::Property: - { - Property p = parseProperty(line, lineNum); - properties.push_back(std::move(p)); - break; - } - case Section::Keybinding: - { - Keybinding kb = parseKeybinding(line, lineNum); - keybindings.push_back(std::move(kb)); - break; - } - case Section::Time: - time = parseTime(line, lineNum); - break; - case Section::Camera: - camera = parseCamera(line, lineNum); - foundCamera = true; - break; - case Section::MarkNodes: - { - std::string m = parseMarkNodes(line, lineNum); - markNodes.push_back(std::move(m)); - break; - } - default: - throw ghoul::MissingCaseException(); + case Section::None: + currentSection = parseSection(line, lineNum); + break; + case Section::Version: + version = parseVersion(line, lineNum); + foundVersion = true; + break; + case Section::Module: + { + Module m = parseModule(line, lineNum); + modules.push_back(std::move(m)); + break; + } + case Section::Asset: + { + Asset a = parseAsset(line, lineNum); + assets.push_back(std::move(a)); + break; + } + case Section::Property: + { + Property p = parseProperty(line, lineNum); + properties.push_back(std::move(p)); + break; + } + case Section::Keybinding: + { + Keybinding kb = parseKeybinding(line, lineNum); + keybindings.push_back(std::move(kb)); + break; + } + case Section::Time: + time = parseTime(line, lineNum); + break; + case Section::Camera: + camera = parseCamera(line, lineNum); + break; + case Section::MarkNodes: + { + std::string m = parseMarkNodes(line, lineNum); + markNodes.push_back(std::move(m)); + break; + } + default: + throw ghoul::MissingCaseException(); } } @@ -697,12 +707,6 @@ Profile::Profile(const std::vector& content) { "Did not find Version information when loading profile" ); } - - if (!foundCamera) { - throw ghoul::RuntimeError( - "Did not find Camera information when loading profile" - ); - } } std::string Profile::convertToScene() const { @@ -798,6 +802,9 @@ std::string Profile::convertToScene() const { // Camera output += std::visit( overloaded{ + [](const std::monostate&) { + return std::string(); + }, [](const CameraNavState& camera) { std::string result; result += "openspace.navigation.setNavigationState({"; diff --git a/tests/profile/basic_assets.profile b/tests/profile/basic_assets.profile new file mode 100644 index 0000000000..62fec23682 --- /dev/null +++ b/tests/profile/basic_assets.profile @@ -0,0 +1,7 @@ +#Version +12.13.14 + +#Asset +folder1/folder2/asset require +folder3/folder4/asset2 require variable +folder5/folder6/asset3 request diff --git a/tests/profile/basic_camera_gotogeo.profile b/tests/profile/basic_camera_gotogeo.profile new file mode 100644 index 0000000000..cbf5d7f670 --- /dev/null +++ b/tests/profile/basic_camera_gotogeo.profile @@ -0,0 +1,5 @@ +#Version +12.13.14 + +#Camera +goToGeo "anchor" 1.0 2.0 diff --git a/tests/profile/basic_camera_gotogeo_altitude.profile b/tests/profile/basic_camera_gotogeo_altitude.profile new file mode 100644 index 0000000000..069d94a230 --- /dev/null +++ b/tests/profile/basic_camera_gotogeo_altitude.profile @@ -0,0 +1,5 @@ +#Version +12.13.14 + +#Camera +goToGeo "anchor" 1.0 2.0 4.0 diff --git a/tests/profile/basic_camera_navstate.profile b/tests/profile/basic_camera_navstate.profile new file mode 100644 index 0000000000..02a9783733 --- /dev/null +++ b/tests/profile/basic_camera_navstate.profile @@ -0,0 +1,5 @@ +#Version +12.13.14 + +#Camera +setNavigationState "node" "root" 1.0, 2.0, 3.0 4.0, 5.0, 6.0 diff --git a/tests/profile/basic_keybindings.profile b/tests/profile/basic_keybindings.profile new file mode 100644 index 0000000000..7f309a4b0f --- /dev/null +++ b/tests/profile/basic_keybindings.profile @@ -0,0 +1,7 @@ +#Version +12.13.14 + +#Keybinding +T T documentation T name T Gui-Path true T script +U U documentation U name U Gui-Path false U script +CTRL+V CTRL+V documentation CTRL+V name CTRL+V Gui-Path false CTRL+V script diff --git a/tests/profile/basic_mark_nodes.profile b/tests/profile/basic_mark_nodes.profile new file mode 100644 index 0000000000..5deecdfc31 --- /dev/null +++ b/tests/profile/basic_mark_nodes.profile @@ -0,0 +1,7 @@ +#Version +12.13.14 + +#MarkNodes +node-1 +node-2 +node-3 diff --git a/tests/profile/basic_modules.profile b/tests/profile/basic_modules.profile new file mode 100644 index 0000000000..2ba1c93dfb --- /dev/null +++ b/tests/profile/basic_modules.profile @@ -0,0 +1,7 @@ +#Version +12.13.14 + +#Module +abc-module +def-module +ghi-module diff --git a/tests/profile/basic_properties.profile b/tests/profile/basic_properties.profile new file mode 100644 index 0000000000..abc6c35ec0 --- /dev/null +++ b/tests/profile/basic_properties.profile @@ -0,0 +1,10 @@ +#Version +12.13.14 + +#Property +setPropertyValue property_name_1 property_value_1 +setPropertyValue property_name_2 property_value_2 +setPropertyValue property_name_3 property_value_3 +setPropertyValueSingle property_name_4 property_value_5 +setPropertyValueSingle property_name_4 property_value_5 +setPropertyValueSingle property_name_4 property_value_5 diff --git a/tests/profile/basic_time_absolute.profile b/tests/profile/basic_time_absolute.profile new file mode 100644 index 0000000000..269a06319a --- /dev/null +++ b/tests/profile/basic_time_absolute.profile @@ -0,0 +1,5 @@ +#Version +12.13.14 + +#Time +absolute 2020-06-01T12:00:00 diff --git a/tests/profile/basic_time_relative.profile b/tests/profile/basic_time_relative.profile new file mode 100644 index 0000000000..253aff665b --- /dev/null +++ b/tests/profile/basic_time_relative.profile @@ -0,0 +1,5 @@ +#Version +12.13.14 + +#Time +relative -1d diff --git a/tests/profile/minimal.profile b/tests/profile/minimal.profile new file mode 100644 index 0000000000..7ec5af0497 --- /dev/null +++ b/tests/profile/minimal.profile @@ -0,0 +1,2 @@ +#Version +12.13.14 diff --git a/tests/profile/test_profile.cpp b/tests/profile/test_profile.cpp index 524cfb2214..bc25117b7d 100644 --- a/tests/profile/test_profile.cpp +++ b/tests/profile/test_profile.cpp @@ -23,28 +23,166 @@ ****************************************************************************************/ #include "catch2/catch.hpp" -#include "test_common.h" -#include -#include -#include +//#include "test_common.h" +//#include +//#include +//#include +// +//#include +//#include +//#include "openspace/scene/profile.h" +//#include +//#include +//#include +//#include +//#include +//#include +// +//#include +//#include +//#include -#include -#include -#include "openspace/scene/profile.h" -#include -#include -#include -#include + +#include #include -#include -#include - -#include -#include -#include +#include using namespace openspace; +namespace { + Profile loadProfile(const std::string& filename) { + std::ifstream f(absPath(filename)); + + std::vector lines; + std::string line; + while (std::getline(f, line)) { + lines.push_back(std::move(line)); + } + + return Profile(lines); + } + + std::string loadFile(const std::string& filename) { + std::ifstream f(absPath(filename)); + std::string content( + (std::istreambuf_iterator(f)), + std::istreambuf_iterator() + ); + return content; + } +} // namespace + +TEST_CASE("Minimal", "[profile]") { + constexpr const char* TestFile = "${TESTDIR}/profile/minimal.profile"; + Profile p = loadProfile(TestFile); + + std::string serialized = p.serialize(); + std::string contents = loadFile(TestFile); + + REQUIRE(serialized == contents); +} + +TEST_CASE("Basic Module", "[profile]") { + constexpr const char* TestFile = "${TESTDIR}/profile/basic_modules.profile"; + Profile p = loadProfile(TestFile); + + std::string serialized = p.serialize(); + std::string contents = loadFile(TestFile); + + REQUIRE(serialized == contents); +} + +TEST_CASE("Basic Assets", "[profile]") { + constexpr const char* TestFile = "${TESTDIR}/profile/basic_assets.profile"; + Profile p = loadProfile(TestFile); + + std::string serialized = p.serialize(); + std::string contents = loadFile(TestFile); + + REQUIRE(serialized == contents); +} + +TEST_CASE("Basic Properties", "[profile]") { + constexpr const char* TestFile = "${TESTDIR}/profile/basic_properties.profile"; + Profile p = loadProfile(TestFile); + + std::string serialized = p.serialize(); + std::string contents = loadFile(TestFile); + + REQUIRE(serialized == contents); +} + +TEST_CASE("Basic Keybindings", "[profile]") { + constexpr const char* TestFile = "${TESTDIR}/profile/basic_keybindings.profile"; + Profile p = loadProfile(TestFile); + + std::string serialized = p.serialize(); + std::string contents = loadFile(TestFile); + + REQUIRE(serialized == contents); +} + +TEST_CASE("Basic Time Relative", "[profile]") { + constexpr const char* TestFile = "${TESTDIR}/profile/basic_time_relative.profile"; + Profile p = loadProfile(TestFile); + + std::string serialized = p.serialize(); + std::string contents = loadFile(TestFile); + + REQUIRE(serialized == contents); +} + +TEST_CASE("Basic Time Absolute", "[profile]") { + constexpr const char* TestFile = "${TESTDIR}/profile/basic_time_absolute.profile"; + Profile p = loadProfile(TestFile); + + std::string serialized = p.serialize(); + std::string contents = loadFile(TestFile); + + REQUIRE(serialized == contents); +} + +TEST_CASE("Basic Camera NavState", "[profile]") { + constexpr const char* TestFile = "${TESTDIR}/profile/basic_camera_navstate.profile"; + Profile p = loadProfile(TestFile); + + std::string serialized = p.serialize(); + std::string contents = loadFile(TestFile); + + REQUIRE(serialized == contents); +} + +TEST_CASE("Basic Camera GoToGeo", "[profile]") { + constexpr const char* TestFile = "${TESTDIR}/profile/basic_camera_gotogeo.profile"; + Profile p = loadProfile(TestFile); + + std::string serialized = p.serialize(); + std::string contents = loadFile(TestFile); + + REQUIRE(serialized == contents); +} + +TEST_CASE("Basic Camera GoToGeo altitude", "[profile]") { + constexpr const char* TestFile = + "${TESTDIR}/profile/basic_camera_gotogeo_altitude.profile"; + Profile p = loadProfile(TestFile); + + std::string serialized = p.serialize(); + std::string contents = loadFile(TestFile); + + REQUIRE(serialized == contents); +} + +TEST_CASE("Basic Mark Nodes", "[profile]") { + constexpr const char* TestFile = "${TESTDIR}/profile/basic_mark_nodes.profile"; + Profile p = loadProfile(TestFile); + + std::string serialized = p.serialize(); + std::string contents = loadFile(TestFile); + + REQUIRE(serialized == contents); +} + //namespace { // int passTest(lua_State* state) { // bool* test = reinterpret_cast(lua_touserdata(state, lua_upvalueindex(1)));