From a0667439dfd52db3392cfd22cd2660735e3e4ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 12 Nov 2024 21:50:02 +0100 Subject: [PATCH] SceneTools: add reference() and mutableReference() helpers. Matching what's in MeshTools, because I need them to implement other algorithms that match what's in MeshTools. In other words no idea why I didn't make these along with copy() already. --- src/Magnum/SceneTools/CMakeLists.txt | 32 +++--- src/Magnum/SceneTools/Copy.cpp | 14 +++ src/Magnum/SceneTools/Copy.h | 25 +++- src/Magnum/SceneTools/Test/CMakeLists.txt | 2 +- src/Magnum/SceneTools/Test/CopyTest.cpp | 133 +++++++++++++++++++--- 5 files changed, 173 insertions(+), 33 deletions(-) diff --git a/src/Magnum/SceneTools/CMakeLists.txt b/src/Magnum/SceneTools/CMakeLists.txt index 797cdf8b4..e6ef13c60 100644 --- a/src/Magnum/SceneTools/CMakeLists.txt +++ b/src/Magnum/SceneTools/CMakeLists.txt @@ -40,12 +40,12 @@ set(CMAKE_FOLDER "Magnum/SceneTools") find_package(Corrade REQUIRED PluginManager) # Files shared between main library and unit test library -set(MagnumSceneTools_SRCS - Copy.cpp) +set(MagnumSceneTools_SRCS ) # Files compiled with different flags for main library and unit test library set(MagnumSceneTools_GracefulAssert_SRCS Combine.cpp + Copy.cpp Filter.cpp Hierarchy.cpp Map.cpp) @@ -71,22 +71,22 @@ if(MAGNUM_BUILD_DEPRECATED) OrderClusterParents.h) endif() -# Objects shared between main and test library -add_library(MagnumSceneToolsObjects OBJECT - ${MagnumSceneTools_SRCS} - ${MagnumSceneTools_HEADERS} - ${MagnumSceneTools_PRIVATE_HEADERS}) -target_include_directories(MagnumSceneToolsObjects PUBLIC $) -if(NOT MAGNUM_BUILD_STATIC) - target_compile_definitions(MagnumSceneToolsObjects PRIVATE "MagnumSceneToolsObjects_EXPORTS") -endif() -if(NOT MAGNUM_BUILD_STATIC OR MAGNUM_BUILD_STATIC_PIC) - set_target_properties(MagnumSceneToolsObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) -endif() +# # Objects shared between main and test library +# add_library(MagnumSceneToolsObjects OBJECT +# ${MagnumSceneTools_SRCS} +# ${MagnumSceneTools_HEADERS} +# ${MagnumSceneTools_PRIVATE_HEADERS}) +# target_include_directories(MagnumSceneToolsObjects PUBLIC $) +# if(NOT MAGNUM_BUILD_STATIC) +# target_compile_definitions(MagnumSceneToolsObjects PRIVATE "MagnumSceneToolsObjects_EXPORTS") +# endif() +# if(NOT MAGNUM_BUILD_STATIC OR MAGNUM_BUILD_STATIC_PIC) +# set_target_properties(MagnumSceneToolsObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) +# endif() # Main SceneTools library add_library(MagnumSceneTools ${SHARED_OR_STATIC} - $ + # $ ${MagnumSceneTools_GracefulAssert_SRCS} ${MagnumSceneTools_HEADERS} ${MagnumSceneTools_PRIVATE_HEADERS}) @@ -128,7 +128,7 @@ endif() if(MAGNUM_BUILD_TESTS) # Library with graceful assert for testing add_library(MagnumSceneToolsTestLib ${SHARED_OR_STATIC} ${EXCLUDE_FROM_ALL_IF_TEST_TARGET} - $ + # $ ${MagnumSceneTools_GracefulAssert_SRCS}) set_target_properties(MagnumSceneToolsTestLib PROPERTIES DEBUG_POSTFIX "-d") target_compile_definitions(MagnumSceneToolsTestLib PRIVATE diff --git a/src/Magnum/SceneTools/Copy.cpp b/src/Magnum/SceneTools/Copy.cpp index 79513f3cf..76e8a1c0b 100644 --- a/src/Magnum/SceneTools/Copy.cpp +++ b/src/Magnum/SceneTools/Copy.cpp @@ -33,6 +33,20 @@ namespace Magnum { namespace SceneTools { +Trade::SceneData reference(const Trade::SceneData& scene) { + return Trade::SceneData{scene.mappingType(), scene.mappingBound(), + {}, scene.data(), Trade::sceneFieldDataNonOwningArray(scene.fieldData())}; +} + +Trade::SceneData mutableReference(Trade::SceneData& scene) { + CORRADE_ASSERT(scene.dataFlags() & Trade::DataFlag::Mutable, + "SceneTools::mutableReference(): data not mutable", + (Trade::SceneData{Trade::SceneMappingType::UnsignedInt, 0, {}, {}})); + + return Trade::SceneData{scene.mappingType(), scene.mappingBound(), + Trade::DataFlag::Mutable, scene.mutableData(), Trade::sceneFieldDataNonOwningArray(scene.fieldData())}; +} + Trade::SceneData copy(const Trade::SceneData& scene) { return copy(Trade::SceneData{scene.mappingType(), scene.mappingBound(), {}, scene.data(), diff --git a/src/Magnum/SceneTools/Copy.h b/src/Magnum/SceneTools/Copy.h index 2f373cba0..b1c724b16 100644 --- a/src/Magnum/SceneTools/Copy.h +++ b/src/Magnum/SceneTools/Copy.h @@ -27,7 +27,7 @@ */ /** @file - * @brief Function @ref Magnum::SceneTools::copy() + * @brief Function @ref Magnum::SceneTools::copy(), @ref Magnum::SceneTools::reference(), @ref Magnum::SceneTools::mutableReference() * @m_since_latest */ @@ -63,6 +63,29 @@ isn't changed in any way. */ MAGNUM_SCENETOOLS_EXPORT Trade::SceneData copy(Trade::SceneData&& scene); +/** +@brief Create an immutable reference on a @ref Trade::SceneData +@m_since_latest + +The returned instance has empty @ref Trade::SceneData::dataFlags() and +references field data from the @p scene as well. The function performs no +allocation or data copy. Use @ref copy() for an inverse operation. +@see @ref mutableReference() +*/ +MAGNUM_SCENETOOLS_EXPORT Trade::SceneData reference(const Trade::SceneData& scene); + +/** +@brief Create a mutable reference on a @ref Trade::SceneData +@m_since{2020,06} + +The returned instance has @ref Trade::SceneData::dataFlags() set to +@ref Trade::DataFlag::Mutable. The function performs no allocation or data +copy. Use @ref copy() for an inverse operation. Expects that @p scene is +mutable. +@see @ref reference() +*/ +MAGNUM_SCENETOOLS_EXPORT Trade::SceneData mutableReference(Trade::SceneData& scene); + }} #endif diff --git a/src/Magnum/SceneTools/Test/CMakeLists.txt b/src/Magnum/SceneTools/Test/CMakeLists.txt index a9d6970df..c73b87237 100644 --- a/src/Magnum/SceneTools/Test/CMakeLists.txt +++ b/src/Magnum/SceneTools/Test/CMakeLists.txt @@ -52,7 +52,7 @@ file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/$/configure.h INPUT ${CMAKE_CURRENT_BINARY_DIR}/configure.h.in) corrade_add_test(SceneToolsCombineTest CombineTest.cpp LIBRARIES MagnumSceneToolsTestLib) -corrade_add_test(SceneToolsCopyTest CopyTest.cpp LIBRARIES MagnumSceneTools) +corrade_add_test(SceneToolsCopyTest CopyTest.cpp LIBRARIES MagnumSceneToolsTestLib) corrade_add_test(SceneToolsConvertToSingleFunc___Test ConvertToSingleFunctionObjectsTest.cpp LIBRARIES MagnumSceneToolsTestLib) corrade_add_test(SceneToolsFilterTest FilterTest.cpp LIBRARIES MagnumSceneToolsTestLib) corrade_add_test(SceneToolsHierarchyTest HierarchyTest.cpp LIBRARIES MagnumSceneToolsTestLib) diff --git a/src/Magnum/SceneTools/Test/CopyTest.cpp b/src/Magnum/SceneTools/Test/CopyTest.cpp index c4b901af1..662dcc5e2 100644 --- a/src/Magnum/SceneTools/Test/CopyTest.cpp +++ b/src/Magnum/SceneTools/Test/CopyTest.cpp @@ -24,12 +24,14 @@ DEALINGS IN THE SOFTWARE. */ +#include /** @todo remove once Debug is stream-free */ #include #include #include #include #include #include +#include /** @todo remove once Debug is stream-free */ #include "Magnum/SceneTools/Copy.h" #include "Magnum/Trade/SceneData.h" @@ -39,24 +41,38 @@ namespace Magnum { namespace SceneTools { namespace Test { namespace { struct CopyTest: TestSuite::Tester { explicit CopyTest(); - void test(); + void copy(); - void rvalueNotOwned(); - void rvalueDataFieldsOwned(); - void rvalueDataOwned(); - void rvalueFieldsOwned(); + void copyRvalueNotOwned(); + void copyRvalueDataFieldsOwned(); + void copyRvalueDataOwned(); + void copyRvalueFieldsOwned(); + + void reference(); + void referenceNoDataFieldData(); + + void mutableReference(); + void mutableReferenceNoDataFieldData(); + void mutableReferenceNotMutable(); }; CopyTest::CopyTest() { - addTests({&CopyTest::test, + addTests({&CopyTest::copy, + + &CopyTest::copyRvalueNotOwned, + &CopyTest::copyRvalueDataFieldsOwned, + &CopyTest::copyRvalueDataOwned, + &CopyTest::copyRvalueFieldsOwned, - &CopyTest::rvalueNotOwned, - &CopyTest::rvalueDataFieldsOwned, - &CopyTest::rvalueDataOwned, - &CopyTest::rvalueFieldsOwned}); + &CopyTest::reference, + &CopyTest::referenceNoDataFieldData, + + &CopyTest::mutableReference, + &CopyTest::mutableReferenceNoDataFieldData, + &CopyTest::mutableReferenceNotMutable}); } -void CopyTest::test() { +void CopyTest::copy() { const struct Data { UnsignedShort parentMeshMapping[4]; Long parent[4]; @@ -174,7 +190,7 @@ void CopyTest::test() { CORRADE_VERIFY(!fieldData.deleter()); } -void CopyTest::rvalueNotOwned() { +void CopyTest::copyRvalueNotOwned() { struct Data { UnsignedShort parentMapping[2]; Int parent[2]; @@ -209,7 +225,7 @@ void CopyTest::rvalueNotOwned() { CORRADE_VERIFY(copy.fieldData().data() != fields); } -void CopyTest::rvalueDataFieldsOwned() { +void CopyTest::copyRvalueDataFieldsOwned() { struct Data { UnsignedShort parentMapping[2]; Int parent[2]; @@ -249,7 +265,7 @@ void CopyTest::rvalueDataFieldsOwned() { CORRADE_COMPARE(copy.fieldData().data(), originalFields); } -void CopyTest::rvalueDataOwned() { +void CopyTest::copyRvalueDataOwned() { struct Data { UnsignedShort parentMapping[2]; Int parent[2]; @@ -287,7 +303,7 @@ void CopyTest::rvalueDataOwned() { CORRADE_VERIFY(copy.fieldData().data() != fields); } -void CopyTest::rvalueFieldsOwned() { +void CopyTest::copyRvalueFieldsOwned() { struct Data { UnsignedShort parentMapping[2]; Int parent[2]; @@ -327,6 +343,93 @@ void CopyTest::rvalueFieldsOwned() { } } +void CopyTest::reference() { + struct Data { + UnsignedShort parentMapping[2]; + Int parent[2]; + }; + Containers::Array data{NoInit, sizeof(Data)}; + Containers::StridedArrayView1D view = Containers::arrayCast(data); + + Trade::SceneData scene{Trade::SceneMappingType::UnsignedShort, 31, Utility::move(data), { + Trade::SceneFieldData{Trade::SceneField::Parent, + Containers::arrayView(view[0].parentMapping), + Containers::arrayView(view[0].parent)} + }}; + + Trade::SceneData reference = SceneTools::reference(scene); + CORRADE_COMPARE(reference.mappingType(), Trade::SceneMappingType::UnsignedShort); + CORRADE_COMPARE(reference.mappingBound(), 31); + CORRADE_COMPARE(reference.dataFlags(), Trade::DataFlags{}); + CORRADE_COMPARE(static_cast(reference.data().data()), scene.data().data()); + CORRADE_COMPARE(static_cast(reference.fieldData().data()), scene.fieldData().data()); +} + +void CopyTest::referenceNoDataFieldData() { + Trade::SceneData scene{Trade::SceneMappingType::UnsignedShort, 31, {}, {}}; + + Trade::SceneData reference = SceneTools::reference(scene); + CORRADE_COMPARE(reference.mappingType(), Trade::SceneMappingType::UnsignedShort); + CORRADE_COMPARE(reference.mappingBound(), 31); + CORRADE_COMPARE(reference.dataFlags(), Trade::DataFlags{}); + CORRADE_VERIFY(!static_cast(reference.data().data())); + CORRADE_VERIFY(!static_cast(reference.fieldData().data())); +} + +void CopyTest::mutableReference() { + struct Data { + UnsignedShort parentMapping[2]; + Int parent[2]; + }; + Containers::Array data{NoInit, sizeof(Data)}; + Containers::StridedArrayView1D view = Containers::arrayCast(data); + + Trade::SceneData scene{Trade::SceneMappingType::UnsignedShort, 31, Utility::move(data), { + Trade::SceneFieldData{Trade::SceneField::Parent, + Containers::arrayView(view[0].parentMapping), + Containers::arrayView(view[0].parent)} + }}; + + Trade::SceneData reference = SceneTools::mutableReference(scene); + CORRADE_COMPARE(reference.mappingType(), Trade::SceneMappingType::UnsignedShort); + CORRADE_COMPARE(reference.mappingBound(), 31); + CORRADE_COMPARE(reference.dataFlags(), Trade::DataFlag::Mutable); + CORRADE_COMPARE(static_cast(reference.data().data()), scene.data().data()); + CORRADE_COMPARE(static_cast(reference.fieldData().data()), scene.fieldData().data()); +} + +void CopyTest::mutableReferenceNoDataFieldData() { + Trade::SceneData scene{Trade::SceneMappingType::UnsignedShort, 31, {}, {}}; + + Trade::SceneData reference = SceneTools::mutableReference(scene); + CORRADE_COMPARE(reference.mappingType(), Trade::SceneMappingType::UnsignedShort); + CORRADE_COMPARE(reference.mappingBound(), 31); + CORRADE_COMPARE(reference.dataFlags(), Trade::DataFlag::Mutable); + CORRADE_VERIFY(!static_cast(reference.data().data())); + CORRADE_VERIFY(!static_cast(reference.fieldData().data())); +} + +void CopyTest::mutableReferenceNotMutable() { + CORRADE_SKIP_IF_NO_ASSERT(); + + const struct { + UnsignedShort parentMapping[2]; + Int parent[2]; + } data[1]{}; + + Trade::SceneData scene{Trade::SceneMappingType::UnsignedShort, 31, Trade::DataFlag::Global, data, { + Trade::SceneFieldData{Trade::SceneField::Parent, + Containers::arrayView(data[0].parentMapping), + Containers::arrayView(data[0].parent)} + }}; + CORRADE_COMPARE(scene.dataFlags(), Trade::DataFlag::Global); + + std::ostringstream out; + Error redirectError{&out}; + SceneTools::mutableReference(scene); + CORRADE_COMPARE(out.str(), "SceneTools::mutableReference(): data not mutable\n"); +} + }}}} CORRADE_TEST_MAIN(Magnum::SceneTools::Test::CopyTest)