Skip to content

Commit

Permalink
enum arrays are not blittable - special cased (#860)
Browse files Browse the repository at this point in the history
* enum arrays are not blittable - special cased

* flags require different treatment

* reinstated array functions for all value types, just in case
  • Loading branch information
Scottj1s authored Jun 9, 2021
1 parent 7c19930 commit e372646
Show file tree
Hide file tree
Showing 6 changed files with 356 additions and 15 deletions.
151 changes: 151 additions & 0 deletions src/Tests/TestComponentCSharp/Class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,157 @@ namespace winrt::TestComponentCSharp::implementation
_bool = provideBool();
_boolChanged(*this, _bool);
}

TestComponentCSharp::EnumValue Class::EnumProperty()
{
return _enumValue;
}
void Class::EnumProperty(TestComponentCSharp::EnumValue const& value)
{
_enumValue = value;
}
winrt::event_token Class::EnumPropertyChanged(Windows::Foundation::EventHandler<TestComponentCSharp::EnumValue> const& handler)
{
return _enumChanged.add(handler);
}
void Class::EnumPropertyChanged(winrt::event_token const& token) noexcept
{
_enumChanged.remove(token);
}
void Class::RaiseEnumChanged()
{
_enumChanged(*this, _enumValue);
}
void Class::CallForEnum(TestComponentCSharp::ProvideEnum const& provide)
{
_enumValue = provide();
_enumChanged(*this, _enumValue);
}
TestComponentCSharp::EnumStruct Class::EnumStructProperty()
{
return _enumStruct;
}
void Class::EnumStructProperty(TestComponentCSharp::EnumStruct const& value)
{
_enumStruct = value;
}
winrt::event_token Class::EnumStructPropertyChanged(Windows::Foundation::EventHandler<TestComponentCSharp::EnumStruct> const& handler)
{
return _enumStructChanged.add(handler);
}
void Class::EnumStructPropertyChanged(winrt::event_token const& token) noexcept
{
_enumStructChanged.remove(token);
}
void Class::RaiseEnumStructChanged()
{
_enumStructChanged(*this, _enumStruct);
}
void Class::CallForEnumStruct(TestComponentCSharp::ProvideEnumStruct const& provide)
{
_enumStruct = provide();
_enumStructChanged(*this, _enumStruct);
}
com_array<TestComponentCSharp::EnumValue> Class::EnumsProperty()
{
return { _enums.begin(), _enums.end() };
}
void Class::EnumsProperty(array_view<TestComponentCSharp::EnumValue const> value)
{
_enums.assign(value.begin(), value.end());
}
void Class::CallForEnums(TestComponentCSharp::ProvideEnums const& provide)
{
EnumsProperty(provide());
}
com_array<TestComponentCSharp::EnumStruct> Class::EnumStructsProperty()
{
return { _enumStructs.begin(), _enumStructs.end() };
}
void Class::EnumStructsProperty(array_view<TestComponentCSharp::EnumStruct const> value)
{
_enumStructs.assign(value.begin(), value.end());
}
void Class::CallForEnumStructs(TestComponentCSharp::ProvideEnumStructs const& provide)
{
EnumStructsProperty(provide());
}

TestComponentCSharp::FlagValue Class::FlagProperty()
{
return _flagValue;
}
void Class::FlagProperty(TestComponentCSharp::FlagValue const& value)
{
_flagValue = value;
}
winrt::event_token Class::FlagPropertyChanged(Windows::Foundation::EventHandler<TestComponentCSharp::FlagValue> const& handler)
{
return _flagChanged.add(handler);
}
void Class::FlagPropertyChanged(winrt::event_token const& token) noexcept
{
_flagChanged.remove(token);
}
void Class::RaiseFlagChanged()
{
_flagChanged(*this, _flagValue);
}
void Class::CallForFlag(TestComponentCSharp::ProvideFlag const& provide)
{
_flagValue = provide();
_flagChanged(*this, _flagValue);
}
TestComponentCSharp::FlagStruct Class::FlagStructProperty()
{
return _flagStruct;
}
void Class::FlagStructProperty(TestComponentCSharp::FlagStruct const& value)
{
_flagStruct = value;
}
winrt::event_token Class::FlagStructPropertyChanged(Windows::Foundation::EventHandler<TestComponentCSharp::FlagStruct> const& handler)
{
return _flagStructChanged.add(handler);
}
void Class::FlagStructPropertyChanged(winrt::event_token const& token) noexcept
{
_flagStructChanged.remove(token);
}
void Class::RaiseFlagStructChanged()
{
_flagStructChanged(*this, _flagStruct);
}
void Class::CallForFlagStruct(TestComponentCSharp::ProvideFlagStruct const& provide)
{
_flagStruct = provide();
_flagStructChanged(*this, _flagStruct);
}
com_array<TestComponentCSharp::FlagValue> Class::FlagsProperty()
{
return { _flags.begin(), _flags.end() };
}
void Class::FlagsProperty(array_view<TestComponentCSharp::FlagValue const> value)
{
_flags.assign(value.begin(), value.end());
}
void Class::CallForFlags(TestComponentCSharp::ProvideFlags const& provide)
{
FlagsProperty(provide());
}
com_array<TestComponentCSharp::FlagStruct> Class::FlagStructsProperty()
{
return { _flagStructs.begin(), _flagStructs.end() };
}
void Class::FlagStructsProperty(array_view<TestComponentCSharp::FlagStruct const> value)
{
_flagStructs.assign(value.begin(), value.end());
}
void Class::CallForFlagStructs(TestComponentCSharp::ProvideFlagStructs const& provide)
{
FlagStructsProperty(provide());
}

hstring Class::StringProperty()
{
return _string;
Expand Down
48 changes: 48 additions & 0 deletions src/Tests/TestComponentCSharp/Class.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ namespace winrt::TestComponentCSharp::implementation
winrt::event<Windows::Foundation::EventHandler<int32_t>> _intChanged;
bool _bool = false;
winrt::event<Windows::Foundation::EventHandler<bool>> _boolChanged;
EnumValue _enumValue;
winrt::event<Windows::Foundation::EventHandler<EnumValue>> _enumChanged;
std::vector<EnumValue> _enums{ EnumValue::One, EnumValue::Two };
EnumStruct _enumStruct;
winrt::event<Windows::Foundation::EventHandler<EnumStruct>> _enumStructChanged;
std::vector<EnumStruct> _enumStructs{ EnumStruct{EnumValue::One}, EnumStruct{EnumValue::Two} };
FlagValue _flagValue;
winrt::event<Windows::Foundation::EventHandler<FlagValue>> _flagChanged;
std::vector<FlagValue> _flags{ FlagValue::One, FlagValue::All };
FlagStruct _flagStruct;
winrt::event<Windows::Foundation::EventHandler<FlagStruct>> _flagStructChanged;
std::vector<FlagStruct> _flagStructs{ FlagStruct{FlagValue::One}, FlagStruct{FlagValue::All} };
winrt::hstring _string;
winrt::hstring _string2;
winrt::event<Windows::Foundation::TypedEventHandler<TestComponentCSharp::Class, hstring>> _stringChanged;
Expand Down Expand Up @@ -133,6 +145,42 @@ namespace winrt::TestComponentCSharp::implementation
void BoolPropertyChanged(winrt::event_token const& token) noexcept;
void RaiseBoolChanged();
void CallForBool(TestComponentCSharp::ProvideBool const& provideBool);
TestComponentCSharp::EnumValue EnumProperty();
void EnumProperty(TestComponentCSharp::EnumValue const& value);
winrt::event_token EnumPropertyChanged(Windows::Foundation::EventHandler<TestComponentCSharp::EnumValue> const& handler);
void EnumPropertyChanged(winrt::event_token const& token) noexcept;
void RaiseEnumChanged();
void CallForEnum(TestComponentCSharp::ProvideEnum const& provide);
TestComponentCSharp::EnumStruct EnumStructProperty();
void EnumStructProperty(TestComponentCSharp::EnumStruct const& value);
winrt::event_token EnumStructPropertyChanged(Windows::Foundation::EventHandler<TestComponentCSharp::EnumStruct> const& handler);
void EnumStructPropertyChanged(winrt::event_token const& token) noexcept;
void RaiseEnumStructChanged();
void CallForEnumStruct(TestComponentCSharp::ProvideEnumStruct const& provide);
com_array<TestComponentCSharp::EnumValue> EnumsProperty();
void EnumsProperty(array_view<TestComponentCSharp::EnumValue const> value);
void CallForEnums(TestComponentCSharp::ProvideEnums const& provide);
com_array<TestComponentCSharp::EnumStruct> EnumStructsProperty();
void EnumStructsProperty(array_view<TestComponentCSharp::EnumStruct const> value);
void CallForEnumStructs(TestComponentCSharp::ProvideEnumStructs const& provide);
TestComponentCSharp::FlagValue FlagProperty();
void FlagProperty(TestComponentCSharp::FlagValue const& value);
winrt::event_token FlagPropertyChanged(Windows::Foundation::EventHandler<TestComponentCSharp::FlagValue> const& handler);
void FlagPropertyChanged(winrt::event_token const& token) noexcept;
void RaiseFlagChanged();
void CallForFlag(TestComponentCSharp::ProvideFlag const& provide);
TestComponentCSharp::FlagStruct FlagStructProperty();
void FlagStructProperty(TestComponentCSharp::FlagStruct const& value);
winrt::event_token FlagStructPropertyChanged(Windows::Foundation::EventHandler<TestComponentCSharp::FlagStruct> const& handler);
void FlagStructPropertyChanged(winrt::event_token const& token) noexcept;
void RaiseFlagStructChanged();
void CallForFlagStruct(TestComponentCSharp::ProvideFlagStruct const& provide);
com_array<TestComponentCSharp::FlagValue> FlagsProperty();
void FlagsProperty(array_view<TestComponentCSharp::FlagValue const> value);
void CallForFlags(TestComponentCSharp::ProvideFlags const& provide);
com_array<TestComponentCSharp::FlagStruct> FlagStructsProperty();
void FlagStructsProperty(array_view<TestComponentCSharp::FlagStruct const> value);
void CallForFlagStructs(TestComponentCSharp::ProvideFlagStructs const& provide);
hstring StringProperty();
void StringProperty(hstring const& value);
winrt::event_token StringPropertyChanged(Windows::Foundation::TypedEventHandler<TestComponentCSharp::Class, hstring> const& handler);
Expand Down
59 changes: 58 additions & 1 deletion src/Tests/TestComponentCSharp/TestComponentCSharp.idl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,29 @@ namespace TestComponentCSharp
delegate void EventHandlerCollection(Class sender, Windows.Foundation.Collections.IVector<Int32> arg0, Windows.Foundation.Collections.IMap<Int32, String> arg1);
delegate Int32 EventWithReturn(Int32 arg);

[flags]
enum FlagValue
{
One = 0x00000001,
All = 0xFFFFFFFF,
};

struct FlagStruct
{
FlagValue value;
};

enum EnumValue
{
One,
Two,
};

struct EnumStruct
{
EnumValue value;
};

struct BlittableStruct
{
Int32 i32;
Expand Down Expand Up @@ -54,6 +77,14 @@ namespace TestComponentCSharp
delegate Boolean ProvideBool();
delegate String ProvideString();
delegate Object ProvideObject();
delegate EnumValue ProvideEnum();
delegate EnumValue[] ProvideEnums();
delegate FlagValue ProvideFlag();
delegate FlagValue[] ProvideFlags();
delegate EnumStruct ProvideEnumStruct();
delegate EnumStruct[] ProvideEnumStructs();
delegate FlagStruct ProvideFlagStruct();
delegate FlagStruct[] ProvideFlagStructs();
delegate Windows.Foundation.Collections.IIterable<Object> ProvideObjectIterable();
delegate Windows.Foundation.Uri ProvideUri();
delegate Windows.Foundation.Collections.IKeyValuePair<String, String> ProvideStringPair();
Expand Down Expand Up @@ -159,6 +190,32 @@ namespace TestComponentCSharp
void RaiseBoolChanged();
void CallForBool(ProvideBool provideBool);

// Enums (oddly, arrays are not blittable - but all other structurings are)
EnumValue EnumProperty;
event Windows.Foundation.EventHandler<EnumValue> EnumPropertyChanged;
void RaiseEnumChanged();
void CallForEnum(ProvideEnum provide);
EnumStruct EnumStructProperty;
event Windows.Foundation.EventHandler<EnumStruct> EnumStructPropertyChanged;
void RaiseEnumStructChanged();
void CallForEnumStruct(ProvideEnumStruct provide);
EnumValue[] EnumsProperty;
void CallForEnums(ProvideEnums provide);
EnumStruct[] EnumStructsProperty;
void CallForEnumStructs(ProvideEnumStructs provide);
FlagValue FlagProperty;
event Windows.Foundation.EventHandler<FlagValue> FlagPropertyChanged;
void RaiseFlagChanged();
void CallForFlag(ProvideFlag provide);
FlagStruct FlagStructProperty;
event Windows.Foundation.EventHandler<FlagStruct> FlagStructPropertyChanged;
void RaiseFlagStructChanged();
void CallForFlagStruct(ProvideFlagStruct provide);
FlagValue[] FlagsProperty;
void CallForFlags(ProvideFlags provide);
FlagStruct[] FlagStructsProperty;
void CallForFlagStructs(ProvideFlagStructs provide);

String StringProperty;
event Windows.Foundation.TypedEventHandler<Class, String> StringPropertyChanged;
void RaiseStringChanged();
Expand All @@ -182,7 +239,7 @@ namespace TestComponentCSharp
Windows.Foundation.Uri UriProperty;
void RaiseUriChanged();
void CallForUri(ProvideUri provideUri);
event Windows.Foundation.EventHandler<Windows.Foundation.Uri > UriPropertyChanged;
event Windows.Foundation.EventHandler<Windows.Foundation.Uri> UriPropertyChanged;

Windows.Foundation.Collections.IKeyValuePair<String, String> StringPairProperty;
void RaiseStringPairChanged();
Expand Down
66 changes: 66 additions & 0 deletions src/Tests/UnitTest/TestComponentCSharp_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,72 @@ public TestCSharp()
TestObject = new Class();
}

[Fact]
public void TestEnums()
{
// Enums
var expectedEnum = EnumValue.Two;
TestObject.EnumProperty = expectedEnum;
Assert.Equal(expectedEnum, TestObject.EnumProperty);
expectedEnum = EnumValue.One;
TestObject.CallForEnum(() => expectedEnum);
TestObject.EnumPropertyChanged +=
(object sender, EnumValue value) => Assert.Equal(expectedEnum, value);
TestObject.RaiseEnumChanged();

var expectedEnumStruct = new EnumStruct() { value = EnumValue.Two };
TestObject.EnumStructProperty = expectedEnumStruct;
Assert.Equal(expectedEnumStruct, TestObject.EnumStructProperty);
expectedEnumStruct = new EnumStruct() { value = EnumValue.One };
TestObject.CallForEnumStruct(() => expectedEnumStruct);
TestObject.EnumStructPropertyChanged +=
(object sender, EnumStruct value) => Assert.Equal(expectedEnumStruct, value);
TestObject.RaiseEnumStructChanged();

var expectedEnums = new EnumValue[] { EnumValue.One, EnumValue.Two };
TestObject.EnumsProperty = expectedEnums;
Assert.Equal(expectedEnums, TestObject.EnumsProperty);
TestObject.CallForEnums(() => expectedEnums);
Assert.Equal(expectedEnums, TestObject.EnumsProperty);

var expectedEnumStructs = new EnumStruct[] { new EnumStruct(EnumValue.One), new EnumStruct(EnumValue.Two) };
TestObject.EnumStructsProperty = expectedEnumStructs;
Assert.Equal(expectedEnumStructs, TestObject.EnumStructsProperty);
TestObject.CallForEnumStructs(() => expectedEnumStructs);
Assert.Equal(expectedEnumStructs, TestObject.EnumStructsProperty);

// Flags
var expectedFlag = FlagValue.All;
TestObject.FlagProperty = expectedFlag;
Assert.Equal(expectedFlag, TestObject.FlagProperty);
expectedFlag = FlagValue.One;
TestObject.CallForFlag(() => expectedFlag);
TestObject.FlagPropertyChanged +=
(object sender, FlagValue value) => Assert.Equal(expectedFlag, value);
TestObject.RaiseFlagChanged();

var expectedFlagStruct = new FlagStruct() { value = FlagValue.All };
TestObject.FlagStructProperty = expectedFlagStruct;
Assert.Equal(expectedFlagStruct, TestObject.FlagStructProperty);
expectedFlagStruct = new FlagStruct() { value = FlagValue.One };
TestObject.CallForFlagStruct(() => expectedFlagStruct);
TestObject.FlagStructPropertyChanged +=
(object sender, FlagStruct value) => Assert.Equal(expectedFlagStruct, value);
TestObject.RaiseFlagStructChanged();

var expectedFlags = new FlagValue[] { FlagValue.One, FlagValue.All };
TestObject.FlagsProperty = expectedFlags;
Assert.Equal(expectedFlags, TestObject.FlagsProperty);
TestObject.CallForFlags(() => expectedFlags);
Assert.Equal(expectedFlags, TestObject.FlagsProperty);

var expectedFlagStructs = new FlagStruct[] { new FlagStruct(FlagValue.One), new FlagStruct(FlagValue.All) };
TestObject.FlagStructsProperty = expectedFlagStructs;
Assert.Equal(expectedFlagStructs, TestObject.FlagStructsProperty);
TestObject.CallForFlagStructs(() => expectedFlagStructs);
Assert.Equal(expectedFlagStructs, TestObject.FlagStructsProperty);
}

[Fact]
public void TestGetByte()
{
Expand Down
Loading

0 comments on commit e372646

Please sign in to comment.