event_emitter.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Copyright (c) 2014 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #ifndef ATOM_BROWSER_API_EVENT_EMITTER_H_
  5. #define ATOM_BROWSER_API_EVENT_EMITTER_H_
  6. #include <vector>
  7. #include "atom/common/api/event_emitter_caller.h"
  8. #include "content/public/browser/browser_thread.h"
  9. #include "native_mate/wrappable.h"
  10. namespace content {
  11. class RenderFrameHost;
  12. }
  13. namespace IPC {
  14. class Message;
  15. }
  16. namespace mate {
  17. namespace internal {
  18. v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
  19. v8::Local<v8::Object> object,
  20. content::RenderFrameHost* sender,
  21. IPC::Message* message);
  22. v8::Local<v8::Object> CreateCustomEvent(v8::Isolate* isolate,
  23. v8::Local<v8::Object> object,
  24. v8::Local<v8::Object> event);
  25. v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags);
  26. } // namespace internal
  27. // Provide helperers to emit event in JavaScript.
  28. template <typename T>
  29. class EventEmitter : public Wrappable<T> {
  30. public:
  31. typedef std::vector<v8::Local<v8::Value>> ValueArray;
  32. // Make the convinient methods visible:
  33. // https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
  34. v8::Isolate* isolate() const { return Wrappable<T>::isolate(); }
  35. v8::Local<v8::Object> GetWrapper() const {
  36. return Wrappable<T>::GetWrapper();
  37. }
  38. // this.emit(name, event, args...);
  39. template <typename... Args>
  40. bool EmitCustomEvent(const base::StringPiece& name,
  41. v8::Local<v8::Object> event,
  42. const Args&... args) {
  43. return EmitWithEvent(
  44. name, internal::CreateCustomEvent(isolate(), GetWrapper(), event),
  45. args...);
  46. }
  47. // this.emit(name, new Event(flags), args...);
  48. template <typename... Args>
  49. bool EmitWithFlags(const base::StringPiece& name,
  50. int flags,
  51. const Args&... args) {
  52. return EmitCustomEvent(
  53. name, internal::CreateEventFromFlags(isolate(), flags), args...);
  54. }
  55. // this.emit(name, new Event(), args...);
  56. template <typename... Args>
  57. bool Emit(const base::StringPiece& name, const Args&... args) {
  58. return EmitWithSender(name, nullptr, nullptr, args...);
  59. }
  60. // this.emit(name, new Event(sender, message), args...);
  61. template <typename... Args>
  62. bool EmitWithSender(const base::StringPiece& name,
  63. content::RenderFrameHost* sender,
  64. IPC::Message* message,
  65. const Args&... args) {
  66. v8::Locker locker(isolate());
  67. v8::HandleScope handle_scope(isolate());
  68. v8::Local<v8::Object> wrapper = GetWrapper();
  69. if (wrapper.IsEmpty()) {
  70. return false;
  71. }
  72. v8::Local<v8::Object> event =
  73. internal::CreateJSEvent(isolate(), wrapper, sender, message);
  74. return EmitWithEvent(name, event, args...);
  75. }
  76. protected:
  77. EventEmitter() {}
  78. private:
  79. // this.emit(name, event, args...);
  80. template <typename... Args>
  81. bool EmitWithEvent(const base::StringPiece& name,
  82. v8::Local<v8::Object> event,
  83. const Args&... args) {
  84. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  85. v8::Locker locker(isolate());
  86. v8::HandleScope handle_scope(isolate());
  87. EmitEvent(isolate(), GetWrapper(), name, event, args...);
  88. return event->Get(StringToV8(isolate(), "defaultPrevented"))
  89. ->BooleanValue(isolate()->GetCurrentContext())
  90. .ToChecked();
  91. }
  92. DISALLOW_COPY_AND_ASSIGN(EventEmitter);
  93. };
  94. } // namespace mate
  95. #endif // ATOM_BROWSER_API_EVENT_EMITTER_H_