mirror of https://github.com/mosra/magnum.git
Browse Source
Basically just the same logic as MeshTools::copy() including the same TODO and XFAIL, just with some scene-specific special-cases on top.pull/620/head
6 changed files with 558 additions and 16 deletions
@ -0,0 +1,141 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
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 "Copy.h" |
||||
|
||||
#include <Corrade/Containers/StridedBitArrayView.h> |
||||
#include <Corrade/Utility/Algorithms.h> |
||||
|
||||
#include "Magnum/Trade/SceneData.h" |
||||
|
||||
namespace Magnum { namespace SceneTools { |
||||
|
||||
Trade::SceneData copy(const Trade::SceneData& scene) { |
||||
return copy(Trade::SceneData{scene.mappingType(), scene.mappingBound(), |
||||
{}, scene.data(), |
||||
Trade::sceneFieldDataNonOwningArray(scene.fieldData()), |
||||
scene.importerState()}); |
||||
} |
||||
|
||||
Trade::SceneData copy(Trade::SceneData&& scene) { |
||||
/* Transfer data if they're owned and mutable, allocate a copy otherwise.
|
||||
Save also the original data view for new field pointer calculation. */ |
||||
const Containers::ArrayView<const char> originalData = scene.data(); |
||||
Containers::Array<char> data; |
||||
if(scene.dataFlags() >= (Trade::DataFlag::Mutable|Trade::DataFlag::Owned)) |
||||
data = scene.releaseData(); |
||||
else { |
||||
data = Containers::Array<char>{NoInit, originalData.size()}; |
||||
Utility::copy(originalData, data); |
||||
} |
||||
|
||||
/* There's no way to know if field data are owned until we release them and
|
||||
check the deleter, but releasing them makes it impossible to use the |
||||
convenience SceneData APIs, so we have to do it the hard way. */ |
||||
Containers::Array<Trade::SceneFieldData> originalFieldData = scene.releaseFieldData(); |
||||
|
||||
/* If the field data are owned *and* the data weren't copied, we can reuse
|
||||
the original array in its entirety */ |
||||
Containers::Array<Trade::SceneFieldData> fieldData; |
||||
if(!originalFieldData.deleter() && (scene.dataFlags() & Trade::DataFlag::Owned)) { |
||||
fieldData = std::move(originalFieldData); |
||||
|
||||
/* Otherwise we have to allocate a new one and re-route the fields to a
|
||||
potentially different data array */ |
||||
/** @todo could theoretically also just modify the array in-place if it has
|
||||
a default deleter, but would need to pay attention to not copy items |
||||
to themselves and such */ |
||||
} else { |
||||
/* Using DefaultInit so the array has a default deleter and isn't
|
||||
problematic to use in plugins */ |
||||
fieldData = Containers::Array<Trade::SceneFieldData>{DefaultInit, originalFieldData.size()}; |
||||
for(std::size_t i = 0; i != originalFieldData.size(); ++i) { |
||||
const Trade::SceneFieldData& originalField = originalFieldData[i]; |
||||
|
||||
/* If the field is offset-only, copy it directly, yay! */ |
||||
if(originalField.flags() & Trade::SceneFieldFlag::OffsetOnly) |
||||
fieldData[i] = originalField; |
||||
|
||||
/* Otherwise there's a bunch of special cases based on its type */ |
||||
else { |
||||
const Trade::SceneMappingType mappingType = originalField.mappingType(); |
||||
const Containers::StridedArrayView1D<const void> mappingView{ |
||||
data, data.data() + (static_cast<const char*>(originalField.mappingData().data()) - originalData.data()), |
||||
originalField.size(), |
||||
originalField.mappingData().stride()}; |
||||
|
||||
const Trade::SceneFieldType fieldType = originalField.fieldType(); |
||||
if(fieldType == Trade::SceneFieldType::Bit) { |
||||
if(originalField.fieldArraySize() == 0) { |
||||
const Containers::StridedBitArrayView1D fieldView{ |
||||
/** @todo explicit construction from an ArrayView?! */ |
||||
Containers::BitArrayView{data.data(), 0, data.size()*8}, |
||||
data.data() + (static_cast<const char*>(originalField.fieldBitData().data()) - originalData.data()), |
||||
originalField.fieldBitData().offset(), |
||||
originalField.size(), |
||||
originalField.fieldBitData().stride()[0]}; |
||||
fieldData[i] = Trade::SceneFieldData{originalField.name(), |
||||
mappingType, mappingView, |
||||
fieldView, originalField.flags()}; |
||||
} else { |
||||
const Containers::StridedBitArrayView2D fieldView{ |
||||
/** @todo explicit construction from an ArrayView?! */ |
||||
Containers::BitArrayView{data.data(), 0, data.size()*8}, |
||||
data.data() + (static_cast<const char*>(originalField.fieldBitData().data()) - originalData.data()), |
||||
originalField.fieldBitData().offset(), |
||||
{originalField.size(), originalField.fieldArraySize()}, |
||||
originalField.fieldBitData().stride()}; |
||||
fieldData[i] = Trade::SceneFieldData{originalField.name(), |
||||
mappingType, mappingView, |
||||
fieldView, originalField.flags()}; |
||||
} |
||||
} else { |
||||
const Containers::StridedArrayView1D<const void> fieldView{ |
||||
data, data.data() + (static_cast<const char*>(originalField.fieldData().data()) - originalData.data()), |
||||
originalField.size(), |
||||
originalField.fieldData().stride()}; |
||||
|
||||
if(Trade::Implementation::isSceneFieldTypeString(fieldType)) { |
||||
fieldData[i] = Trade::SceneFieldData{originalField.name(), |
||||
mappingType, mappingView, |
||||
data.data() + (originalField.stringData() - originalData.data()), |
||||
fieldType, fieldView, |
||||
originalField.flags()}; |
||||
} else { |
||||
fieldData[i] = Trade::SceneFieldData{originalField.name(), |
||||
mappingType, mappingView, |
||||
fieldType, fieldView, |
||||
originalField.fieldArraySize(), originalField.flags()}; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return Trade::SceneData{scene.mappingType(), scene.mappingBound(), |
||||
std::move(data), std::move(fieldData), scene.importerState()}; |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,67 @@
|
||||
#ifndef Magnum_SceneTools_Copy_h |
||||
#define Magnum_SceneTools_Copy_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
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. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Function @ref Magnum::SceneTools::copy() |
||||
* @m_since_latest |
||||
*/ |
||||
|
||||
#include "Magnum/SceneTools/visibility.h" |
||||
#include "Magnum/Trade/Trade.h" |
||||
|
||||
namespace Magnum { namespace SceneTools { |
||||
|
||||
/**
|
||||
@brief Make an owned copy of the scene |
||||
@m_since_latest |
||||
|
||||
Allocates a copy of @ref Trade::SceneData::data() and |
||||
@relativeref{Trade::SceneData,fieldData()} and returns a new scene with them. |
||||
All other properties such as the mapping bound or importer state are passed |
||||
through unchanged, the data layout isn't changed in any way. The resulting |
||||
@ref Trade::SceneData::dataFlags() are always @ref Trade::DataFlag::Owned and |
||||
@ref Trade::DataFlag::Mutable. |
||||
@see @ref copy(Trade::SceneData&&) |
||||
*/ |
||||
MAGNUM_SCENETOOLS_EXPORT Trade::SceneData copy(const Trade::SceneData& material); |
||||
|
||||
/**
|
||||
@brief Make a scene with owned data |
||||
@m_since_latest |
||||
|
||||
If @ref Trade::SceneData::dataFlags() are not @ref Trade::DataFlag::Owned and |
||||
@ref Trade::DataFlag::Mutable or the field data don't have the default deleter, |
||||
allocates a copy of @ref Trade::SceneData::data() or |
||||
@relativeref{Trade::SceneData,fieldData()}, otherwise transfers their |
||||
ownership. The resulting data are always owned and mutable, the data layout |
||||
isn't changed in any way. |
||||
*/ |
||||
MAGNUM_SCENETOOLS_EXPORT Trade::SceneData copy(Trade::SceneData&& material); |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,331 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
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 <Corrade/Containers/StridedBitArrayView.h> |
||||
#include <Corrade/Containers/StringIterable.h> |
||||
#include <Corrade/Containers/StringView.h> |
||||
#include <Corrade/TestSuite/Tester.h> |
||||
#include <Corrade/TestSuite/Compare/Container.h> |
||||
#include <Corrade/Utility/Algorithms.h> |
||||
|
||||
#include "Magnum/SceneTools/Copy.h" |
||||
#include "Magnum/Trade/SceneData.h" |
||||
|
||||
namespace Magnum { namespace SceneTools { namespace Test { namespace { |
||||
|
||||
struct CopyTest: TestSuite::Tester { |
||||
explicit CopyTest(); |
||||
|
||||
void test(); |
||||
|
||||
void rvalueNotOwned(); |
||||
void rvalueDataFieldsOwned(); |
||||
void rvalueDataOwned(); |
||||
void rvalueFieldsOwned(); |
||||
}; |
||||
|
||||
CopyTest::CopyTest() { |
||||
addTests({&CopyTest::test, |
||||
|
||||
&CopyTest::rvalueNotOwned, |
||||
&CopyTest::rvalueDataFieldsOwned, |
||||
&CopyTest::rvalueDataOwned, |
||||
&CopyTest::rvalueFieldsOwned}); |
||||
} |
||||
|
||||
void CopyTest::test() { |
||||
const struct Data { |
||||
UnsignedShort parentMeshMapping[4]; |
||||
Long parent[4]; |
||||
UnsignedInt mesh[4]; |
||||
UnsignedShort bitsMapping[3]; |
||||
bool bit[3]; |
||||
UnsignedInt bits[3]; |
||||
UnsignedShort stringMapping[2]; |
||||
char stringData[7]; |
||||
UnsignedByte strings[2]; |
||||
} data[]{{ |
||||
{1, 3, 5, 2}, |
||||
{-1, 1, 3, -1}, |
||||
{6667, 29862, 12393, 31222}, |
||||
{16, 12, 10}, |
||||
{false, true, false}, |
||||
{0xa, 0x4, 0xe}, |
||||
{100, 200}, |
||||
{'N', 'O', '\0', 'y', 'e', 's', '\0'}, |
||||
{3, 7} |
||||
}}; |
||||
|
||||
Trade::SceneData scene{Trade::SceneMappingType::UnsignedShort, 201, {}, data, { |
||||
Trade::SceneFieldData{Trade::SceneField::Parent, |
||||
Containers::arrayView(data->parentMeshMapping), |
||||
Containers::arrayView(data->parent)}, |
||||
/* Offset-only field */ |
||||
Trade::SceneFieldData{Trade::SceneField::Mesh, 4, |
||||
Trade::SceneMappingType::UnsignedShort, offsetof(Data, parentMeshMapping), sizeof(UnsignedShort), |
||||
Trade::SceneFieldType::UnsignedInt, offsetof(Data, mesh), sizeof(UnsignedInt)}, |
||||
/* Bit field */ |
||||
Trade::SceneFieldData{Trade::sceneFieldCustom(37), |
||||
Containers::arrayView(data->bitsMapping), |
||||
Containers::stridedArrayView(data->bit).sliceBit(0)}, |
||||
/* Bit array field */ |
||||
Trade::SceneFieldData{Trade::sceneFieldCustom(38), |
||||
Containers::arrayView(data->bitsMapping), |
||||
Containers::StridedBitArrayView2D{Containers::BitArrayView{data->bits}, data->bits, 1, {3, 3}, {sizeof(UnsignedInt)*8, 1}}}, |
||||
/* String field */ |
||||
Trade::SceneFieldData{Trade::sceneFieldCustom(664), |
||||
Containers::arrayView(data->stringMapping), |
||||
data->stringData, Trade::SceneFieldType::StringOffset8, |
||||
Containers::arrayView(data->strings), Trade::SceneFieldFlag::NullTerminatedString} |
||||
}}; |
||||
|
||||
Trade::SceneData copy = SceneTools::copy(scene); |
||||
CORRADE_COMPARE(copy.mappingType(), Trade::SceneMappingType::UnsignedShort); |
||||
CORRADE_COMPARE(copy.mappingBound(), 201); |
||||
|
||||
CORRADE_COMPARE(copy.dataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.fieldCount(), 5); |
||||
|
||||
for(std::size_t i = 0; i != copy.fieldCount(); ++i) { |
||||
CORRADE_ITERATION(i); |
||||
|
||||
CORRADE_COMPARE(copy.fieldName(i), scene.fieldName(i)); |
||||
CORRADE_COMPARE(copy.fieldSize(i), scene.fieldSize(i)); |
||||
CORRADE_COMPARE(copy.fieldArraySize(i), scene.fieldArraySize(i)); |
||||
CORRADE_COMPARE(copy.fieldType(i), scene.fieldType(i)); |
||||
/* Checks also for offset-only flags */ |
||||
CORRADE_COMPARE(copy.fieldFlags(i), scene.fieldFlags(i)); |
||||
} |
||||
|
||||
CORRADE_COMPARE_AS(copy.mapping<UnsignedShort>(Trade::SceneField::Parent), |
||||
Containers::arrayView(data->parentMeshMapping), |
||||
TestSuite::Compare::Container); |
||||
CORRADE_COMPARE_AS(copy.field<Long>(Trade::SceneField::Parent), |
||||
Containers::arrayView(data->parent), |
||||
TestSuite::Compare::Container); |
||||
|
||||
CORRADE_COMPARE_AS(copy.mapping<UnsignedShort>(Trade::SceneField::Mesh), |
||||
Containers::arrayView(data->parentMeshMapping), |
||||
TestSuite::Compare::Container); |
||||
CORRADE_COMPARE_AS(copy.field<UnsignedInt>(Trade::SceneField::Mesh), |
||||
Containers::arrayView(data->mesh), |
||||
TestSuite::Compare::Container); |
||||
|
||||
CORRADE_COMPARE_AS(copy.mapping<UnsignedShort>(Trade::sceneFieldCustom(37)), |
||||
Containers::arrayView(data->bitsMapping), |
||||
TestSuite::Compare::Container); |
||||
CORRADE_COMPARE_AS(copy.fieldBits(Trade::sceneFieldCustom(37)), |
||||
Containers::stridedArrayView(data->bit).sliceBit(0), |
||||
TestSuite::Compare::Container); |
||||
|
||||
CORRADE_COMPARE_AS(copy.mapping<UnsignedShort>(Trade::sceneFieldCustom(38)), |
||||
Containers::arrayView(data->bitsMapping), |
||||
TestSuite::Compare::Container); |
||||
CORRADE_COMPARE_AS(copy.fieldBitArrays(Trade::sceneFieldCustom(38))[0], |
||||
Containers::stridedArrayView({true, false, true}).sliceBit(0), |
||||
TestSuite::Compare::Container); |
||||
CORRADE_COMPARE_AS(copy.fieldBitArrays(Trade::sceneFieldCustom(38))[1], |
||||
Containers::stridedArrayView({false, true, false}).sliceBit(0), |
||||
TestSuite::Compare::Container); |
||||
CORRADE_COMPARE_AS(copy.fieldBitArrays(Trade::sceneFieldCustom(38))[2], |
||||
Containers::stridedArrayView({true, true, true}).sliceBit(0), |
||||
TestSuite::Compare::Container); |
||||
|
||||
CORRADE_COMPARE_AS(copy.mapping<UnsignedShort>(Trade::sceneFieldCustom(664)), |
||||
Containers::arrayView(data->stringMapping), |
||||
TestSuite::Compare::Container); |
||||
CORRADE_COMPARE_AS(copy.fieldStrings(Trade::sceneFieldCustom(664)), |
||||
(Containers::StringIterable{"NO", "yes"}), |
||||
TestSuite::Compare::Container); |
||||
|
||||
/* The data layout should be the same and thus the raw data should match
|
||||
as well */ |
||||
CORRADE_COMPARE_AS(copy.data(), |
||||
scene.data(), |
||||
TestSuite::Compare::Container); |
||||
|
||||
/* The data should have a default deleter to make this usable in plugins */ |
||||
Containers::Array<char> sceneData = copy.releaseData(); |
||||
Containers::Array<Trade::SceneFieldData> fieldData = copy.releaseFieldData(); |
||||
CORRADE_VERIFY(!sceneData.deleter()); |
||||
CORRADE_VERIFY(!fieldData.deleter()); |
||||
} |
||||
|
||||
void CopyTest::rvalueNotOwned() { |
||||
struct Data { |
||||
UnsignedShort parentMapping[2]; |
||||
Int parent[2]; |
||||
} data[]{{ |
||||
{1, 3}, |
||||
{-1, 1} |
||||
}}; |
||||
const Trade::SceneFieldData fields[]{ |
||||
Trade::SceneFieldData{Trade::SceneField::Parent, |
||||
Containers::arrayView(data->parentMapping), |
||||
Containers::arrayView(data->parent)} |
||||
}; |
||||
|
||||
Trade::SceneData copy = SceneTools::copy(Trade::SceneData{Trade::SceneMappingType::UnsignedShort, 12, |
||||
Trade::DataFlag::Mutable|Trade::DataFlag::ExternallyOwned, data, |
||||
Trade::sceneFieldDataNonOwningArray(fields)}); |
||||
|
||||
CORRADE_COMPARE(copy.mappingType(), Trade::SceneMappingType::UnsignedShort); |
||||
CORRADE_COMPARE(copy.mappingBound(), 12); |
||||
CORRADE_COMPARE(copy.dataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
|
||||
CORRADE_COMPARE(copy.fieldCount(), 1); |
||||
CORRADE_COMPARE_AS(copy.mapping<UnsignedShort>(Trade::SceneField::Parent), |
||||
Containers::arrayView(data->parentMapping), |
||||
TestSuite::Compare::Container); |
||||
CORRADE_COMPARE_AS(copy.field<Int>(Trade::SceneField::Parent), |
||||
Containers::arrayView(data->parent), |
||||
TestSuite::Compare::Container); |
||||
|
||||
/* Nothing should be copied in this case */ |
||||
CORRADE_VERIFY(copy.data().data() != static_cast<void*>(data)); |
||||
CORRADE_VERIFY(copy.fieldData().data() != fields); |
||||
} |
||||
|
||||
void CopyTest::rvalueDataFieldsOwned() { |
||||
struct Data { |
||||
UnsignedShort parentMapping[2]; |
||||
Int parent[2]; |
||||
}; |
||||
Containers::Array<char> data{NoInit, sizeof(Data)}; |
||||
Containers::StridedArrayView1D<Data> view = Containers::arrayCast<Data>(data); |
||||
Utility::copy({{ |
||||
{1, 3}, |
||||
{-1, 1} |
||||
}}, view); |
||||
|
||||
/* InPlaceInit causes a non-default deleter to be used, which would cause
|
||||
a copy to be made internally */ |
||||
Containers::Array<Trade::SceneFieldData> fields{ValueInit, 1}; |
||||
fields[0] = Trade::SceneFieldData{Trade::SceneField::Parent, |
||||
Containers::arrayView(view[0].parentMapping), |
||||
Containers::arrayView(view[0].parent)}; |
||||
const Trade::SceneFieldData* originalFields = fields; |
||||
|
||||
Trade::SceneData copy = SceneTools::copy(Trade::SceneData{Trade::SceneMappingType::UnsignedShort, 12, |
||||
std::move(data), std::move(fields)}); |
||||
|
||||
CORRADE_COMPARE(copy.mappingType(), Trade::SceneMappingType::UnsignedShort); |
||||
CORRADE_COMPARE(copy.mappingBound(), 12); |
||||
CORRADE_COMPARE(copy.dataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
|
||||
CORRADE_COMPARE(copy.fieldCount(), 1); |
||||
CORRADE_COMPARE_AS(copy.mapping<UnsignedShort>(Trade::SceneField::Parent), |
||||
Containers::arrayView(view[0].parentMapping), |
||||
TestSuite::Compare::Container); |
||||
CORRADE_COMPARE_AS(copy.field<Int>(Trade::SceneField::Parent), |
||||
Containers::arrayView(view[0].parent), |
||||
TestSuite::Compare::Container); |
||||
|
||||
/* Both data should be transferred without any copy */ |
||||
CORRADE_COMPARE(copy.data().data(), view.data()); |
||||
CORRADE_COMPARE(copy.fieldData().data(), originalFields); |
||||
} |
||||
|
||||
void CopyTest::rvalueDataOwned() { |
||||
struct Data { |
||||
UnsignedShort parentMapping[2]; |
||||
Int parent[2]; |
||||
}; |
||||
Containers::Array<char> data{NoInit, sizeof(Data)}; |
||||
Containers::StridedArrayView1D<Data> view = Containers::arrayCast<Data>(data); |
||||
Utility::copy({{ |
||||
{1, 3}, |
||||
{-1, 1} |
||||
}}, view); |
||||
|
||||
Trade::SceneFieldData fields[]{ |
||||
Trade::SceneFieldData{Trade::SceneField::Parent, |
||||
Containers::arrayView(view[0].parentMapping), |
||||
Containers::arrayView(view[0].parent)} |
||||
}; |
||||
|
||||
Trade::SceneData copy = SceneTools::copy(Trade::SceneData{Trade::SceneMappingType::UnsignedShort, 12, |
||||
std::move(data), Trade::sceneFieldDataNonOwningArray(fields)}); |
||||
|
||||
CORRADE_COMPARE(copy.mappingType(), Trade::SceneMappingType::UnsignedShort); |
||||
CORRADE_COMPARE(copy.mappingBound(), 12); |
||||
CORRADE_COMPARE(copy.dataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
|
||||
CORRADE_COMPARE(copy.fieldCount(), 1); |
||||
CORRADE_COMPARE_AS(copy.mapping<UnsignedShort>(Trade::SceneField::Parent), |
||||
Containers::arrayView(view[0].parentMapping), |
||||
TestSuite::Compare::Container); |
||||
CORRADE_COMPARE_AS(copy.field<Int>(Trade::SceneField::Parent), |
||||
Containers::arrayView(view[0].parent), |
||||
TestSuite::Compare::Container); |
||||
|
||||
/* Only data should be transferred, fields copied */ |
||||
CORRADE_COMPARE(copy.data().data(), view.data()); |
||||
CORRADE_VERIFY(copy.fieldData().data() != fields); |
||||
} |
||||
|
||||
void CopyTest::rvalueFieldsOwned() { |
||||
struct Data { |
||||
UnsignedShort parentMapping[2]; |
||||
Int parent[2]; |
||||
} data[]{{ |
||||
{1, 3}, |
||||
{-1, 1} |
||||
}}; |
||||
|
||||
/* InPlaceInit causes a non-default deleter to be used, which would cause
|
||||
a copy to be made internally */ |
||||
Containers::Array<Trade::SceneFieldData> fields{ValueInit, 1}; |
||||
fields[0] = Trade::SceneFieldData{Trade::SceneField::Parent, |
||||
Containers::arrayView(data->parentMapping), |
||||
Containers::arrayView(data->parent)}; |
||||
const Trade::SceneFieldData* originalFields = fields; |
||||
|
||||
Trade::SceneData copy = SceneTools::copy(Trade::SceneData{Trade::SceneMappingType::UnsignedShort, 12, |
||||
Trade::DataFlag::ExternallyOwned, data, std::move(fields)}); |
||||
|
||||
CORRADE_COMPARE(copy.mappingType(), Trade::SceneMappingType::UnsignedShort); |
||||
CORRADE_COMPARE(copy.mappingBound(), 12); |
||||
CORRADE_COMPARE(copy.dataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
|
||||
CORRADE_COMPARE(copy.fieldCount(), 1); |
||||
CORRADE_COMPARE_AS(copy.mapping<UnsignedShort>(Trade::SceneField::Parent), |
||||
Containers::arrayView(data->parentMapping), |
||||
TestSuite::Compare::Container); |
||||
CORRADE_COMPARE_AS(copy.field<Int>(Trade::SceneField::Parent), |
||||
Containers::arrayView(data->parent), |
||||
TestSuite::Compare::Container); |
||||
|
||||
/* Data should be copied */ |
||||
CORRADE_VERIFY(copy.data().data() != static_cast<void*>(data)); |
||||
{ |
||||
CORRADE_EXPECT_FAIL("Field data currently get copied always when they need to be modified."); |
||||
CORRADE_COMPARE(copy.fieldData().data(), originalFields); |
||||
} |
||||
} |
||||
|
||||
}}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::SceneTools::Test::CopyTest) |
||||
Loading…
Reference in new issue