Index: lib/DispatcherBase_cpp.template |
diff --git a/lib/DispatcherBase_cpp.template b/lib/DispatcherBase_cpp.template |
index 9095cbc961c7761406eb58c76264cf13e9b1f128..b08947aba43f32c1da32a290560dcbd32471e306 100644 |
--- a/lib/DispatcherBase_cpp.template |
+++ b/lib/DispatcherBase_cpp.template |
@@ -39,6 +39,16 @@ DispatchResponse DispatchResponse::InternalError() |
} |
// static |
+DispatchResponse DispatchResponse::InvalidParams(const String& error) |
+{ |
+ DispatchResponse result; |
+ result.m_status = kError; |
+ result.m_errorCode = kInvalidParams; |
+ result.m_errorMessage = error; |
+ return result; |
+} |
+ |
+// static |
DispatchResponse DispatchResponse::FallThrough() |
{ |
DispatchResponse result; |
@@ -58,9 +68,10 @@ DispatcherBase::WeakPtr::~WeakPtr() |
m_dispatcher->m_weakPtrs.erase(this); |
} |
-DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId) |
+DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, int callbackId) |
: m_backendImpl(std::move(backendImpl)) |
- , m_callId(callId) { } |
+ , m_callId(callId) |
+ , m_callbackId(callbackId) { } |
DispatcherBase::Callback::~Callback() = default; |
@@ -77,14 +88,36 @@ void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::Dictionary |
m_backendImpl = nullptr; |
} |
+void DispatcherBase::Callback::fallThroughIfActive() |
+{ |
+ if (!m_backendImpl || !m_backendImpl->get()) |
+ return; |
+ m_backendImpl->get()->markFallThrough(m_callbackId); |
+ m_backendImpl = nullptr; |
+} |
+ |
DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel) |
- : m_frontendChannel(frontendChannel) { } |
+ : m_frontendChannel(frontendChannel) |
+ , m_lastCallbackId(0) |
+ , m_lastCallbackFallThrough(false) { } |
DispatcherBase::~DispatcherBase() |
{ |
clearFrontend(); |
} |
+int DispatcherBase::nextCallbackId() |
+{ |
+ m_lastCallbackFallThrough = false; |
+ return ++m_lastCallbackId; |
+} |
+ |
+void DispatcherBase::markFallThrough(int callbackId) |
+{ |
+ DCHECK(callbackId == m_lastCallbackId); |
+ m_lastCallbackFallThrough = true; |
+} |
+ |
// static |
bool DispatcherBase::getCommandName(const String& message, String* result) |
{ |
@@ -169,7 +202,13 @@ std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr() |
} |
UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel) |
- : m_frontendChannel(frontendChannel) { } |
+ : m_frontendChannel(frontendChannel) |
+ , m_fallThroughForNotFound(false) { } |
+ |
+void UberDispatcher::setFallThroughForNotFound(bool fallThroughForNotFound) |
+{ |
+ m_fallThroughForNotFound = fallThroughForNotFound; |
+} |
void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher) |
{ |
@@ -206,12 +245,16 @@ DispatchResponse::Status UberDispatcher::dispatch(std::unique_ptr<Value> parsedM |
size_t dotIndex = method.find("."); |
if (dotIndex == StringUtil::kNotFound) { |
+ if (m_fallThroughForNotFound) |
+ return DispatchResponse::kFallThrough; |
reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr); |
return DispatchResponse::kError; |
} |
String domain = StringUtil::substring(method, 0, dotIndex); |
auto it = m_dispatchers.find(domain); |
if (it == m_dispatchers.end()) { |
+ if (m_fallThroughForNotFound) |
+ return DispatchResponse::kFallThrough; |
reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr); |
return DispatchResponse::kError; |
} |