diff --git a/atom/browser/api/atom_api_url_request.cc b/atom/browser/api/atom_api_url_request.cc index 465ee3e53cc2..fe60bbb12880 100644 --- a/atom/browser/api/atom_api_url_request.cc +++ b/atom/browser/api/atom_api_url_request.cc @@ -6,6 +6,7 @@ #include #include "atom/browser/api/atom_api_session.h" #include "atom/browser/net/atom_url_request.h" +#include "atom/common/api/event_emitter_caller.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" @@ -52,43 +53,6 @@ struct Converter> { } // namespace mate -namespace { - -template -std::array, sizeof...(ArgTypes)> BuildArgsArray( - v8::Isolate* isolate, - ArgTypes... args) { - std::array, sizeof...(ArgTypes)> result = { - {mate::ConvertToV8(isolate, args)...}}; - return result; -} - -template -void EmitRequestEvent(v8::Isolate* isolate, - v8::Local object, - ArgTypes... args) { - v8::HandleScope handle_scope(isolate); - auto arguments = BuildArgsArray(isolate, args...); - v8::Local _emitRequestEvent; - if (mate::Dictionary(isolate, object) - .Get("_emitRequestEvent", &_emitRequestEvent)) - _emitRequestEvent->Call(object, arguments.size(), arguments.data()); -} - -template -void EmitResponseEvent(v8::Isolate* isolate, - v8::Local object, - ArgTypes... args) { - v8::HandleScope handle_scope(isolate); - auto arguments = BuildArgsArray(isolate, args...); - v8::Local _emitResponseEvent; - if (mate::Dictionary(isolate, object) - .Get("_emitResponseEvent", &_emitResponseEvent)) - _emitResponseEvent->Call(object, arguments.size(), arguments.data()); -} - -} // namespace - namespace atom { namespace api { @@ -249,7 +213,7 @@ bool URLRequest::Write(scoped_refptr buffer, if (is_last) { request_state_.SetFlag(RequestStateFlags::kFinished); - EmitRequestEvent(isolate(), GetWrapper(), true, "finish"); + EmitRequestEvent(true, "finish"); } DCHECK(atom_request_); @@ -273,10 +237,10 @@ void URLRequest::Cancel() { // Really cancel if it was started. atom_request_->Cancel(); } - EmitRequestEvent(isolate(), GetWrapper(), true, "abort"); + EmitRequestEvent(true, "abort"); if (response_state_.Started() && !response_state_.Ended()) { - EmitResponseEvent(isolate(), GetWrapper(), true, "aborted"); + EmitResponseEvent(true, "aborted"); } Close(); } @@ -385,10 +349,10 @@ void URLRequest::OnError(const std::string& error, bool isRequestError) { auto error_object = v8::Exception::Error(mate::StringToV8(isolate(), error)); if (isRequestError) { request_state_.SetFlag(RequestStateFlags::kFailed); - EmitRequestEvent(isolate(), GetWrapper(), false, "error", error_object); + EmitRequestEvent(false, "error", error_object); } else { response_state_.SetFlag(ResponseStateFlags::kFailed); - EmitResponseEvent(isolate(), GetWrapper(), false, "error", error_object); + EmitResponseEvent(false, "error", error_object); } Close(); } @@ -431,9 +395,9 @@ void URLRequest::Close() { request_state_.SetFlag(RequestStateFlags::kClosed); if (response_state_.Started()) { // Emit a close event if we really have a response object. - EmitResponseEvent(isolate(), GetWrapper(), true, "close"); + EmitResponseEvent(true, "close"); } - EmitRequestEvent(isolate(), GetWrapper(), true, "close"); + EmitRequestEvent(true, "close"); } Unpin(); if (atom_request_) { @@ -454,6 +418,18 @@ void URLRequest::Unpin() { wrapper_.Reset(); } +template +void URLRequest::EmitRequestEvent(Args... args) { + v8::HandleScope handle_scope(isolate()); + mate::CustomEmit(isolate(), GetWrapper(), "_emitRequestEvent", args...); +} + +template +void URLRequest::EmitResponseEvent(Args... args) { + v8::HandleScope handle_scope(isolate()); + mate::CustomEmit(isolate(), GetWrapper(), "_emitResponseEvent", args...); +} + } // namespace api } // namespace atom diff --git a/atom/browser/api/atom_api_url_request.h b/atom/browser/api/atom_api_url_request.h index 8b2c32782891..3aae14bb190f 100644 --- a/atom/browser/api/atom_api_url_request.h +++ b/atom/browser/api/atom_api_url_request.h @@ -183,6 +183,10 @@ class URLRequest : public mate::EventEmitter { void Close(); void Pin(); void Unpin(); + template + void EmitRequestEvent(Args... args); + template + void EmitResponseEvent(Args... args); scoped_refptr atom_request_; RequestState request_state_; diff --git a/atom/common/api/event_emitter_caller.cc b/atom/common/api/event_emitter_caller.cc index 40448cad107e..3fbb31c49773 100644 --- a/atom/common/api/event_emitter_caller.cc +++ b/atom/common/api/event_emitter_caller.cc @@ -11,16 +11,16 @@ namespace mate { namespace internal { -v8::Local CallEmitWithArgs(v8::Isolate* isolate, - v8::Local obj, - ValueVector* args) { +v8::Local CallMethodWithArgs(v8::Isolate* isolate, + v8::Local obj, + const char* method, + ValueVector* args) { // Perform microtask checkpoint after running JavaScript. - v8::MicrotasksScope script_scope( - isolate, v8::MicrotasksScope::kRunMicrotasks); + v8::MicrotasksScope script_scope(isolate, + v8::MicrotasksScope::kRunMicrotasks); // Use node::MakeCallback to call the callback, and it will also run pending // tasks in Node.js. - return node::MakeCallback( - isolate, obj, "emit", args->size(), &args->front()); + return node::MakeCallback(isolate, obj, method, args->size(), &args->front()); } } // namespace internal diff --git a/atom/common/api/event_emitter_caller.h b/atom/common/api/event_emitter_caller.h index a2567da9d109..24917cbef62c 100644 --- a/atom/common/api/event_emitter_caller.h +++ b/atom/common/api/event_emitter_caller.h @@ -15,37 +15,50 @@ namespace internal { using ValueVector = std::vector>; -v8::Local CallEmitWithArgs(v8::Isolate* isolate, - v8::Local obj, - ValueVector* args); +v8::Local CallMethodWithArgs(v8::Isolate* isolate, + v8::Local obj, + const char* method, + ValueVector* args); } // namespace internal // obj.emit.apply(obj, name, args...); // The caller is responsible of allocating a HandleScope. -template +template v8::Local EmitEvent(v8::Isolate* isolate, v8::Local obj, const StringType& name, const internal::ValueVector& args) { - internal::ValueVector concatenated_args = { StringToV8(isolate, name) }; + internal::ValueVector concatenated_args = {StringToV8(isolate, name)}; concatenated_args.reserve(1 + args.size()); concatenated_args.insert(concatenated_args.end(), args.begin(), args.end()); - return internal::CallEmitWithArgs(isolate, obj, &concatenated_args); + return internal::CallMethodWithArgs(isolate, obj, "emit", &concatenated_args); } // obj.emit(name, args...); // The caller is responsible of allocating a HandleScope. -template +template v8::Local EmitEvent(v8::Isolate* isolate, v8::Local obj, const StringType& name, const Args&... args) { internal::ValueVector converted_args = { - StringToV8(isolate, name), + StringToV8(isolate, name), ConvertToV8(isolate, args)..., + }; + return internal::CallMethodWithArgs(isolate, obj, "emit", &converted_args); +} + +// obj.custom_emit(args...) +template +v8::Local CustomEmit(v8::Isolate* isolate, + v8::Local object, + const char* custom_emit, + const Args&... args) { + internal::ValueVector converted_args = { ConvertToV8(isolate, args)..., }; - return internal::CallEmitWithArgs(isolate, obj, &converted_args); + return internal::CallMethodWithArgs(isolate, object, custom_emit, + &converted_args); } } // namespace mate