| // 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 "core/frame/PlatformEventDispatcher.h" |
| |
| #include "core/frame/PlatformEventController.h" |
| #include "platform/wtf/AutoReset.h" |
| |
| namespace blink { |
| |
| PlatformEventDispatcher::PlatformEventDispatcher() |
| : is_dispatching_(false), is_listening_(false) {} |
| |
| void PlatformEventDispatcher::AddController( |
| PlatformEventController* controller) { |
| DCHECK(controller); |
| // TODO: If we can avoid to register a same controller twice, we can change |
| // this 'if' to ASSERT. |
| if (controllers_.Contains(controller)) |
| return; |
| |
| controllers_.insert(controller); |
| |
| if (!is_listening_) { |
| StartListening(); |
| is_listening_ = true; |
| } |
| } |
| |
| void PlatformEventDispatcher::RemoveController( |
| PlatformEventController* controller) { |
| DCHECK(controllers_.Contains(controller)); |
| |
| controllers_.erase(controller); |
| if (!is_dispatching_ && controllers_.IsEmpty()) { |
| StopListening(); |
| is_listening_ = false; |
| } |
| } |
| |
| void PlatformEventDispatcher::NotifyControllers() { |
| if (controllers_.IsEmpty()) |
| return; |
| |
| { |
| AutoReset<bool> change_is_dispatching(&is_dispatching_, true); |
| // HashSet m_controllers can be updated during an iteration, and it stops |
| // the iteration. Thus we store it into a Vector to access all elements. |
| HeapVector<Member<PlatformEventController>> snapshot_vector; |
| CopyToVector(controllers_, snapshot_vector); |
| for (PlatformEventController* controller : snapshot_vector) { |
| if (controllers_.Contains(controller)) |
| controller->DidUpdateData(); |
| } |
| } |
| |
| if (controllers_.IsEmpty()) { |
| StopListening(); |
| is_listening_ = false; |
| } |
| } |
| |
| void PlatformEventDispatcher::Trace(blink::Visitor* visitor) { |
| visitor->Trace(controllers_); |
| } |
| |
| } // namespace blink |