Skip to content

Commit

Permalink
add support for non-void event delegates (#418)
Browse files Browse the repository at this point in the history
  • Loading branch information
Scottj1s authored Sep 22, 2020
1 parent 290e744 commit 224ee35
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 2 deletions.
13 changes: 13 additions & 0 deletions TestComponentCSharp/Class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,19 @@ namespace winrt::TestComponentCSharp::implementation
{
_nestedTypedEvent(sender, arg0);
}
winrt::event_token Class::ReturnEvent(TestComponentCSharp::EventWithReturn const& handler)
{
return _returnEvent.add(handler);
}
void Class::ReturnEvent(winrt::event_token const& token) noexcept
{
_returnEvent.remove(token);
}
int32_t Class::InvokeReturnEvent(int32_t const& arg0)
{
_returnEvent(arg0);
return arg0;
}
int32_t Class::IntProperty()
{
return _int;
Expand Down
5 changes: 5 additions & 0 deletions TestComponentCSharp/Class.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace winrt::TestComponentCSharp::implementation
winrt::event<EventHandlerCollection> _collectionEvent;
winrt::event<Windows::Foundation::EventHandler<Windows::Foundation::Collections::IVector<int32_t>>> _nestedEvent;
winrt::event<Windows::Foundation::TypedEventHandler<TestComponentCSharp::Class, Windows::Foundation::Collections::IVector<hstring>>> _nestedTypedEvent;
winrt::event<TestComponentCSharp::EventWithReturn> _returnEvent;

int32_t _int = 0;
winrt::event<Windows::Foundation::EventHandler<int32_t>> _intChanged;
Expand Down Expand Up @@ -106,6 +107,10 @@ namespace winrt::TestComponentCSharp::implementation
winrt::event_token NestedTypedEvent(Windows::Foundation::TypedEventHandler<TestComponentCSharp::Class, Windows::Foundation::Collections::IVector<hstring>> const& handler);
void NestedTypedEvent(winrt::event_token const& token) noexcept;
void InvokeNestedTypedEvent(TestComponentCSharp::Class const& sender, Windows::Foundation::Collections::IVector<hstring> const& arg0);
winrt::event_token ReturnEvent(TestComponentCSharp::EventWithReturn const& handler);
void ReturnEvent(winrt::event_token const& token) noexcept;
int32_t InvokeReturnEvent(int32_t const& arg0);

int32_t IntProperty();
void IntProperty(int32_t value);
winrt::event_token IntPropertyChanged(Windows::Foundation::EventHandler<int32_t> const& handler);
Expand Down
3 changes: 3 additions & 0 deletions TestComponentCSharp/TestComponentCSharp.idl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace TestComponentCSharp
delegate void EventHandler2(Class sender, Int32 arg0);
delegate void EventHandler3(Class sender, Int32 arg0, String arg1);
delegate void EventHandlerCollection(Class sender, Windows.Foundation.Collections.IVector<Int32> arg0, Windows.Foundation.Collections.IMap<Int32, String> arg1);
delegate Int32 EventWithReturn(Int32 arg);

struct BlittableStruct
{
Expand Down Expand Up @@ -135,6 +136,8 @@ namespace TestComponentCSharp
void InvokeNestedEvent(Class sender, Windows.Foundation.Collections.IVector<Int32> arg0);
event Windows.Foundation.TypedEventHandler<Class, Windows.Foundation.Collections.IVector<String> > NestedTypedEvent;
void InvokeNestedTypedEvent(Class sender, Windows.Foundation.Collections.IVector<String> arg0);
event EventWithReturn ReturnEvent;
Int32 InvokeReturnEvent(Int32 arg0);

Int32 IntProperty;
event Windows.Foundation.EventHandler<Int32> IntPropertyChanged;
Expand Down
8 changes: 8 additions & 0 deletions UnitTest/TestComponentCSharp_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ public void TestEvents()
TestObject.InvokeNestedEvent(TestObject, ints);
events_expected++;

TestObject.ReturnEvent += (int arg0) =>
{
events_received++;
return arg0;
};
Assert.Equal(42, TestObject.InvokeReturnEvent(42));
events_expected++;

var collection0 = new int[] { 42, 1729 };
var collection1 = new Dictionary<int, string> { [1] = "foo", [2] = "bar" };
TestObject.CollectionEvent += (Class sender, IList<int> arg0, IDictionary<int, string> arg1) =>
Expand Down
7 changes: 5 additions & 2 deletions cswinrt/strings/WinRT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,10 +409,13 @@ private System.Delegate EventInvoke

_eventInvoke = Expression.Lambda(typeof(TDelegate),
Expression.Block(
invoke.ReturnType,
new[] { delegateLocal },
Expression.Assign(delegateLocal, Expression.Field(Expression.Constant(this), typeof(EventSource<TDelegate>).GetField(nameof(_event), BindingFlags.Instance | BindingFlags.NonPublic))),
Expression.IfThen(
Expression.ReferenceNotEqual(delegateLocal, Expression.Constant(null, typeof(TDelegate))), Expression.Call(delegateLocal, invoke, parameters))),
Expression.Condition(
Expression.ReferenceNotEqual(delegateLocal, Expression.Constant(null, typeof(TDelegate))),
Expression.Call(delegateLocal, invoke, parameters),
Expression.Default(invoke.ReturnType))),
parameters).Compile();

return _eventInvoke;
Expand Down

0 comments on commit 224ee35

Please sign in to comment.