Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Unified Diff: ui/events/platform/platform_event_source.cc

Issue 203483004: events: Introduce PlatformEventDispatcher and PlatformEventSource. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tot-merge Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/events/platform/platform_event_source.h ('k') | ui/events/platform/platform_event_source_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/events/platform/platform_event_source.cc
diff --git a/ui/events/platform/platform_event_source.cc b/ui/events/platform/platform_event_source.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ac3d2752eb10c66bf78437f82bacc0463555e23c
--- /dev/null
+++ b/ui/events/platform/platform_event_source.cc
@@ -0,0 +1,135 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/platform/platform_event_source.h"
+
+#include <algorithm>
+
+#include "base/message_loop/message_loop.h"
+#include "ui/events/event.h"
+#include "ui/events/platform/platform_event_dispatcher.h"
+#include "ui/events/platform/platform_event_observer.h"
+#include "ui/events/platform/scoped_event_dispatcher.h"
+
+namespace ui {
+
+// static
+PlatformEventSource* PlatformEventSource::instance_ = NULL;
+
+PlatformEventSource::PlatformEventSource()
+ : overridden_dispatcher_(NULL),
+ overridden_dispatcher_restored_(false) {
+ CHECK(!instance_) << "Only one platform event source can be created.";
+ instance_ = this;
+}
+
+PlatformEventSource::~PlatformEventSource() {
+ CHECK_EQ(this, instance_);
+ instance_ = NULL;
+}
+
+PlatformEventSource* PlatformEventSource::GetInstance() { return instance_; }
+
+void PlatformEventSource::AddPlatformEventDispatcher(
+ PlatformEventDispatcher* dispatcher) {
+ CHECK(dispatcher);
+ DCHECK(std::find(dispatchers_.begin(), dispatchers_.end(), dispatcher) ==
+ dispatchers_.end());
+ dispatchers_.push_back(dispatcher);
+}
+
+void PlatformEventSource::RemovePlatformEventDispatcher(
+ PlatformEventDispatcher* dispatcher) {
+ PlatformEventDispatcherList::iterator remove =
+ std::remove(dispatchers_.begin(), dispatchers_.end(), dispatcher);
+ if (remove != dispatchers_.end())
+ dispatchers_.erase(remove);
+}
+
+scoped_ptr<ScopedEventDispatcher> PlatformEventSource::OverrideDispatcher(
+ PlatformEventDispatcher* dispatcher) {
+ CHECK(dispatcher);
+ overridden_dispatcher_restored_ = false;
+ return make_scoped_ptr(
+ new ScopedEventDispatcher(&overridden_dispatcher_, dispatcher));
+}
+
+void PlatformEventSource::AddPlatformEventObserver(
+ PlatformEventObserver* observer) {
+ CHECK(observer);
+ observers_.AddObserver(observer);
+}
+
+void PlatformEventSource::RemovePlatformEventObserver(
+ PlatformEventObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+uint32_t PlatformEventSource::DispatchEvent(PlatformEvent platform_event) {
+ uint32_t action = POST_DISPATCH_PERFORM_DEFAULT;
+ bool should_quit = false;
+
+ if (!WillProcessEvent(platform_event)) {
+ // Give the overridden dispatcher a chance to dispatch the event first.
+ if (overridden_dispatcher_)
+ action = overridden_dispatcher_->DispatchEvent(platform_event);
+ should_quit = !!(action & POST_DISPATCH_QUIT_LOOP);
+
+ if (action & POST_DISPATCH_PERFORM_DEFAULT) {
+ for (PlatformEventDispatcherList::iterator i = dispatchers_.begin();
+ i != dispatchers_.end();
+ ++i) {
+ PlatformEventDispatcher* dispatcher = *(i);
+ if (dispatcher->CanDispatchEvent(platform_event))
+ action = dispatcher->DispatchEvent(platform_event);
+ if (action & POST_DISPATCH_QUIT_LOOP)
+ should_quit = true;
+ if (action & POST_DISPATCH_STOP_PROPAGATION)
+ break;
+ }
+ }
+ }
+ DidProcessEvent(platform_event);
+
+ // Terminate the message-loop if the dispatcher requested for it.
+ if (should_quit) {
+ base::MessageLoop::current()->QuitNow();
+ action |= POST_DISPATCH_QUIT_LOOP;
+ }
+
+ // If an overridden dispatcher has been destroyed, then the platform
+ // event-source should halt dispatching the current stream of events, and wait
+ // until the next message-loop iteration for dispatching events. This lets any
+ // nested message-loop to unwind correctly and any new dispatchers to receive
+ // the correct sequence of events.
+ if (overridden_dispatcher_restored_)
+ action |= POST_DISPATCH_QUIT_LOOP;
+
+ overridden_dispatcher_restored_ = false;
+
+ return action;
+}
+
+bool PlatformEventSource::WillProcessEvent(PlatformEvent event) {
+ if (observers_.might_have_observers()) {
+ ObserverListBase<PlatformEventObserver>::Iterator it(observers_);
+ PlatformEventObserver* obs;
+ while ((obs = it.GetNext()) != NULL) {
+ if (obs->WillProcessEvent(event))
+ return true;
+ }
+ }
+ return false;
+}
+
+void PlatformEventSource::DidProcessEvent(PlatformEvent event) {
+ FOR_EACH_OBSERVER(PlatformEventObserver, observers_, DidProcessEvent(event));
+}
+
+void PlatformEventSource::OnOverriddenDispatcherRestored() {
+ CHECK(overridden_dispatcher_);
+ overridden_dispatcher_restored_ = true;
+}
+
+} // namespace ui
« no previous file with comments | « ui/events/platform/platform_event_source.h ('k') | ui/events/platform/platform_event_source_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698