1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
#if !NO_PERF
using System;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Reflection;
using System.Threading;
//
// BREAKING CHANGE v2 > v1.x - FromEvent[Pattern] now has an implicit SubscribeOn and Publish operation.
//
// See FromEvent.cs for more information.
//
namespace System.Reactive.Linq.ObservableImpl
{
class FromEventPattern
{
public class Impl<TDelegate, TEventArgs> : ClassicEventProducer<TDelegate, EventPattern<TEventArgs>>
#if !NO_EVENTARGS_CONSTRAINT
where TEventArgs : EventArgs
#endif
{
private readonly Func<EventHandler<TEventArgs>, TDelegate> _conversion;
public Impl(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
: base(addHandler, removeHandler, scheduler)
{
}
public Impl(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
: base(addHandler, removeHandler, scheduler)
{
_conversion = conversion;
}
protected override TDelegate GetHandler(Action<EventPattern<TEventArgs>> onNext)
{
var handler = default(TDelegate);
if (_conversion == null)
{
Action<object, TEventArgs> h = (sender, eventArgs) => onNext(new EventPattern<TEventArgs>(sender, eventArgs));
handler = ReflectionUtils.CreateDelegate<TDelegate>(h, typeof(Action<object, TEventArgs>).GetMethod("Invoke"));
}
else
{
handler = _conversion((sender, eventArgs) => onNext(new EventPattern<TEventArgs>(sender, eventArgs)));
}
return handler;
}
}
public class Impl<TDelegate, TSender, TEventArgs> : ClassicEventProducer<TDelegate, EventPattern<TSender, TEventArgs>>
#if !NO_EVENTARGS_CONSTRAINT
where TEventArgs : EventArgs
#endif
{
public Impl(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
: base(addHandler, removeHandler, scheduler)
{
}
protected override TDelegate GetHandler(Action<EventPattern<TSender, TEventArgs>> onNext)
{
Action<TSender, TEventArgs> h = (sender, eventArgs) => onNext(new EventPattern<TSender, TEventArgs>(sender, eventArgs));
return ReflectionUtils.CreateDelegate<TDelegate>(h, typeof(Action<TSender, TEventArgs>).GetMethod("Invoke"));
}
}
public class Handler<TSender, TEventArgs, TResult> : EventProducer<Delegate, TResult>
{
private readonly object _target;
private readonly Type _delegateType;
private readonly MethodInfo _addMethod;
private readonly MethodInfo _removeMethod;
private readonly Func<TSender, TEventArgs, TResult> _getResult;
#if HAS_WINRT
private readonly bool _isWinRT;
#endif
public Handler(object target, Type delegateType, MethodInfo addMethod, MethodInfo removeMethod, Func<TSender, TEventArgs, TResult> getResult, bool isWinRT, IScheduler scheduler)
: base(scheduler)
{
#if HAS_WINRT
_isWinRT = isWinRT;
#else
System.Diagnostics.Debug.Assert(!isWinRT);
#endif
_target = target;
_delegateType = delegateType;
_addMethod = addMethod;
_removeMethod = removeMethod;
_getResult = getResult;
}
protected override Delegate GetHandler(Action<TResult> onNext)
{
Action<TSender, TEventArgs> h = (sender, eventArgs) => onNext(_getResult(sender, eventArgs));
return ReflectionUtils.CreateDelegate(_delegateType, h, typeof(Action<TSender, TEventArgs>).GetMethod("Invoke"));
}
protected override IDisposable AddHandler(Delegate handler)
{
var removeHandler = default(Action);
try
{
#if HAS_WINRT
if (_isWinRT)
{
var token = _addMethod.Invoke(_target, new object[] { handler });
removeHandler = () => _removeMethod.Invoke(_target, new object[] { token });
}
else
#endif
{
_addMethod.Invoke(_target, new object[] { handler });
removeHandler = () => _removeMethod.Invoke(_target, new object[] { handler });
}
}
catch (TargetInvocationException tie)
{
throw tie.InnerException;
}
return Disposable.Create(() =>
{
try
{
removeHandler();
}
catch (TargetInvocationException tie)
{
throw tie.InnerException;
}
});
}
}
}
}
#endif
|