event_emitter.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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 "native_mate/wrappable.h"
  9. namespace content {
  10. class RenderFrameHost;
  11. }
  12. namespace IPC {
  13. class Message;
  14. }
  15. namespace mate {
  16. namespace internal {
  17. v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
  18. v8::Local<v8::Object> object,
  19. content::RenderFrameHost* sender,
  20. IPC::Message* message);
  21. v8::Local<v8::Object> CreateCustomEvent(v8::Isolate* isolate,
  22. v8::Local<v8::Object> object,
  23. v8::Local<v8::Object> event);
  24. v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags);
  25. } // namespace internal
  26. // Provide helperers to emit event in JavaScript.
  27. template <typename T>
  28. class EventEmitter : public Wrappable<T> {
  29. public:
  30. typedef std::vector<v8::Local<v8::Value>> ValueArray;
  31. // Make the convinient methods visible:
  32. // https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
  33. v8::Isolate* isolate() const { return Wrappable<T>::isolate(); }
  34. v8::Local<v8::Object> GetWrapper() const {
  35. return Wrappable<T>::GetWrapper();
  36. }
  37. // this.emit(name, event, args...);
  38. template <typename... Args>
  39. bool EmitCustomEvent(const base::StringPiece& name,
  40. v8::Local<v8::Object> event,
  41. const Args&... args) {
  42. return EmitWithEvent(
  43. name, internal::CreateCustomEvent(isolate(), GetWrapper(), event),
  44. args...);
  45. }
  46. // this.emit(name, new Event(flags), args...);
  47. template <typename... Args>
  48. bool EmitWithFlags(const base::StringPiece& name,
  49. int flags,
  50. const Args&... args) {
  51. return EmitCustomEvent(
  52. name, internal::CreateEventFromFlags(isolate(), flags), args...);
  53. }
  54. // this.emit(name, new Event(), args...);
  55. template <typename... Args>
  56. bool Emit(const base::StringPiece& name, const Args&... args) {
  57. return EmitWithSender(name, nullptr, nullptr, args...);
  58. }
  59. // this.emit(name, new Event(sender, message), args...);
  60. template <typename... Args>
  61. bool EmitWithSender(const base::StringPiece& name,
  62. content::RenderFrameHost* sender,
  63. IPC::Message* message,
  64. const Args&... args) {
  65. v8::Locker locker(isolate());
  66. v8::HandleScope handle_scope(isolate());
  67. v8::Local<v8::Object> wrapper = GetWrapper();
  68. if (wrapper.IsEmpty()) {
  69. return false;
  70. }
  71. v8::Local<v8::Object> event =
  72. internal::CreateJSEvent(isolate(), wrapper, sender, message);
  73. return EmitWithEvent(name, event, args...);
  74. }
  75. protected:
  76. EventEmitter() {}
  77. private:
  78. // this.emit(name, event, args...);
  79. template <typename... Args>
  80. bool EmitWithEvent(const base::StringPiece& name,
  81. v8::Local<v8::Object> event,
  82. const Args&... args) {
  83. v8::Locker locker(isolate());
  84. v8::HandleScope handle_scope(isolate());
  85. EmitEvent(isolate(), GetWrapper(), name, event, args...);
  86. return event->Get(StringToV8(isolate(), "defaultPrevented"))
  87. ->BooleanValue();
  88. }
  89. DISALLOW_COPY_AND_ASSIGN(EventEmitter);
  90. };
  91. } // namespace mate
  92. #endif // ATOM_BROWSER_API_EVENT_EMITTER_H_