Nui
event.h
Go to the documentation of this file.
1 //
2 // Copyright (C) Microsoft Corporation
3 // All rights reserved.
4 //
5 // Code in details namespace is for internal usage within the library code
6 //
7 #pragma once
8 
9 #include <type_traits>
10 
11 #include <wrl\def.h>
12 #include <wrl\internal.h>
13 #include <wrl\client.h>
14 #include <wrl\implements.h>
15 #include <wrl\wrappers\corewrappers.h>
16 #include <eventtoken.h>
17 
18 #define WrlSealed
19 
20 // Set packing
21 #pragma pack(push, 8)
22 
23 #ifdef ____x_Windows_CFoundation_CIDeferral_FWD_DEFINED__
24 namespace ABI
25 {
26  namespace Windows
27  {
28  namespace Foundation
29  {
30  typedef ::Windows::Foundation::IDeferral IDeferral;
31  typedef ::Windows::Foundation::IDeferralFactory IDeferralFactory;
32  typedef ::Windows::Foundation::IDeferralCompletedHandler IDeferralCompletedHandler;
33  }
34  }
35 }
36 #endif
37 
38 namespace Microsoft
39 {
40  namespace WRL
41  {
42  // Enum to specify the behavior on checking delegate return results
44  {
45  NoCheck = 1
46  };
47  extern __declspec(selectany) const DelegateCheckMode DefaultDelegateCheckMode = NoCheck;
48 
49  template <DelegateCheckMode delegateCheckMode>
51 
52  template <>
54  {
55  static HRESULT CheckReturn(HRESULT hr)
56  {
57  return hr;
58  }
59  };
60 
61  // Enum to specify the behavior when firing event delegates
63  {
65  FireAll = 2,
66  };
67 
68  // Event error options
69  template <InvokeMode invokeModeValue>
71  {
72  static const InvokeMode invokeMode = invokeModeValue;
73  };
74 
75  // Forward Declaration
76  template <InvokeMode invokeMode>
77  struct InvokeTraits;
78  template <typename TDelegateInterface, typename EventSourceOptions>
79  class EventSource;
80 
81  namespace Details
82  {
83 
84  template <typename TDelegateInterface>
85  void* GetDelegateBucketAssist(TDelegateInterface* pDelegate)
86  {
87  // By ABI contract, delegates satisfy the below as a mechanism of getting at the invocation
88  // function (the fourth slot in the V-Table of the delegate interface). We do not care about
89  // the signature of the function, only its address as a means of improving bucketing.
90  void*** pVT = reinterpret_cast<void***>(pDelegate);
91  return (*pVT)[3];
92  }
93 
94  // ArgTraits allows to determine amount of parameters
95  // on Invoke method of delegate interface
96  template <typename TMemberFunction>
97  struct ArgTraits
98  {
99  static const int args = -1; // Indicates that we cannot match Invoke method signature
100  };
101 
102  template <typename TDelegateInterface>
103  struct ArgTraits<HRESULT (STDMETHODCALLTYPE TDelegateInterface::*)(void)>
104  {
105  static const int args = 0;
106  };
107 
108  template <typename TDelegateInterface, typename TArg1>
109  struct ArgTraits<HRESULT (STDMETHODCALLTYPE TDelegateInterface::*)(TArg1)>
110  {
111  static const int args = 1;
112  typedef TArg1 Arg1Type;
113  };
114 
115  template <typename TDelegateInterface, typename TArg1, typename TArg2>
116  struct ArgTraits<HRESULT (STDMETHODCALLTYPE TDelegateInterface::*)(TArg1, TArg2)>
117  {
118  static const int args = 2;
119  typedef TArg1 Arg1Type;
120  typedef TArg2 Arg2Type;
121  };
122 
123  template <typename TDelegateInterface, typename TArg1, typename TArg2, typename TArg3>
124  struct ArgTraits<HRESULT (STDMETHODCALLTYPE TDelegateInterface::*)(TArg1, TArg2, TArg3)>
125  {
126  static const int args = 3;
127  typedef TArg1 Arg1Type;
128  typedef TArg2 Arg2Type;
129  typedef TArg3 Arg3Type;
130  };
131 
132  template <typename TDelegateInterface, typename TArg1, typename TArg2, typename TArg3, typename TArg4>
133  struct ArgTraits<HRESULT (STDMETHODCALLTYPE TDelegateInterface::*)(TArg1, TArg2, TArg3, TArg4)>
134  {
135  static const int args = 4;
136  typedef TArg1 Arg1Type;
137  typedef TArg2 Arg2Type;
138  typedef TArg3 Arg3Type;
139  typedef TArg4 Arg4Type;
140  };
141 
142  template <
143  typename TDelegateInterface,
144  typename TArg1,
145  typename TArg2,
146  typename TArg3,
147  typename TArg4,
148  typename TArg5>
149  struct ArgTraits<HRESULT (STDMETHODCALLTYPE TDelegateInterface::*)(TArg1, TArg2, TArg3, TArg4, TArg5)>
150  {
151  static const int args = 5;
152  typedef TArg1 Arg1Type;
153  typedef TArg2 Arg2Type;
154  typedef TArg3 Arg3Type;
155  typedef TArg4 Arg4Type;
156  typedef TArg5 Arg5Type;
157  };
158 
159  template <
160  typename TDelegateInterface,
161  typename TArg1,
162  typename TArg2,
163  typename TArg3,
164  typename TArg4,
165  typename TArg5,
166  typename TArg6>
167  struct ArgTraits<HRESULT (
168  STDMETHODCALLTYPE TDelegateInterface::*)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6)>
169  {
170  static const int args = 6;
171  typedef TArg1 Arg1Type;
172  typedef TArg2 Arg2Type;
173  typedef TArg3 Arg3Type;
174  typedef TArg4 Arg4Type;
175  typedef TArg5 Arg5Type;
176  typedef TArg6 Arg6Type;
177  };
178 
179  template <
180  typename TDelegateInterface,
181  typename TArg1,
182  typename TArg2,
183  typename TArg3,
184  typename TArg4,
185  typename TArg5,
186  typename TArg6,
187  typename TArg7>
188  struct ArgTraits<HRESULT (
189  STDMETHODCALLTYPE TDelegateInterface::*)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7)>
190  {
191  static const int args = 7;
192  typedef TArg1 Arg1Type;
193  typedef TArg2 Arg2Type;
194  typedef TArg3 Arg3Type;
195  typedef TArg4 Arg4Type;
196  typedef TArg5 Arg5Type;
197  typedef TArg6 Arg6Type;
198  typedef TArg7 Arg7Type;
199  };
200 
201  template <
202  typename TDelegateInterface,
203  typename TArg1,
204  typename TArg2,
205  typename TArg3,
206  typename TArg4,
207  typename TArg5,
208  typename TArg6,
209  typename TArg7,
210  typename TArg8>
211  struct ArgTraits<HRESULT (
212  STDMETHODCALLTYPE TDelegateInterface::*)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8)>
213  {
214  static const int args = 8;
215  typedef TArg1 Arg1Type;
216  typedef TArg2 Arg2Type;
217  typedef TArg3 Arg3Type;
218  typedef TArg4 Arg4Type;
219  typedef TArg5 Arg5Type;
220  typedef TArg6 Arg6Type;
221  typedef TArg7 Arg7Type;
222  typedef TArg8 Arg8Type;
223  };
224 
225  template <
226  typename TDelegateInterface,
227  typename TArg1,
228  typename TArg2,
229  typename TArg3,
230  typename TArg4,
231  typename TArg5,
232  typename TArg6,
233  typename TArg7,
234  typename TArg8,
235  typename TArg9>
236  struct ArgTraits<HRESULT (
237  STDMETHODCALLTYPE TDelegateInterface::*)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9)>
238  {
239  static const int args = 9;
240  typedef TArg1 Arg1Type;
241  typedef TArg2 Arg2Type;
242  typedef TArg3 Arg3Type;
243  typedef TArg4 Arg4Type;
244  typedef TArg5 Arg5Type;
245  typedef TArg6 Arg6Type;
246  typedef TArg7 Arg7Type;
247  typedef TArg8 Arg8Type;
248  typedef TArg9 Arg9Type;
249  };
250 
251  // Traits factory extract appropriate ArgTraits type
252  // for delegate interface
253  // template <typename TDelegateInterface, bool isImplements = __is_base_of(ImplementsBase,
254  // TDelegateInterface)>
255  template <
256  typename TDelegateInterface,
257  bool isImplements = std::is_base_of_v<ImplementsBase, TDelegateInterface>>
259 
260  // Specialization for the none Implements based interface
261  template <typename TDelegateInterface>
262  struct ArgTraitsHelper<TDelegateInterface, false>
263  {
264  typedef decltype(&TDelegateInterface::Invoke) methodType;
266  static const int args = Traits::args;
267  typedef TDelegateInterface Interface;
268  // Make sure that you are using STDMETHOD macro to define delegate interfaces
269  static_assert(
270  args != -1,
271  "Delegate Invoke signature doesn't match. Possible reasons: wrong calling convention, wrong "
272  "returned type or passed too many parameters to 'Callback'");
273  };
274 
275  // Specialization for Implements based interface
276  template <typename TDelegateInterface>
277  struct ArgTraitsHelper<TDelegateInterface, true>
278  : ArgTraitsHelper<typename TDelegateInterface::FirstInterface>
279  {};
280 
281  // Invoke helper provide implementation of invoke method
282  // depending on amount and type of arguments from ArgTraitsHelper
283  template <typename TDelegateInterface, typename TCallback, unsigned int argCount>
284  struct InvokeHelper;
285 
286  template <typename TDelegateInterface, typename TCallback>
287  struct InvokeHelper<TDelegateInterface, TCallback, 0> WrlSealed
288  : public ::Microsoft::WRL::RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
289  {
290  explicit InvokeHelper(TCallback callback) throw()
291  : callback_(callback)
292  {}
293 
294  STDMETHOD(Invoke)()
295  {
297  }
298  TCallback callback_;
299  };
300 
301  template <typename TDelegateInterface, typename TCallback>
302  struct InvokeHelper<TDelegateInterface, TCallback, 1> WrlSealed
303  : public ::Microsoft::WRL::RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
304  {
306 
307  explicit InvokeHelper(TCallback callback) throw()
308  : callback_(callback)
309  {}
310 
311  STDMETHOD(Invoke)(typename Traits::Arg1Type arg1)
312  {
314  }
315  TCallback callback_;
316  };
317 
318  template <typename TDelegateInterface, typename TCallback>
319  struct InvokeHelper<TDelegateInterface, TCallback, 2> WrlSealed
320  : public ::Microsoft::WRL::RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
321  {
323 
324  explicit InvokeHelper(TCallback callback) throw()
325  : callback_(callback)
326  {}
327 
328  STDMETHOD(Invoke)(typename Traits::Arg1Type arg1, typename Traits::Arg2Type arg2)
329  {
330  return DelegateTraits<DefaultDelegateCheckMode>::CheckReturn(callback_(arg1, arg2));
331  }
332  TCallback callback_;
333  };
334 
335  template <typename TDelegateInterface, typename TCallback>
336  struct InvokeHelper<TDelegateInterface, TCallback, 3> WrlSealed
337  : public ::Microsoft::WRL::RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
338  {
340 
341  explicit InvokeHelper(TCallback callback) throw()
342  : callback_(callback)
343  {}
344 
345  STDMETHOD(Invoke)
346  (typename Traits::Arg1Type arg1, typename Traits::Arg2Type arg2, typename Traits::Arg3Type arg3)
347  {
348  return DelegateTraits<DefaultDelegateCheckMode>::CheckReturn(callback_(arg1, arg2, arg3));
349  }
350  TCallback callback_;
351  };
352 
353  template <typename TDelegateInterface, typename TCallback>
354  struct InvokeHelper<TDelegateInterface, TCallback, 4> WrlSealed
355  : ::Microsoft::WRL::RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
356  {
358 
359  explicit InvokeHelper(TCallback callback) throw()
360  : callback_(callback)
361  {}
362 
363  STDMETHOD(Invoke)
364  (typename Traits::Arg1Type arg1,
365  typename Traits::Arg2Type arg2,
366  typename Traits::Arg3Type arg3,
367  typename Traits::Arg4Type arg4)
368  {
369  return DelegateTraits<DefaultDelegateCheckMode>::CheckReturn(callback_(arg1, arg2, arg3, arg4));
370  }
371  TCallback callback_;
372  };
373 
374  template <typename TDelegateInterface, typename TCallback>
375  struct InvokeHelper<TDelegateInterface, TCallback, 5> WrlSealed
376  : ::Microsoft::WRL::RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
377  {
379 
380  explicit InvokeHelper(TCallback callback) throw()
381  : callback_(callback)
382  {}
383 
384  STDMETHOD(Invoke)
385  (typename Traits::Arg1Type arg1,
386  typename Traits::Arg2Type arg2,
387  typename Traits::Arg3Type arg3,
388  typename Traits::Arg4Type arg4,
389  typename Traits::Arg5Type arg5)
390  {
392  callback_(arg1, arg2, arg3, arg4, arg5));
393  }
394  TCallback callback_;
395  };
396 
397  template <typename TDelegateInterface, typename TCallback>
398  struct InvokeHelper<TDelegateInterface, TCallback, 6> WrlSealed
399  : ::Microsoft::WRL::RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
400  {
402 
403  explicit InvokeHelper(TCallback callback) throw()
404  : callback_(callback)
405  {}
406 
407  STDMETHOD(Invoke)
408  (typename Traits::Arg1Type arg1,
409  typename Traits::Arg2Type arg2,
410  typename Traits::Arg3Type arg3,
411  typename Traits::Arg4Type arg4,
412  typename Traits::Arg5Type arg5,
413  typename Traits::Arg6Type arg6)
414  {
416  callback_(arg1, arg2, arg3, arg4, arg5, arg6));
417  }
418  TCallback callback_;
419  };
420 
421  template <typename TDelegateInterface, typename TCallback>
422  struct InvokeHelper<TDelegateInterface, TCallback, 7> WrlSealed
423  : ::Microsoft::WRL::RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
424  {
426 
427  explicit InvokeHelper(TCallback callback) throw()
428  : callback_(callback)
429  {}
430 
431  STDMETHOD(Invoke)
432  (typename Traits::Arg1Type arg1,
433  typename Traits::Arg2Type arg2,
434  typename Traits::Arg3Type arg3,
435  typename Traits::Arg4Type arg4,
436  typename Traits::Arg5Type arg5,
437  typename Traits::Arg6Type arg6,
438  typename Traits::Arg7Type arg7)
439  {
441  callback_(arg1, arg2, arg3, arg4, arg5, arg6, arg7));
442  }
443  TCallback callback_;
444  };
445 
446  template <typename TDelegateInterface, typename TCallback>
447  struct InvokeHelper<TDelegateInterface, TCallback, 8> WrlSealed
448  : ::Microsoft::WRL::RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
449  {
451 
452  explicit InvokeHelper(TCallback callback) throw()
453  : callback_(callback)
454  {}
455 
456  STDMETHOD(Invoke)
457  (typename Traits::Arg1Type arg1,
458  typename Traits::Arg2Type arg2,
459  typename Traits::Arg3Type arg3,
460  typename Traits::Arg4Type arg4,
461  typename Traits::Arg5Type arg5,
462  typename Traits::Arg6Type arg6,
463  typename Traits::Arg7Type arg7,
464  typename Traits::Arg8Type arg8)
465  {
467  callback_(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8));
468  }
469  TCallback callback_;
470  };
471 
472  template <typename TDelegateInterface, typename TCallback>
473  struct InvokeHelper<TDelegateInterface, TCallback, 9> WrlSealed
474  : ::Microsoft::WRL::RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
475  {
477 
478  explicit InvokeHelper(TCallback callback) throw()
479  : callback_(callback)
480  {}
481 
482  STDMETHOD(Invoke)
483  (typename Traits::Arg1Type arg1,
484  typename Traits::Arg2Type arg2,
485  typename Traits::Arg3Type arg3,
486  typename Traits::Arg4Type arg4,
487  typename Traits::Arg5Type arg5,
488  typename Traits::Arg6Type arg6,
489  typename Traits::Arg7Type arg7,
490  typename Traits::Arg8Type arg8,
491  typename Traits::Arg9Type arg9)
492  {
494  callback_(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9));
495  }
496  TCallback callback_;
497  };
498 
499 #ifdef NUI_WRL_AGILE_INVOKE
500  template <typename TDelegateInterface, unsigned int argCount>
501  struct AgileInvokeHelper;
502 
503  template <typename TDelegateInterface>
504  struct AgileInvokeHelper<TDelegateInterface, 0>
506  Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
507  TDelegateInterface,
508  Microsoft::WRL::FtmBase>
509  {
511 
512  public:
513  HRESULT Initialize(_In_ TDelegateInterface* delegateInterface)
514  {
515  return Microsoft::WRL::AsAgile(delegateInterface, &_agileptr);
516  }
517 
518  virtual HRESULT STDMETHODCALLTYPE Invoke()
519  {
520  ComPtr<TDelegateInterface> localDelegate;
521 
522  HRESULT hr = _agileptr.CopyTo(localDelegate.GetAddressOf());
523  if (SUCCEEDED(hr))
524  {
525  hr = localDelegate->Invoke();
526  }
527  return hr;
528  }
529 
530  private:
531  AgileRef _agileptr;
532  };
533 
534  template <typename TDelegateInterface>
535  struct AgileInvokeHelper<TDelegateInterface, 1>
537  Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
538  TDelegateInterface,
539  Microsoft::WRL::FtmBase>
540  {
542 
543  public:
544  HRESULT Initialize(_In_ TDelegateInterface* delegateInterface)
545  {
546  return Microsoft::WRL::AsAgile(delegateInterface, &_agileptr);
547  }
548 
549  virtual HRESULT STDMETHODCALLTYPE Invoke(typename Traits::Arg1Type arg1)
550  {
551  ComPtr<TDelegateInterface> localDelegate;
552 
553  HRESULT hr = _agileptr.CopyTo(localDelegate.GetAddressOf());
554  if (SUCCEEDED(hr))
555  {
556  hr = localDelegate->Invoke(arg1);
557  }
558  return hr;
559  }
560 
561  private:
562  AgileRef _agileptr;
563  };
564 
565  template <typename TDelegateInterface>
566  struct AgileInvokeHelper<TDelegateInterface, 2>
568  Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
569  TDelegateInterface,
570  Microsoft::WRL::FtmBase>
571  {
573 
574  public:
575  HRESULT Initialize(_In_ TDelegateInterface* delegateInterface)
576  {
577  return Microsoft::WRL::AsAgile(delegateInterface, &_agileptr);
578  }
579 
580  virtual HRESULT STDMETHODCALLTYPE Invoke(typename Traits::Arg1Type arg1, typename Traits::Arg2Type arg2)
581  {
582  ComPtr<TDelegateInterface> localDelegate;
583 
584  HRESULT hr = _agileptr.CopyTo(localDelegate.GetAddressOf());
585  if (SUCCEEDED(hr))
586  {
587  hr = localDelegate->Invoke(arg1, arg2);
588  }
589  return hr;
590  }
591 
592  private:
593  AgileRef _agileptr;
594  };
595 
596  template <typename TDelegateInterface>
597  struct AgileInvokeHelper<TDelegateInterface, 3>
599  Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
600  TDelegateInterface,
601  Microsoft::WRL::FtmBase>
602  {
604 
605  public:
606  HRESULT Initialize(_In_ TDelegateInterface* delegateInterface)
607  {
608  return Microsoft::WRL::AsAgile(delegateInterface, &_agileptr);
609  }
610 
611  virtual HRESULT STDMETHODCALLTYPE
612  Invoke(typename Traits::Arg1Type arg1, typename Traits::Arg2Type arg2, typename Traits::Arg3Type arg3)
613  {
614  ComPtr<TDelegateInterface> localDelegate;
615 
616  HRESULT hr = _agileptr.CopyTo(localDelegate.GetAddressOf());
617  if (SUCCEEDED(hr))
618  {
619  hr = localDelegate->Invoke(arg1, arg2, arg3);
620  }
621  return hr;
622  }
623 
624  private:
625  AgileRef _agileptr;
626  };
627 
628  template <typename TDelegateInterface>
629  HRESULT
630  CreateAgileHelper(_In_ TDelegateInterface* delegateInterface, _COM_Outptr_ TDelegateInterface** wrapper)
631  {
632  *wrapper = nullptr;
633  ComPtr<AgileInvokeHelper<
634  TDelegateInterface,
636  invokeHelper;
637 
638  static_assert(
639  __is_base_of(IUnknown, TDelegateInterface) && !__is_base_of(IInspectable, TDelegateInterface),
640  "Delegates objects must be 'IUnknown' base and not 'IInspectable'");
641 
642  invokeHelper = Make<AgileInvokeHelper<
643  TDelegateInterface,
645  HRESULT hr = invokeHelper ? S_OK : E_OUTOFMEMORY;
646  if (SUCCEEDED(hr))
647  {
648  hr = invokeHelper->Initialize(delegateInterface);
649  if (SUCCEEDED(hr))
650  {
651  hr = invokeHelper.CopyTo(wrapper);
652  }
653  }
654  return hr;
655  }
656 
657 #endif // NUI_WRL_AGILE_INVOKE
658 
659  } // namespace Details
660 
661  // Implementation of Callback helper that wire delegate interfaces
662  // and provide object implementation for Invoke method
663  // Specialization for lambda, function pointer and functor
664  template <typename TDelegateInterface, typename TCallback>
666  {
667  static_assert(
668  __is_base_of(IUnknown, TDelegateInterface) && !__is_base_of(IInspectable, TDelegateInterface),
669  "Delegates objects must be 'IUnknown' base and not 'IInspectable'");
670 
671  return Make<
672  Details::
673  InvokeHelper<TDelegateInterface, TCallback, Details::ArgTraitsHelper<TDelegateInterface>::args>>(
674  callback);
675  }
676 
677  // Specialization for pointer to the method
678  template <typename TDelegateInterface, typename TCallbackObject>
679  ComPtr<typename Details::ArgTraitsHelper<TDelegateInterface>::Interface>
680  Callback(_In_ TCallbackObject* object, _In_ HRESULT (TCallbackObject::*method)()) throw()
681  {
682  static_assert(
683  __is_base_of(IUnknown, TDelegateInterface) && !__is_base_of(IInspectable, TDelegateInterface),
684  "Delegates objects must be 'IUnknown' base and not 'IInspectable'");
685  static_assert(
687  "Number of arguments on object method doesn't match number of arguments on Delegate::Invoke");
688 
689  struct ComObject WrlSealed : RuntimeClass<RuntimeClassFlags<ClassicCom>, TDelegateInterface>
690  {
691  ComObject(TCallbackObject* object, HRESULT (TCallbackObject::*method)()) throw()
692  : object_(object)
693  , method_(method)
694  {}
695 
696  STDMETHOD(Invoke)()
697  {
698  return (object_->*method_)();
699  }
700 
701  TCallbackObject* object_;
702  HRESULT (TCallbackObject::*method_)();
703  };
704 
705  return Make<ComObject>(object, method);
706  }
707 
708  template <typename TDelegateInterface, typename TCallbackObject, typename TArg1>
709  ComPtr<typename Details::ArgTraitsHelper<TDelegateInterface>::Interface>
710  Callback(_In_ TCallbackObject* object, _In_ HRESULT (TCallbackObject::*method)(TArg1)) throw()
711  {
712  static_assert(
713  __is_base_of(IUnknown, TDelegateInterface) && !__is_base_of(IInspectable, TDelegateInterface),
714  "Delegates objects must be 'IUnknown' base and not 'IInspectable'");
715  static_assert(
717  "Number of arguments on object method doesn't match number of arguments on Delegate::Invoke");
718  static_assert(
720  "Argument 1 from object method doesn't match Invoke argument 1");
721 
722  struct ComObject WrlSealed : RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
723  {
724  ComObject(TCallbackObject* object, HRESULT (TCallbackObject::*method)(TArg1)) throw()
725  : object_(object)
726  , method_(method)
727  {}
728 
729  STDMETHOD(Invoke)(TArg1 arg1)
730  {
731  return (object_->*method_)(arg1);
732  }
733 
734  TCallbackObject* object_;
735  HRESULT (TCallbackObject::*method_)(TArg1);
736  };
737 
738  return Make<ComObject>(object, method);
739  }
740 
741  template <typename TDelegateInterface, typename TCallbackObject, typename TArg1, typename TArg2>
742  ComPtr<typename Details::ArgTraitsHelper<TDelegateInterface>::Interface>
743  Callback(_In_ TCallbackObject* object, _In_ HRESULT (TCallbackObject::*method)(TArg1, TArg2)) throw()
744  {
745  static_assert(
746  __is_base_of(IUnknown, TDelegateInterface) && !__is_base_of(IInspectable, TDelegateInterface),
747  "Delegates objects must be 'IUnknown' base and not 'IInspectable'");
748  static_assert(
750  "Number of arguments on object method doesn't match number of arguments on Delegate::Invoke");
751  static_assert(
753  "Argument 1 from object method doesn't match Invoke argument 1");
754  static_assert(
756  "Argument 2 from object method doesn't match Invoke argument 2");
757 
758  struct ComObject WrlSealed : RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
759  {
760  ComObject(TCallbackObject* object, HRESULT (TCallbackObject::*method)(TArg1, TArg2)) throw()
761  : object_(object)
762  , method_(method)
763  {}
764 
765  STDMETHOD(Invoke)(TArg1 arg1, TArg2 arg2)
766  {
767  return (object_->*method_)(arg1, arg2);
768  }
769 
770  TCallbackObject* object_;
771  HRESULT (TCallbackObject::*method_)(TArg1, TArg2);
772  };
773 
774  return Make<ComObject>(object, method);
775  }
776 
777  template <typename TDelegateInterface, typename TCallbackObject, typename TArg1, typename TArg2, typename TArg3>
778  ComPtr<typename Details::ArgTraitsHelper<TDelegateInterface>::Interface>
779  Callback(_In_ TCallbackObject* object, _In_ HRESULT (TCallbackObject::*method)(TArg1, TArg2, TArg3)) throw()
780  {
781  static_assert(
782  __is_base_of(IUnknown, TDelegateInterface) && !__is_base_of(IInspectable, TDelegateInterface),
783  "Delegates objects must be 'IUnknown' base and not 'IInspectable'");
784  static_assert(
786  "Number of arguments on object method doesn't match number of arguments on Delegate::Invoke");
787  static_assert(
789  "Argument 1 from object method doesn't match Invoke argument 1");
790  static_assert(
792  "Argument 2 from object method doesn't match Invoke argument 2");
793  static_assert(
795  "Argument 3 from object method doesn't match Invoke argument 3");
796 
797  struct ComObject WrlSealed : RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
798  {
799  ComObject(TCallbackObject* object, HRESULT (TCallbackObject::*method)(TArg1, TArg2, TArg3)) throw()
800  : object_(object)
801  , method_(method)
802  {}
803 
804  STDMETHOD(Invoke)(TArg1 arg1, TArg2 arg2, TArg3 arg3)
805  {
806  return (object_->*method_)(arg1, arg2, arg3);
807  }
808 
809  TCallbackObject* object_;
810  HRESULT (TCallbackObject::*method_)(TArg1, TArg2, TArg3);
811  };
812 
813  return Make<ComObject>(object, method);
814  }
815 
816  template <
817  typename TDelegateInterface,
818  typename TCallbackObject,
819  typename TArg1,
820  typename TArg2,
821  typename TArg3,
822  typename TArg4>
824  _In_ TCallbackObject* object,
825  _In_ HRESULT (TCallbackObject::*method)(TArg1, TArg2, TArg3, TArg4)) throw()
826  {
827  static_assert(
828  __is_base_of(IUnknown, TDelegateInterface) && !__is_base_of(IInspectable, TDelegateInterface),
829  "Delegates objects must be 'IUnknown' base and not 'IInspectable'");
830  static_assert(
832  "Number of arguments on object method doesn't match number of arguments on Delegate::Invoke");
833  static_assert(
835  "Argument 1 from object method doesn't match Invoke argument 1");
836  static_assert(
838  "Argument 2 from object method doesn't match Invoke argument 2");
839  static_assert(
841  "Argument 3 from object method doesn't match Invoke argument 3");
842  static_assert(
844  "Argument 4 from object method doesn't match Invoke argument 4");
845 
846  struct ComObject WrlSealed : RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
847  {
848  ComObject(
849  TCallbackObject* object,
850  HRESULT (TCallbackObject::*method)(TArg1, TArg2, TArg3, TArg4)) throw()
851  : object_(object)
852  , method_(method)
853  {}
854 
855  STDMETHOD(Invoke)(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
856  {
857  return (object_->*method_)(arg1, arg2, arg3, arg4);
858  }
859 
860  TCallbackObject* object_;
861  HRESULT (TCallbackObject::*method_)(TArg1, TArg2, TArg3, TArg4);
862  };
863 
864  return Make<ComObject>(object, method);
865  }
866 
867  template <
868  typename TDelegateInterface,
869  typename TCallbackObject,
870  typename TArg1,
871  typename TArg2,
872  typename TArg3,
873  typename TArg4,
874  typename TArg5>
876  _In_ TCallbackObject* object,
877  _In_ HRESULT (TCallbackObject::*method)(TArg1, TArg2, TArg3, TArg4, TArg5)) throw()
878  {
879  static_assert(
880  __is_base_of(IUnknown, TDelegateInterface) && !__is_base_of(IInspectable, TDelegateInterface),
881  "Delegates objects must be 'IUnknown' base and not 'IInspectable'");
882  static_assert(
884  "Number of arguments on object method doesn't match number of arguments on Delegate::Invoke");
885  static_assert(
887  "Argument 1 from object method doesn't match Invoke argument 1");
888  static_assert(
890  "Argument 2 from object method doesn't match Invoke argument 2");
891  static_assert(
893  "Argument 3 from object method doesn't match Invoke argument 3");
894  static_assert(
896  "Argument 4 from object method doesn't match Invoke argument 4");
897  static_assert(
899  "Argument 5 from object method doesn't match Invoke argument 5");
900 
901  struct ComObject WrlSealed : RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
902  {
903  ComObject(
904  TCallbackObject* object,
905  HRESULT (TCallbackObject::*method)(TArg1, TArg2, TArg3, TArg4, TArg5)) throw()
906  : object_(object)
907  , method_(method)
908  {}
909 
910  STDMETHOD(Invoke)(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
911  {
912  return (object_->*method_)(arg1, arg2, arg3, arg4, arg5);
913  }
914 
915  TCallbackObject* object_;
916  HRESULT (TCallbackObject::*method_)(TArg1, TArg2, TArg3, TArg4, TArg5);
917  };
918 
919  return Make<ComObject>(object, method);
920  }
921 
922  template <
923  typename TDelegateInterface,
924  typename TCallbackObject,
925  typename TArg1,
926  typename TArg2,
927  typename TArg3,
928  typename TArg4,
929  typename TArg5,
930  typename TArg6>
932  _In_ TCallbackObject* object,
933  _In_ HRESULT (TCallbackObject::*method)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6)) throw()
934  {
935  static_assert(
936  __is_base_of(IUnknown, TDelegateInterface) && !__is_base_of(IInspectable, TDelegateInterface),
937  "Delegates objects must be 'IUnknown' base and not 'IInspectable'");
938  static_assert(
940  "Number of arguments on object method doesn't match number of arguments on Delegate::Invoke");
941  static_assert(
943  "Argument 1 from object method doesn't match Invoke argument 1");
944  static_assert(
946  "Argument 2 from object method doesn't match Invoke argument 2");
947  static_assert(
949  "Argument 3 from object method doesn't match Invoke argument 3");
950  static_assert(
952  "Argument 4 from object method doesn't match Invoke argument 4");
953  static_assert(
955  "Argument 5 from object method doesn't match Invoke argument 5");
956  static_assert(
958  "Argument 6 from object method doesn't match Invoke argument 6");
959 
960  struct ComObject WrlSealed : RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
961  {
962  ComObject(
963  TCallbackObject* object,
964  HRESULT (TCallbackObject::*method)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6)) throw()
965  : object_(object)
966  , method_(method)
967  {}
968 
969  STDMETHOD(Invoke)(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
970  {
971  return (object_->*method_)(arg1, arg2, arg3, arg4, arg5, arg6);
972  }
973 
974  TCallbackObject* object_;
975  HRESULT (TCallbackObject::*method_)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6);
976  };
977 
978  return Make<ComObject>(object, method);
979  }
980 
981  template <
982  typename TDelegateInterface,
983  typename TCallbackObject,
984  typename TArg1,
985  typename TArg2,
986  typename TArg3,
987  typename TArg4,
988  typename TArg5,
989  typename TArg6,
990  typename TArg7>
992  _In_ TCallbackObject* object,
993  _In_ HRESULT (TCallbackObject::*method)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7)) throw()
994  {
995  static_assert(
996  __is_base_of(IUnknown, TDelegateInterface) && !__is_base_of(IInspectable, TDelegateInterface),
997  "Delegates objects must be 'IUnknown' base and not 'IInspectable'");
998  static_assert(
1000  "Number of arguments on object method doesn't match number of arguments on Delegate::Invoke");
1001  static_assert(
1003  "Argument 1 from object method doesn't match Invoke argument 1");
1004  static_assert(
1006  "Argument 2 from object method doesn't match Invoke argument 2");
1007  static_assert(
1009  "Argument 3 from object method doesn't match Invoke argument 3");
1010  static_assert(
1012  "Argument 4 from object method doesn't match Invoke argument 4");
1013  static_assert(
1015  "Argument 5 from object method doesn't match Invoke argument 5");
1016  static_assert(
1018  "Argument 6 from object method doesn't match Invoke argument 6");
1019  static_assert(
1021  "Argument 7 from object method doesn't match Invoke argument 7");
1022 
1023  struct ComObject WrlSealed : RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
1024  {
1025  ComObject(
1026  TCallbackObject* object,
1027  HRESULT (TCallbackObject::*method)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7)) throw()
1028  : object_(object)
1029  , method_(method)
1030  {}
1031 
1032  STDMETHOD(Invoke)(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7)
1033  {
1034  return (object_->*method_)(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
1035  }
1036 
1037  TCallbackObject* object_;
1038  HRESULT (TCallbackObject::*method_)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7);
1039  };
1040 
1041  return Make<ComObject>(object, method);
1042  }
1043 
1044  template <
1045  typename TDelegateInterface,
1046  typename TCallbackObject,
1047  typename TArg1,
1048  typename TArg2,
1049  typename TArg3,
1050  typename TArg4,
1051  typename TArg5,
1052  typename TArg6,
1053  typename TArg7,
1054  typename TArg8>
1056  _In_ TCallbackObject* object,
1057  _In_ HRESULT (TCallbackObject::*method)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8)) throw()
1058  {
1059  static_assert(
1060  __is_base_of(IUnknown, TDelegateInterface) && !__is_base_of(IInspectable, TDelegateInterface),
1061  "Delegates objects must be 'IUnknown' base and not 'IInspectable'");
1062  static_assert(
1064  "Number of arguments on object method doesn't match number of arguments on Delegate::Invoke");
1065  static_assert(
1067  "Argument 1 from object method doesn't match Invoke argument 1");
1068  static_assert(
1070  "Argument 2 from object method doesn't match Invoke argument 2");
1071  static_assert(
1073  "Argument 3 from object method doesn't match Invoke argument 3");
1074  static_assert(
1076  "Argument 4 from object method doesn't match Invoke argument 4");
1077  static_assert(
1079  "Argument 5 from object method doesn't match Invoke argument 5");
1080  static_assert(
1082  "Argument 6 from object method doesn't match Invoke argument 6");
1083  static_assert(
1085  "Argument 7 from object method doesn't match Invoke argument 7");
1086  static_assert(
1088  "Argument 8 from object method doesn't match Invoke argument 8");
1089 
1090  struct ComObject WrlSealed : RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
1091  {
1092  ComObject(
1093  TCallbackObject* object,
1094  HRESULT (TCallbackObject::*method)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8)) throw()
1095  : object_(object)
1096  , method_(method)
1097  {}
1098 
1099  STDMETHOD(Invoke)
1100  (TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8)
1101  {
1102  return (object_->*method_)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
1103  }
1104 
1105  TCallbackObject* object_;
1106  HRESULT (TCallbackObject::*method_)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8);
1107  };
1108 
1109  return Make<ComObject>(object, method);
1110  }
1111 
1112  template <
1113  typename TDelegateInterface,
1114  typename TCallbackObject,
1115  typename TArg1,
1116  typename TArg2,
1117  typename TArg3,
1118  typename TArg4,
1119  typename TArg5,
1120  typename TArg6,
1121  typename TArg7,
1122  typename TArg8,
1123  typename TArg9>
1125  _In_ TCallbackObject* object,
1126  _In_ HRESULT (
1127  TCallbackObject::*method)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9)) throw()
1128  {
1129  static_assert(
1130  __is_base_of(IUnknown, TDelegateInterface) && !__is_base_of(IInspectable, TDelegateInterface),
1131  "Delegates objects must be 'IUnknown' base and not 'IInspectable'");
1132  static_assert(
1134  "Number of arguments on object method doesn't match number of arguments on Delegate::Invoke");
1135  static_assert(
1137  "Argument 1 from object method doesn't match Invoke argument 1");
1138  static_assert(
1140  "Argument 2 from object method doesn't match Invoke argument 2");
1141  static_assert(
1143  "Argument 3 from object method doesn't match Invoke argument 3");
1144  static_assert(
1146  "Argument 4 from object method doesn't match Invoke argument 4");
1147  static_assert(
1149  "Argument 5 from object method doesn't match Invoke argument 5");
1150  static_assert(
1152  "Argument 6 from object method doesn't match Invoke argument 6");
1153  static_assert(
1155  "Argument 7 from object method doesn't match Invoke argument 7");
1156  static_assert(
1158  "Argument 8 from object method doesn't match Invoke argument 8");
1159  static_assert(
1161  "Argument 9 from object method doesn't match Invoke argument 9");
1162 
1163  struct ComObject WrlSealed : RuntimeClass<RuntimeClassFlags<Delegate>, TDelegateInterface>
1164  {
1165  ComObject(
1166  TCallbackObject* object,
1167  HRESULT (TCallbackObject::*
1168  method)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9)) throw()
1169  : object_(object)
1170  , method_(method)
1171  {}
1172 
1173  STDMETHOD(Invoke)
1174  (TArg1 arg1,
1175  TArg2 arg2,
1176  TArg3 arg3,
1177  TArg4 arg4,
1178  TArg5 arg5,
1179  TArg6 arg6,
1180  TArg7 arg7,
1181  TArg8 arg8,
1182  TArg9 arg9)
1183  {
1184  return (object_->*method_)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
1185  }
1186 
1187  TCallbackObject* object_;
1188  HRESULT (TCallbackObject::*method_)(TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9);
1189  };
1190 
1191  return Make<ComObject>(object, method);
1192  }
1193 
1194  namespace Details
1195  {
1196 
1197  // EventTargetArray is used to keep array of event targets. This array is fixed-length.
1198  // Every time element is added/removed from array EventSource allocate new array. This array
1199  // is optimize-for-invoke lock strategy in EventSource
1200  class EventTargetArray WrlSealed
1201  : public ::Microsoft::WRL::RuntimeClass<::Microsoft::WRL::RuntimeClassFlags<ClassicCom>, IUnknown>
1202  {
1203  public:
1205  : begin_(nullptr)
1206  , end_(nullptr)
1207  , bucketAssists_(nullptr)
1208  {}
1209 
1210  HRESULT RuntimeClassInitialize(size_t items) throw()
1211  {
1212  begin_ = new (std::nothrow) ComPtr<IUnknown>[items];
1213  bucketAssists_ = new (std::nothrow) void*[items];
1214  if (begin_ == nullptr || bucketAssists_ == nullptr)
1215  {
1216  // Don't check against nullptr because delete does it
1217  delete[] begin_;
1218  delete[] bucketAssists_;
1219 
1220  // Set member pointers to nullptr so destructor does not try to delete them again
1221  begin_ = nullptr;
1222  bucketAssists_ = nullptr;
1223 
1224  return E_OUTOFMEMORY;
1225  }
1226 
1227  end_ = begin_;
1228  return S_OK;
1229  }
1230 
1232  {
1233  // Don't check against nullptr because delete does it
1234  delete[] begin_;
1235  delete[] bucketAssists_;
1236  }
1237 
1239  {
1240  return begin_;
1241  }
1242 
1244  {
1245  return end_;
1246  }
1247 
1248  void AddTail(_In_ IUnknown* element) throw()
1249  {
1250  AddTail(element, nullptr);
1251  }
1252 
1253  void AddTail(_In_ IUnknown* element, void* bucketAssist) throw()
1254  {
1255  // We'll run over the end if you call AddTail too many times, but the alternate would be an extra
1256  // variable to keep track of the number of items allocated. This class is only privately used by
1257  // EventSourceBase.
1258  *end_ = element;
1259  *(bucketAssists_ + (end_ - begin_)) = bucketAssist;
1260  end_++;
1261  }
1262 
1263  size_t Length() throw()
1264  {
1265  return static_cast<size_t>(end_ - begin_);
1266  }
1267 
1269  {
1270  return bucketAssists_;
1271  }
1272 
1274  {
1275  return bucketAssists_ + (end_ - begin_);
1276  }
1277 
1278  private:
1279  ComPtr<IUnknown>* begin_;
1280  ComPtr<IUnknown>* end_;
1281  void** bucketAssists_;
1282  };
1283 
1284  } // namespace Details
1285 
1286  template <>
1288  {
1289  template <typename TInvokeMethod, typename TDelegateInterface>
1290  static HRESULT InvokeDelegates(
1291  TInvokeMethod invokeOne,
1292  Details::EventTargetArray* targetArray,
1293  EventSource<TDelegateInterface, InvokeModeOptions<FireAll>>* pEvent)
1294  {
1296  targets = targetArray;
1297 
1298  for (auto element = targets->Begin(); element != targets->End(); element++)
1299  {
1300  HRESULT hr = (invokeOne)(*element);
1301  if (FAILED(hr))
1302  {
1303  // ::RoTransformError(hr, S_OK, nullptr);
1304  // Remove event that is already disconnected
1305  if (hr == RPC_E_DISCONNECTED || hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE) ||
1306  hr == static_cast<HRESULT>(JSCRIPT_E_CANTEXECUTE))
1307  {
1308  EventRegistrationToken token;
1309  token.value = reinterpret_cast<__int64>(element->Get());
1310  pEvent->Remove(token);
1311  }
1312  }
1313  }
1314  return S_OK;
1315  }
1316  };
1317 
1318  template <>
1320  {
1321  template <typename TInvokeMethod, typename TDelegateInterface>
1322  static HRESULT InvokeDelegates(
1323  TInvokeMethod invokeOne,
1324  Details::EventTargetArray* targetArray,
1325  EventSource<TDelegateInterface, InvokeModeOptions<StopOnFirstError>>* pEvent)
1326  {
1327  HRESULT hr = S_OK;
1329  targets = targetArray;
1330 
1331  for (auto element = targets->Begin(); element != targets->End(); element++)
1332  {
1333  hr = (invokeOne)(*element);
1334  // Remove event that is already disconnected
1335  if (hr == RPC_E_DISCONNECTED || hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE) ||
1336  hr == static_cast<HRESULT>(JSCRIPT_E_CANTEXECUTE))
1337  {
1338  // if we get the above errors, treat it as success and unregister the delegate
1339  //::RoTransformError(hr, S_OK, nullptr);
1340  EventRegistrationToken token;
1341  token.value = reinterpret_cast<__int64>(element->Get());
1342  pEvent->Remove(token);
1343  hr = S_OK;
1344  }
1345  if (FAILED(hr))
1346  {
1347  // break out of the loop on the first unhandled error
1348  break;
1349  }
1350  }
1351  return hr;
1352  }
1353  };
1354 
1355 #if (defined(BUILD_WINDOWS) && (NTDDI_VERSION >= NTDDI_WINBLUE))
1356  template <
1357  typename TDelegateInterface,
1358  typename TEventSourceOptions = InvokeModeOptions<ReportUnhandledOnFirstErrorWithWin8Quirk>>
1359 #else
1360  template <typename TDelegateInterface, typename TEventSourceOptions = InvokeModeOptions<FireAll>>
1361 #endif // (defined(BUILD_WINDOWS) && (NTDDI_VERSION >= NTDDI_WINBLUE))
1363  {
1364  public:
1365  EventSource() throw()
1366  : targets_(nullptr)
1367  {}
1368 
1369  HRESULT Add(_In_opt_ TDelegateInterface* delegateInterface, _Out_ EventRegistrationToken* token) throw()
1370  {
1371  // Make sure that delegate interface pointer is not null
1372  if (delegateInterface == nullptr)
1373  {
1374  return E_INVALIDARG;
1375  }
1376 
1377  return AddInternal(
1378  delegateInterface, Microsoft::WRL::Details::GetDelegateBucketAssist(delegateInterface), token);
1379  }
1380 
1381  HRESULT Remove(EventRegistrationToken token) throw()
1382  {
1383  // Used for deleting the current array without holding the addRemoveLock.
1385  { // lock scope for addRemoveLock_
1386  // The addRemoveLock_ prevents multiple threads from doing simultaneous adds/removes.
1387  // An invoke may be occurring during an add or remove operation.
1389 
1390  if (targets_ == nullptr)
1391  {
1392  return S_OK; // List is currently empty - thus token wasn't found, just return
1393  }
1394 
1396  size_t availableSlots = targets_->Length() - 1;
1397  bool removed = false;
1398  // If one element in the array
1399  if (availableSlots == 0)
1400  {
1401  if (reinterpret_cast<__int64>(targets_->Begin()->Get()) == token.value)
1402  {
1403  removed = true;
1404  }
1405  }
1406  else
1407  {
1408  // Instantiate EventTargetArray
1409  HRESULT hr =
1410  MakeAndInitialize<Details::EventTargetArray>(pNewList.GetAddressOf(), availableSlots);
1411  if (FAILED(hr))
1412  {
1413  return hr;
1414  }
1415 
1416  void** bucketElement = targets_->Begin_BucketAssists();
1417 
1418  for (auto element = targets_->Begin(); element != targets_->End(); element++)
1419  {
1420  if (!removed && token.value == reinterpret_cast<__int64>(element->Get()))
1421  {
1422  removed = true;
1423  continue;
1424  }
1425 
1426  // The ComPtr<TDelegateInterface> contained in p is assigned to a
1427  // ComPtr<TDelegateInterface> of a new node in pNewList. The net result is
1428  // an addref on the interface.
1429  if (availableSlots == 0)
1430  {
1431  // We don't have any availableSlots left in the target array, hence every item was
1432  // copied from the source array. This means we didn't find the item in the list - just
1433  // return.
1435  !removed && "Attempt to remove token that was not added to this EventSource<>");
1436  break;
1437  }
1438 
1439  // Copy every registrant from old list except the item being removed
1440  // The ComPtr<TDelegateInterface> contained in p is assigned to a
1441  // ComPtr<TDelegateInterface> of a new node in pNewList. The net result is
1442  // an addref on the interface.
1443  pNewList->AddTail(element->Get(), *bucketElement);
1444  bucketElement++;
1445  availableSlots--;
1446  }
1447  }
1448 
1449  if (removed)
1450  {
1451  // lock scope for targetsPointerLock
1452  // The targetsPointerLock_ protects the exchanging of the new list (with the removal)
1453  // for the old list (which could be used currently for firing events)
1455 
1456  // We move targets_ to pTempList so that we can actually delete the list while
1457  // not holding any locks. The InvokeAll method may still have a reference to targets_ so
1458  // even when pTempList releases, this might not delete what was in targets_.
1459  pTempList = Details::Move(targets_);
1460 
1461  // We still have some items left inside pNewList, so move it to targets_.
1462  targets_ = Details::Move(pNewList);
1463 
1464  // If we don't have any items added, the Details::Move(targets_) above already set targets_ to
1465  // nullptr. The result is that now when pTempList destructs, it will cause what used to be
1466  // targets_ to be freed.
1467 
1468  } // end lock scope for targetsPointerLock
1469 
1470  } // end lock scope for addRemoveLock
1471 
1472  // Destroys pTempList here (this is the old targets_)
1473 
1474  return S_OK;
1475  }
1476 
1477  protected:
1478  HRESULT
1479  Add(_In_opt_ TDelegateInterface* delegateInterface,
1480  _In_opt_ void* bucketAssist,
1481  _Out_ EventRegistrationToken* token) throw()
1482  {
1483  // Make sure that delegate interface pointer is not null
1484  if (delegateInterface == nullptr)
1485  {
1486  return E_INVALIDARG;
1487  }
1488 
1489  return AddInternal(delegateInterface, bucketAssist, token);
1490  }
1491 
1492  private:
1493  HRESULT AddInternal(
1494  _In_ TDelegateInterface* delegateInterface,
1495  _In_opt_ void* bucketAssist,
1496  _Out_ EventRegistrationToken* token) throw()
1497  {
1498  // Clear token value
1499  token->value = 0;
1500 
1501  // This must be defined outside of the scope where the addRemoveLock is taken to ensure that it's
1502  // destructor is called after the lock is released
1504 
1505  { // lock scope for addRemoveLock
1506  // We are doing "copy to new list and add" so as not to disturb the list that may be
1507  // currently undergoing a walk and fire (invoke).
1508 
1509  // The addRemoveLock_ prevents multiple threads from doing simultaneous adds.
1510  // An invoke may be occurring during an add or remove operation.
1512 
1514 
1515  // Allocate event array
1516  HRESULT hr = MakeAndInitialize<Details::EventTargetArray>(
1517  pNewList.GetAddressOf(), targets_ == nullptr ? 1 : targets_->Length() + 1);
1518  // Make sure allocation succeeded
1519  if (FAILED(hr))
1520  {
1521  return hr;
1522  }
1523 
1524  // The list may not exist if nobody has registered
1525  if (targets_)
1526  {
1527  void** bucketElement = targets_->Begin_BucketAssists();
1528  for (auto element = targets_->Begin(); element != targets_->End(); element++)
1529  {
1530  // The ComPtr<TDelegateInterface> contained in the current targets_ node
1531  // is assigned to a ComPtr<TDelegateInterface> of a new node in pNewList
1532  // the net result is an addref on the interface.
1533 
1534  pNewList->AddTail(element->Get(), *bucketElement);
1535  bucketElement++;
1536  }
1537  }
1538 
1539  // Get unique token value
1540  token->value = reinterpret_cast<__int64>(delegateInterface);
1541 
1542  // AddTail operation will take a reference which will result in
1543  // this function adding one reference count on delegateInterface.
1544  pNewList->AddTail(delegateInterface, bucketAssist);
1545 
1546  {
1547  // lock scope for targetsPointerLock
1548  // The targetsPointerLock_ protects the exchanging of the new list (with the addition)
1549  // for the old list (which could be used currently for firing events)
1551 
1552  // We move targets_ to pTempList so that we can actually delete the list while
1553  // not holding any locks. The InvokeAll method may still have a reference to targets_ so
1554  // even when pTempList releases, this might not delete what was in targets_.
1555  pTempList = Details::Move(targets_);
1556 
1557  // We're done with pNewList, so just move it to targets_.
1558  targets_ = Details::Move(pNewList);
1559 
1560  } // end lock scope for targetsPointerLock
1561  } // end lock scope for addRemoveLock
1562 
1563  // Destroys pTempList here (this is the old targets_)
1564 
1565  return S_OK;
1566  }
1567 
1568  // TInvokeMethod is a functor that performs the appropriate invoke, depending on the
1569  // number of arguments specified.
1570  template <typename TInvokeMethod>
1571  _Check_return_ HRESULT DoInvoke(TInvokeMethod invokeOne) throw()
1572  {
1573  HRESULT hr = S_OK;
1574  // The targetsPointerLock_ protects the acquisition of an AddRef'd pointer to
1575  // "current list". An Add/Remove operation may occur during the
1576  // firing of events (but occurs on a copy of the list). i.e. both
1577  // InvokeAll/invoke and Add/Remove are readers of the "current list".
1578  // NOTE: EventSource<TDelegateInterface>::InvokeAll(...) must never take the addRemoveLock_.
1579  ComPtr<Details::EventTargetArray> targets;
1580 
1581  // Scoping for lock
1582  {
1584  targets = targets_;
1585  }
1586 
1587  // The list may not exist if nobody has registered
1588  if (targets)
1589  {
1590  hr = InvokeTraits<TEventSourceOptions::invokeMode>::InvokeDelegates(invokeOne, targets.Get(), this);
1591  }
1592  return hr;
1593  }
1594 
1595  public:
1596  _Check_return_ HRESULT InvokeAll() throw()
1597  {
1598  return DoInvoke([](ComPtr<IUnknown>& p) -> HRESULT {
1599  return static_cast<TDelegateInterface*>(p.Get())->Invoke();
1600  });
1601  }
1602 
1603  template <typename T0>
1604  _Check_return_ HRESULT InvokeAll(T0 arg0) throw()
1605  {
1606  return DoInvoke([arg0](ComPtr<IUnknown>& p) -> HRESULT {
1607  return static_cast<TDelegateInterface*>(p.Get())->Invoke(arg0);
1608  });
1609  }
1610 
1611  template <typename T0, typename T1>
1612  _Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1) throw()
1613  {
1614  return DoInvoke([arg0, arg1](ComPtr<IUnknown>& p) -> HRESULT {
1615  return static_cast<TDelegateInterface*>(p.Get())->Invoke(arg0, arg1);
1616  });
1617  }
1618 
1619  template <typename T0, typename T1, typename T2>
1620  _Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2) throw()
1621  {
1622  return DoInvoke([arg0, arg1, arg2](ComPtr<IUnknown>& p) -> HRESULT {
1623  return static_cast<TDelegateInterface*>(p.Get())->Invoke(arg0, arg1, arg2);
1624  });
1625  }
1626 
1627  template <typename T0, typename T1, typename T2, typename T3>
1628  _Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3) throw()
1629  {
1630  return DoInvoke([arg0, arg1, arg2, arg3](ComPtr<IUnknown>& p) -> HRESULT {
1631  return static_cast<TDelegateInterface*>(p.Get())->Invoke(arg0, arg1, arg2, arg3);
1632  });
1633  }
1634 
1635  template <typename T0, typename T1, typename T2, typename T3, typename T4>
1636  _Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) throw()
1637  {
1638  return DoInvoke([arg0, arg1, arg2, arg3, arg4](ComPtr<IUnknown>& p) -> HRESULT {
1639  return static_cast<TDelegateInterface*>(p.Get())->Invoke(arg0, arg1, arg2, arg3, arg4);
1640  });
1641  }
1642 
1643  template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
1644  _Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) throw()
1645  {
1646  return DoInvoke([arg0, arg1, arg2, arg3, arg4, arg5](ComPtr<IUnknown>& p) -> HRESULT {
1647  return static_cast<TDelegateInterface*>(p.Get())->Invoke(arg0, arg1, arg2, arg3, arg4, arg5);
1648  });
1649  }
1650 
1651  template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
1652  _Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) throw()
1653  {
1654  return DoInvoke([arg0, arg1, arg2, arg3, arg4, arg5, arg6](ComPtr<IUnknown>& p) -> HRESULT {
1655  return static_cast<TDelegateInterface*>(p.Get())->Invoke(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
1656  });
1657  }
1658 
1659  template <
1660  typename T0,
1661  typename T1,
1662  typename T2,
1663  typename T3,
1664  typename T4,
1665  typename T5,
1666  typename T6,
1667  typename T7>
1668  _Check_return_ HRESULT
1669  InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) throw()
1670  {
1671  return DoInvoke([arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7](ComPtr<IUnknown>& p) -> HRESULT {
1672  return static_cast<TDelegateInterface*>(p.Get())->Invoke(
1673  arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
1674  });
1675  }
1676 
1677  template <
1678  typename T0,
1679  typename T1,
1680  typename T2,
1681  typename T3,
1682  typename T4,
1683  typename T5,
1684  typename T6,
1685  typename T7,
1686  typename T8>
1687  _Check_return_ HRESULT
1688  InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) throw()
1689  {
1690  return DoInvoke([arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8](ComPtr<IUnknown>& p) -> HRESULT {
1691  return static_cast<TDelegateInterface*>(p.Get())->Invoke(
1692  arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
1693  });
1694  }
1695 
1696  template <
1697  typename T0,
1698  typename T1,
1699  typename T2,
1700  typename T3,
1701  typename T4,
1702  typename T5,
1703  typename T6,
1704  typename T7,
1705  typename T8,
1706  typename T9>
1707  _Check_return_ HRESULT
1708  InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) throw()
1709  {
1710  return DoInvoke(
1711  [arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9](ComPtr<IUnknown>& p) -> HRESULT {
1712  return static_cast<TDelegateInterface*>(p.Get())->Invoke(
1713  arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
1714  });
1715  }
1716 
1717  size_t GetSize() const throw()
1718  {
1719  return targets_ == nullptr ? 0 : targets_->Length();
1720  }
1721 
1722  protected:
1726  };
1727 
1728 #ifdef __windows2Efoundation_h__
1729 
1730  template <typename TEventArgsInterface, typename TEventArgsClass>
1731  class DeferrableEventArgs : public TEventArgsInterface
1732  {
1733  public:
1734  STDMETHOD(GetDeferral)(_COM_Outptr_ ::ABI::Windows::Foundation::IDeferral** result)
1735  {
1736  *result = nullptr;
1737  auto lockGuard = lock_.LockExclusive();
1738  if (raised_)
1739  {
1740  // Cannot ask for a deferral after the event handler returned.
1741  ::RoOriginateError(E_ILLEGAL_METHOD_CALL, nullptr);
1742  return E_ILLEGAL_METHOD_CALL;
1743  }
1744 
1746  HRESULT hr = GetActivationFactory(
1747  Wrappers::HStringReference(RuntimeClass_Windows_Foundation_Deferral).Get(), &factory);
1748  if (FAILED(hr))
1749  {
1750  return hr;
1751  }
1752 
1754  auto callback =
1755  Microsoft::WRL::Callback<::ABI::Windows::Foundation::IDeferralCompletedHandler>([lifetime]() {
1756  return lifetime->Complete();
1757  });
1758  if (callback == nullptr)
1759  {
1760  return E_OUTOFMEMORY;
1761  }
1762 
1764  hr = factory->Create(callback.Get(), &deferral);
1765  if (FAILED(hr))
1766  {
1767  return hr;
1768  }
1769 
1770  completionsRequired_++;
1771  return deferral.CopyTo(result);
1772  }
1773 
1774  // InvokeAllFinished() should be called after the event source calls InvokeAll. This will prevent further
1775  // deferrals from being taken, and cause the completion handler to execute if no deferrals were taken.
1776  void InvokeAllFinished()
1777  {
1778  bool invokeNeeded;
1779 
1780  // We need to hold a lock while modifying private state, but release it before invoking a completion
1781  // handler.
1782  {
1783  auto lockGuard = lock_.LockExclusive();
1784  raised_ = true;
1785  invokeNeeded = (completionsRequired_ == 0);
1786  }
1787 
1788  if (invokeNeeded)
1789  {
1790  static_cast<TEventArgsClass*>(this)->InvokeCompleteHandler();
1791  }
1792  }
1793 
1794  private:
1795  _Requires_lock_not_held_(lock_) HRESULT Complete()
1796  {
1797  bool invokeNeeded;
1798 
1799  // We need to hold a lock while modifying private state, but release it before invoking a completion
1800  // handler.
1801  {
1802  auto lockGuard = lock_.LockExclusive();
1803  if (completionsRequired_ == 0)
1804  {
1805  // This should never happen since Complete() should only be called by
1806  // Windows.Foundation.Deferral which will only invoke our completion handler once.
1807  ::RoOriginateError(E_ILLEGAL_METHOD_CALL, nullptr);
1808  return E_ILLEGAL_METHOD_CALL;
1809  }
1810  completionsRequired_--;
1811  invokeNeeded = (raised_ && (completionsRequired_ == 0));
1812  }
1813 
1814  if (invokeNeeded)
1815  {
1816  static_cast<TEventArgsClass*>(this)->InvokeCompleteHandler();
1817  }
1818 
1819  return S_OK;
1820  }
1821 
1822  Wrappers::SRWLock lock_;
1823  _Guarded_by_(lock_) bool raised_ = false;
1824  _Guarded_by_(lock_) long completionsRequired_ = 0;
1825  };
1826 
1827 #endif // __windows2Efoundation_h__
1828 
1829 #ifdef NUI_WRL_AGILE_INVOKE
1830 # if defined(BUILD_WINDOWS)
1831  template <
1832  typename TDelegateInterface,
1833  typename TEventSourceOptions =
1835 # else
1836  template <
1837  typename TDelegateInterface,
1838  typename TEventSourceOptions = Microsoft::WRL::InvokeModeOptions<FireAll>>
1839 # endif // defined(BUILD_WINDOWS)
1840  class AgileEventSource : public Microsoft::WRL::EventSource<TDelegateInterface, TEventSourceOptions>
1841  {
1842  // defining type 'Super' for other compilers since '__super' is a VC++-specific language extension
1844 
1845  public:
1846  HRESULT Add(_In_ TDelegateInterface* delegateInterface, _Out_ EventRegistrationToken* token)
1847  {
1848  if (delegateInterface == nullptr)
1849  {
1850  // We do not want to store a null interface pointer in the event list. This makes the behavior of
1851  // AgileEvent similar to the behavior of Event.
1852  return E_INVALIDARG;
1853  }
1854 
1856  HRESULT hr = Details::CreateAgileHelper<TDelegateInterface>(delegateInterface, &agileCallback);
1857  if (SUCCEEDED(hr))
1858  {
1859  hr = Super::Add(
1860  agileCallback.Get(),
1862  token);
1863  }
1864  return hr;
1865  }
1866  };
1867 #endif // NUI_WRL_AGILE_INVOKE
1868 
1869  }
1870 } // namespace ::Microsoft::WRL
1871 
1872 // Restore packing
1873 #pragma pack(pop)
1874 
1875 #ifdef BUILD_WINDOWS
1876 # include <wrl\internalevent.h>
1877 #endif
Definition: client.h:100
HRESULT CopyTo(InterfaceType **ptr) const
Definition: client.h:281
InterfaceType *const * GetAddressOf() const
Definition: client.h:243
InterfaceType * Get() const
Definition: client.h:223
Definition: event.h:1363
_Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3)
Definition: event.h:1628
HRESULT Remove(EventRegistrationToken token)
Definition: event.h:1381
HRESULT Add(_In_opt_ TDelegateInterface *delegateInterface, _In_opt_ void *bucketAssist, _Out_ EventRegistrationToken *token)
Definition: event.h:1479
_Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
Definition: event.h:1636
_Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
Definition: event.h:1669
Wrappers::SRWLock addRemoveLock_
Definition: event.h:1725
Wrappers::SRWLock targetsPointerLock_
Definition: event.h:1724
size_t GetSize() const
Definition: event.h:1717
_Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1)
Definition: event.h:1612
EventSource()
Definition: event.h:1365
_Check_return_ HRESULT InvokeAll(T0 arg0)
Definition: event.h:1604
_Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
Definition: event.h:1644
_Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2)
Definition: event.h:1620
_Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9)
Definition: event.h:1708
ComPtr< Details::EventTargetArray > targets_
Definition: event.h:1723
HRESULT Add(_In_opt_ TDelegateInterface *delegateInterface, _Out_ EventRegistrationToken *token)
Definition: event.h:1369
_Check_return_ HRESULT InvokeAll()
Definition: event.h:1596
_Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
Definition: event.h:1688
_Check_return_ HRESULT InvokeAll(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
Definition: event.h:1652
Definition: implements.h:2422
Definition: corewrappers.h:975
Definition: corewrappers.h:708
Details::SyncLockExclusive SyncLockExclusive
Definition: corewrappers.h:710
_Acquires_exclusive_lock_ return _Post_same_lock_ return SyncLockExclusive LockExclusive()
Definition: corewrappers.h:722
#define WrlSealed
Definition: event.h:18
#define __WRL_ASSERT__(cond)
Definition: internal.h:13
Definition: client.h:369
ComPtr< T > Make(TArgs &&... args)
Definition: implements.h:2785
void * GetDelegateBucketAssist(TDelegateInterface *pDelegate)
Definition: event.h:85
RemoveReference< T >::Type && Move(_Inout_ T &&arg)
Definition: internal.h:95
__declspec(selectany) const DelegateCheckMode DefaultDelegateCheckMode
ComPtr< typename Details::ArgTraitsHelper< TDelegateInterface >::Interface > Callback(TCallback callback)
Definition: event.h:665
InvokeMode
Definition: event.h:63
@ FireAll
Definition: event.h:65
@ StopOnFirstError
Definition: event.h:64
DelegateCheckMode
Definition: event.h:44
@ NoCheck
Definition: event.h:45
This file has no copyright assigned and is placed in the Public Domain.
Definition: client.h:26
HRESULT GetActivationFactory(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef< T > factory)
Definition: client.h:361
Definition: client.h:351
constexpr auto JSCRIPT_E_CANTEXECUTE
Definition: patch.h:4
Definition: eventtoken.h:44
__int64 value
Definition: eventtoken.h:45
static HRESULT CheckReturn(HRESULT hr)
Definition: event.h:55
Definition: event.h:50
ArgTraits< methodType > Traits
Definition: event.h:265
decltype(&TDelegateInterface::Invoke) typedef methodType
Definition: event.h:264
static const int args
Definition: event.h:99
Definition: internal.h:66
Definition: event.h:289
EventTargetArray()
Definition: event.h:1204
void AddTail(_In_ IUnknown *element)
Definition: event.h:1248
void ** Begin_BucketAssists()
Definition: event.h:1268
Traits::Arg1Type Traits::Arg2Type Traits::Arg3Type Traits::Arg4Type Traits::Arg5Type Traits::Arg6Type arg6
Definition: event.h:414
Traits::Arg1Type Traits::Arg2Type Traits::Arg3Type Traits::Arg4Type Traits::Arg5Type Traits::Arg6Type Traits::Arg7Type arg7
Definition: event.h:439
HRESULT RuntimeClassInitialize(size_t items)
Definition: event.h:1210
ArgTraitsHelper< TDelegateInterface >::Traits Traits
Definition: event.h:305
void AddTail(_In_ IUnknown *element, void *bucketAssist)
Definition: event.h:1253
void ** End_BucketAssists()
Definition: event.h:1273
~EventTargetArray()
Definition: event.h:1231
Traits::Arg1Type arg1
Definition: event.h:346
InvokeHelper(TCallback callback)
Definition: event.h:290
Traits::Arg1Type Traits::Arg2Type Traits::Arg3Type Traits::Arg4Type Traits::Arg5Type Traits::Arg6Type Traits::Arg7Type Traits::Arg8Type arg8
Definition: event.h:465
TCallback callback_
Definition: event.h:298
size_t Length()
Definition: event.h:1263
ComPtr< IUnknown > * End()
Definition: event.h:1243
Traits::Arg1Type Traits::Arg2Type Traits::Arg3Type Traits::Arg4Type Traits::Arg5Type arg5
Definition: event.h:390
Traits::Arg1Type Traits::Arg2Type Traits::Arg3Type Traits::Arg4Type Traits::Arg5Type Traits::Arg6Type Traits::Arg7Type Traits::Arg8Type Traits::Arg9Type arg9
Definition: event.h:492
ComPtr< IUnknown > * Begin()
Definition: event.h:1238
Traits::Arg1Type Traits::Arg2Type Traits::Arg3Type Traits::Arg4Type arg4
Definition: event.h:368
Definition: event.h:71
static const InvokeMode invokeMode
Definition: event.h:72
static HRESULT InvokeDelegates(TInvokeMethod invokeOne, Details::EventTargetArray *targetArray, EventSource< TDelegateInterface, InvokeModeOptions< FireAll >> *pEvent)
Definition: event.h:1290
static HRESULT InvokeDelegates(TInvokeMethod invokeOne, Details::EventTargetArray *targetArray, EventSource< TDelegateInterface, InvokeModeOptions< StopOnFirstError >> *pEvent)
Definition: event.h:1322
Definition: event.h:77