@ -84,6 +84,7 @@ struct SceneDataTest: TestSuite::Tester {
void constructFieldTooLargeMappingStride ( ) ;
void constructFieldTooLargeMappingStride ( ) ;
void constructFieldTooLargeFieldStride ( ) ;
void constructFieldTooLargeFieldStride ( ) ;
void constructFieldOffsetOnlyNotAllowed ( ) ;
void constructFieldOffsetOnlyNotAllowed ( ) ;
void constructFieldTrivialNotAllowed ( ) ;
void constructFieldWrongDataAccess ( ) ;
void constructFieldWrongDataAccess ( ) ;
void constructField2DWrongSize ( ) ;
void constructField2DWrongSize ( ) ;
void constructField2DNonContiguous ( ) ;
void constructField2DNonContiguous ( ) ;
@ -196,6 +197,9 @@ struct SceneDataTest: TestSuite::Tester {
void fieldForFieldMissing ( ) ;
void fieldForFieldMissing ( ) ;
void findFieldObjectOffsetInvalidObject ( ) ;
void findFieldObjectOffsetInvalidObject ( ) ;
template < class T > void implicitNullMapping ( ) ;
template < class T > void trivialNullParent ( ) ;
void releaseFieldData ( ) ;
void releaseFieldData ( ) ;
void releaseData ( ) ;
void releaseData ( ) ;
} ;
} ;
@ -375,6 +379,7 @@ SceneDataTest::SceneDataTest() {
& SceneDataTest : : constructFieldTooLargeMappingStride ,
& SceneDataTest : : constructFieldTooLargeMappingStride ,
& SceneDataTest : : constructFieldTooLargeFieldStride ,
& SceneDataTest : : constructFieldTooLargeFieldStride ,
& SceneDataTest : : constructFieldOffsetOnlyNotAllowed ,
& SceneDataTest : : constructFieldOffsetOnlyNotAllowed ,
& SceneDataTest : : constructFieldTrivialNotAllowed ,
& SceneDataTest : : constructFieldWrongDataAccess ,
& SceneDataTest : : constructFieldWrongDataAccess ,
& SceneDataTest : : constructField2DWrongSize ,
& SceneDataTest : : constructField2DWrongSize ,
& SceneDataTest : : constructField2DNonContiguous ,
& SceneDataTest : : constructField2DNonContiguous ,
@ -562,6 +567,16 @@ SceneDataTest::SceneDataTest() {
addTests ( { & SceneDataTest : : fieldForFieldMissing ,
addTests ( { & SceneDataTest : : fieldForFieldMissing ,
& SceneDataTest : : findFieldObjectOffsetInvalidObject ,
& SceneDataTest : : findFieldObjectOffsetInvalidObject ,
& SceneDataTest : : implicitNullMapping < UnsignedByte > ,
& SceneDataTest : : implicitNullMapping < UnsignedShort > ,
& SceneDataTest : : implicitNullMapping < UnsignedInt > ,
& SceneDataTest : : implicitNullMapping < UnsignedLong > ,
& SceneDataTest : : trivialNullParent < Byte > ,
& SceneDataTest : : trivialNullParent < Short > ,
& SceneDataTest : : trivialNullParent < Int > ,
& SceneDataTest : : trivialNullParent < Long > ,
& SceneDataTest : : releaseFieldData ,
& SceneDataTest : : releaseFieldData ,
& SceneDataTest : : releaseData } ) ;
& SceneDataTest : : releaseData } ) ;
}
}
@ -1104,6 +1119,23 @@ void SceneDataTest::constructFieldOffsetOnlyNotAllowed() {
" Trade::SceneFieldData: can't pass Trade::SceneFieldFlag::OffsetOnly for a view \n " ) ;
" Trade::SceneFieldData: can't pass Trade::SceneFieldFlag::OffsetOnly for a view \n " ) ;
}
}
void SceneDataTest : : constructFieldTrivialNotAllowed ( ) {
# ifdef CORRADE_NO_ASSERT
CORRADE_SKIP ( " CORRADE_NO_ASSERT defined, can't test assertions " ) ;
# endif
const UnsignedShort rotationMappingData [ 3 ] { } ;
const Quaternion rotationFieldData [ 3 ] ;
std : : ostringstream out ;
Error redirectError { & out } ;
SceneFieldData { SceneField : : Rotation , 3 , SceneMappingType : : UnsignedShort , 0 , sizeof ( UnsignedShort ) , SceneFieldType : : Quaternion , 0 , sizeof ( Quaternion ) , SceneFieldFlag : : TrivialField } ;
SceneFieldData { sceneFieldCustom ( 666 ) , Containers : : arrayView ( rotationMappingData ) , Containers : : arrayView ( rotationFieldData ) , SceneFieldFlag : : TrivialField } ;
CORRADE_COMPARE ( out . str ( ) ,
" Trade::SceneFieldData: can't pass Trade::SceneFieldFlag::TrivialField for Trade::SceneField::Rotation \n "
" Trade::SceneFieldData: can't pass Trade::SceneFieldFlag::TrivialField for Trade::SceneField::Custom(666) \n " ) ;
}
void SceneDataTest : : constructFieldWrongDataAccess ( ) {
void SceneDataTest : : constructFieldWrongDataAccess ( ) {
# ifdef CORRADE_NO_ASSERT
# ifdef CORRADE_NO_ASSERT
CORRADE_SKIP ( " CORRADE_NO_ASSERT defined, can't test assertions " ) ;
CORRADE_SKIP ( " CORRADE_NO_ASSERT defined, can't test assertions " ) ;
@ -5552,6 +5584,284 @@ void SceneDataTest::findFieldObjectOffsetInvalidObject() {
" Trade::SceneData::skinsFor(): object 7 out of bounds for 7 objects \n " ) ;
" Trade::SceneData::skinsFor(): object 7 out of bounds for 7 objects \n " ) ;
}
}
template < class T > void SceneDataTest : : implicitNullMapping ( ) {
setTestCaseTemplateName ( NameTraits < T > : : name ( ) ) ;
struct Field {
UnsignedByte id ;
/* Mapping second so it isn't at offset 0, implying something weird */
T mapping ;
} data [ ] {
{ 1 , 0 } ,
{ 7 , 1 } ,
{ 22 , 2 } ,
{ 15 , 3 } ,
{ 3 , 5 } , /* this is to know whether we got our or generated data */
} ;
Containers : : StridedArrayView1D < Field > view = data ;
SceneData scene { Implementation : : sceneMappingTypeFor < T > ( ) , 6 , { } , data , {
/* Implicit mapping, with data supplied */
SceneFieldData { SceneField : : Mesh , view . slice ( & Field : : mapping ) , view . slice ( & Field : : id ) , SceneFieldFlag : : ImplicitMapping } ,
/* Implicit mapping, with no data */
SceneFieldData { SceneField : : Camera , Containers : : ArrayView < T > { nullptr , Containers : : arraySize ( data ) } , view . slice ( & Field : : id ) , SceneFieldFlag : : ImplicitMapping } ,
/* Implicit mapping offset-only, pointing to the data. This gets
ignored because there ' s no non - shitty non - magic - constants way to
know if the offset is valid . */
SceneFieldData { SceneField : : Light , Containers : : arraySize ( data ) , Implementation : : sceneMappingTypeFor < T > ( ) , offsetof ( Field , mapping ) , sizeof ( Field ) , SceneFieldType : : UnsignedByte , offsetof ( Field , id ) , sizeof ( Field ) , SceneFieldFlag : : ImplicitMapping } ,
/* Implicit mapping offset-only, pointing to wherever. Abusing a Parent
field and faking it to be signed because Skin needs some
transformation field as well */
SceneFieldData { SceneField : : Parent , Containers : : arraySize ( data ) , Implementation : : sceneMappingTypeFor < T > ( ) , 666666666 , 0 , SceneFieldType : : Byte , offsetof ( Field , id ) , sizeof ( Field ) , SceneFieldFlag : : ImplicitMapping }
} } ;
/* Only the non-null view will be non-null, the offset-only will all be
null also */
CORRADE_COMPARE ( scene . mapping ( 0 ) . data ( ) , & data [ 0 ] . mapping ) ;
CORRADE_COMPARE ( scene . mapping ( 1 ) . data ( ) , nullptr ) ;
CORRADE_COMPARE ( scene . mapping ( 2 ) . data ( ) , nullptr ) ;
CORRADE_COMPARE ( scene . mapping ( 3 ) . data ( ) , nullptr ) ;
/* If the view is not nullptr, it'll use the data and won't generate */
{
CORRADE_COMPARE_AS ( scene . meshesMaterialsAsArray ( ) , ( Containers : : arrayView < Containers : : Pair < UnsignedInt , Containers : : Pair < UnsignedInt , Int > > > ( {
{ 0 , { 1 , - 1 } } ,
{ 1 , { 7 , - 1 } } ,
{ 2 , { 22 , - 1 } } ,
{ 3 , { 15 , - 1 } } ,
{ 5 , { 3 , - 1 } } , /* this would be 4 if generated */
} ) ) , TestSuite : : Compare : : Container ) ;
CORRADE_COMPARE_AS ( scene . meshesMaterialsFor ( 3 ) , ( Containers : : arrayView < Containers : : Pair < UnsignedInt , Int > > ( {
{ 15 , - 1 }
} ) ) , TestSuite : : Compare : : Container ) ;
} {
UnsignedInt mapping [ 5 ] ;
scene . meshesMaterialsInto ( mapping , nullptr , nullptr ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( mapping ) , Containers : : arrayView < UnsignedInt > ( {
0 , 1 , 2 , 3 , 5 /* this would be 4 if generated */
} ) , TestSuite : : Compare : : Container ) ;
} {
UnsignedInt mapping [ 3 ] ;
scene . meshesMaterialsInto ( 2 , mapping , nullptr , nullptr ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( mapping ) , Containers : : arrayView < UnsignedInt > ( {
2 , 3 , 5 /* this would be 4 if generated */
} ) , TestSuite : : Compare : : Container ) ;
}
/* If the view is nullptr, it'll generate the data */
{
CORRADE_COMPARE_AS ( scene . camerasAsArray ( ) , ( Containers : : arrayView < Containers : : Pair < UnsignedInt , UnsignedInt > > ( {
{ 0 , 1 } ,
{ 1 , 7 } ,
{ 2 , 22 } ,
{ 3 , 15 } ,
{ 4 , 3 } ,
} ) ) , TestSuite : : Compare : : Container ) ;
CORRADE_COMPARE_AS ( scene . camerasFor ( 3 ) , Containers : : arrayView < UnsignedInt > ( {
15
} ) , TestSuite : : Compare : : Container ) ;
} {
UnsignedInt mapping [ 5 ] ;
scene . camerasInto ( mapping , nullptr ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( mapping ) , Containers : : arrayView < UnsignedInt > ( {
0 , 1 , 2 , 3 , 4
} ) , TestSuite : : Compare : : Container ) ;
} {
UnsignedInt mapping [ 3 ] ;
scene . camerasInto ( 2 , mapping , nullptr ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( mapping ) , Containers : : arrayView < UnsignedInt > ( {
2 , 3 , 4
} ) , TestSuite : : Compare : : Container ) ;
}
/* For an offset-only implicit mapping it'll generate the data always, even
if the mapping is seemingly there */
{
CORRADE_COMPARE_AS ( scene . lightsAsArray ( ) , ( Containers : : arrayView < Containers : : Pair < UnsignedInt , UnsignedInt > > ( {
{ 0 , 1 } ,
{ 1 , 7 } ,
{ 2 , 22 } ,
{ 3 , 15 } ,
{ 4 , 3 } ,
} ) ) , TestSuite : : Compare : : Container ) ;
CORRADE_COMPARE_AS ( scene . lightsFor ( 3 ) , Containers : : arrayView < UnsignedInt > ( {
15
} ) , TestSuite : : Compare : : Container ) ;
} {
UnsignedInt mapping [ 5 ] ;
scene . lightsInto ( mapping , nullptr ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( mapping ) , Containers : : arrayView < UnsignedInt > ( {
0 , 1 , 2 , 3 , 4
} ) , TestSuite : : Compare : : Container ) ;
} {
UnsignedInt mapping [ 3 ] ;
scene . lightsInto ( 2 , mapping , nullptr ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( mapping ) , Containers : : arrayView < UnsignedInt > ( {
2 , 3 , 4
} ) , TestSuite : : Compare : : Container ) ;
}
/* And if the offset is weirdly off it won't blow up on that */
{
CORRADE_COMPARE_AS ( scene . parentsAsArray ( ) , ( Containers : : arrayView < Containers : : Pair < UnsignedInt , Int > > ( {
{ 0 , 1 } ,
{ 1 , 7 } ,
{ 2 , 22 } ,
{ 3 , 15 } ,
{ 4 , 3 } ,
} ) ) , TestSuite : : Compare : : Container ) ;
CORRADE_COMPARE ( scene . parentFor ( 3 ) , 15 ) ;
} {
UnsignedInt mapping [ 5 ] ;
scene . parentsInto ( mapping , nullptr ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( mapping ) , Containers : : arrayView < UnsignedInt > ( {
0 , 1 , 2 , 3 , 4
} ) , TestSuite : : Compare : : Container ) ;
} {
UnsignedInt mapping [ 3 ] ;
scene . parentsInto ( 2 , mapping , nullptr ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( mapping ) , Containers : : arrayView < UnsignedInt > ( {
2 , 3 , 4
} ) , TestSuite : : Compare : : Container ) ;
}
}
template < class T > void SceneDataTest : : trivialNullParent ( ) {
setTestCaseTemplateName ( NameTraits < T > : : name ( ) ) ;
struct Field {
UnsignedInt mapping ;
T parent ;
} data [ ] {
{ 0 , - 1 } ,
{ 1 , - 1 } ,
{ 2 , - 1 } ,
{ 3 , - 2 } , /* this is to know whether we got our or generated data */
{ 5 , - 1 } , /* this is to know whether we got our or generated data */
} ;
Containers : : StridedArrayView1D < Field > view = data ;
/* If the view is not nullptr, it'll use the data and won't generate */
{
SceneData scene { SceneMappingType : : UnsignedInt , 6 , { } , data , {
SceneFieldData { SceneField : : Parent , view . slice ( & Field : : mapping ) , view . slice ( & Field : : parent ) , SceneFieldFlag : : TrivialField } ,
} } ;
CORRADE_COMPARE ( scene . field ( 0 ) . data ( ) , & data [ 0 ] . parent ) ;
CORRADE_COMPARE_AS ( scene . parentsAsArray ( ) , ( Containers : : arrayView < Containers : : Pair < UnsignedInt , Int > > ( {
{ 0 , - 1 } ,
{ 1 , - 1 } ,
{ 2 , - 1 } ,
{ 3 , - 2 } , /* this would be -1 if generated */
{ 5 , - 1 } , /* this would be 4 if generated */
} ) ) , TestSuite : : Compare : : Container ) ;
CORRADE_COMPARE ( scene . parentFor ( 3 ) , - 2 ) ;
Int parents [ 5 ] ;
scene . parentsInto ( nullptr , parents ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( parents ) , Containers : : arrayView < Int > ( {
- 1 , - 1 , - 1 , - 2 , /* this would be 4 if generated */ - 1
} ) , TestSuite : : Compare : : Container ) ;
}
/* If the view is nullptr, it'll generate the data */
{
SceneData scene { SceneMappingType : : UnsignedInt , 6 , { } , data , {
SceneFieldData { SceneField : : Parent , view . slice ( & Field : : mapping ) , Containers : : ArrayView < T > { nullptr , view . size ( ) } , SceneFieldFlag : : TrivialField } ,
} } ;
CORRADE_COMPARE ( scene . field ( 0 ) . data ( ) , nullptr ) ;
CORRADE_COMPARE_AS ( scene . parentsAsArray ( ) , ( Containers : : arrayView < Containers : : Pair < UnsignedInt , Int > > ( {
{ 0 , - 1 } ,
{ 1 , - 1 } ,
{ 2 , - 1 } ,
{ 3 , - 1 } ,
{ 5 , - 1 } , /* this would be 4 if generated */
} ) ) , TestSuite : : Compare : : Container ) ;
CORRADE_COMPARE ( scene . parentFor ( 3 ) , - 1 ) ;
Int parents [ 5 ] ;
scene . parentsInto ( nullptr , parents ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( parents ) , Containers : : arrayView < Int > ( {
- 1 , - 1 , - 1 , - 1 , - 1
} ) , TestSuite : : Compare : : Container ) ;
}
/* For an offset-only trivial field it'll generate the data always, even
if the field is seemingly there */
{
SceneData scene { SceneMappingType : : UnsignedInt , 6 , { } , data , {
SceneFieldData { SceneField : : Parent , view . size ( ) , SceneMappingType : : UnsignedInt , offsetof ( Field , mapping ) , sizeof ( Field ) , Implementation : : SceneFieldTypeFor < T > : : type ( ) , offsetof ( Field , parent ) , sizeof ( Field ) , SceneFieldFlag : : TrivialField } ,
} } ;
CORRADE_COMPARE ( scene . field ( 0 ) . data ( ) , nullptr ) ;
CORRADE_COMPARE_AS ( scene . parentsAsArray ( ) , ( Containers : : arrayView < Containers : : Pair < UnsignedInt , Int > > ( {
{ 0 , - 1 } ,
{ 1 , - 1 } ,
{ 2 , - 1 } ,
{ 3 , - 1 } ,
{ 5 , - 1 } , /* this would be 4 if generated */
} ) ) , TestSuite : : Compare : : Container ) ;
CORRADE_COMPARE ( scene . parentFor ( 3 ) , - 1 ) ;
Int parents [ 5 ] ;
scene . parentsInto ( nullptr , parents ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( parents ) , Containers : : arrayView < Int > ( {
- 1 , - 1 , - 1 , - 1 , - 1
} ) , TestSuite : : Compare : : Container ) ;
}
/* And if the offset is weirdly off it won't blow up on that */
{
SceneData scene { SceneMappingType : : UnsignedInt , 6 , { } , data , {
SceneFieldData { SceneField : : Parent , view . size ( ) , SceneMappingType : : UnsignedInt , offsetof ( Field , mapping ) , sizeof ( Field ) , Implementation : : SceneFieldTypeFor < T > : : type ( ) , 666666666 , 0 , SceneFieldFlag : : TrivialField } ,
} } ;
CORRADE_COMPARE ( scene . field ( 0 ) . data ( ) , nullptr ) ;
CORRADE_COMPARE_AS ( scene . parentsAsArray ( ) , ( Containers : : arrayView < Containers : : Pair < UnsignedInt , Int > > ( {
{ 0 , - 1 } ,
{ 1 , - 1 } ,
{ 2 , - 1 } ,
{ 3 , - 1 } ,
{ 5 , - 1 } , /* this would be 4 if generated */
} ) ) , TestSuite : : Compare : : Container ) ;
CORRADE_COMPARE ( scene . parentFor ( 3 ) , - 1 ) ;
Int parents [ 5 ] ;
scene . parentsInto ( nullptr , parents ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( parents ) , Containers : : arrayView < Int > ( {
- 1 , - 1 , - 1 , - 1 , - 1
} ) , TestSuite : : Compare : : Container ) ;
}
/* Finally, neither the mapping nor the field is specified */
{
SceneData scene { SceneMappingType : : UnsignedInt , 6 , { } , data , {
SceneFieldData { SceneField : : Parent ,
Containers : : ArrayView < UnsignedInt > { nullptr , view . size ( ) } ,
Containers : : ArrayView < T > { nullptr , view . size ( ) } ,
SceneFieldFlag : : ImplicitMapping | SceneFieldFlag : : TrivialField } ,
} } ;
CORRADE_COMPARE ( scene . field ( 0 ) . data ( ) , nullptr ) ;
CORRADE_COMPARE_AS ( scene . parentsAsArray ( ) , ( Containers : : arrayView < Containers : : Pair < UnsignedInt , Int > > ( {
{ 0 , - 1 } ,
{ 1 , - 1 } ,
{ 2 , - 1 } ,
{ 3 , - 1 } ,
{ 4 , - 1 } ,
} ) ) , TestSuite : : Compare : : Container ) ;
CORRADE_COMPARE ( scene . parentFor ( 3 ) , - 1 ) ;
UnsignedInt mapping [ 5 ] ;
Int parents [ 5 ] ;
scene . parentsInto ( mapping , parents ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( mapping ) , Containers : : arrayView < UnsignedInt > ( {
0 , 1 , 2 , 3 , 4
} ) , TestSuite : : Compare : : Container ) ;
CORRADE_COMPARE_AS ( Containers : : arrayView ( parents ) , Containers : : arrayView < Int > ( {
- 1 , - 1 , - 1 , - 1 , - 1
} ) , TestSuite : : Compare : : Container ) ;
}
}
void SceneDataTest : : releaseFieldData ( ) {
void SceneDataTest : : releaseFieldData ( ) {
struct Field {
struct Field {
UnsignedByte object ;
UnsignedByte object ;