1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "config.h" 6 #include "core/frame/PlatformEventDispatcher.h" 7 8 #include "core/frame/PlatformEventController.h" 9 #include "wtf/TemporaryChange.h" 10 11 namespace blink { 12 PlatformEventDispatcher()13PlatformEventDispatcher::PlatformEventDispatcher() 14 : m_needsPurge(false) 15 , m_isDispatching(false) 16 { 17 } 18 ~PlatformEventDispatcher()19PlatformEventDispatcher::~PlatformEventDispatcher() 20 { 21 } 22 addController(PlatformEventController * controller)23void PlatformEventDispatcher::addController(PlatformEventController* controller) 24 { 25 bool wasEmpty = m_controllers.isEmpty(); 26 if (!m_controllers.contains(controller)) 27 m_controllers.append(controller); 28 if (wasEmpty) 29 startListening(); 30 } 31 removeController(PlatformEventController * controller)32void PlatformEventDispatcher::removeController(PlatformEventController* controller) 33 { 34 // Do not actually remove the controller from the vector, instead zero them out. 35 // The zeros are removed in these two cases: 36 // 1. either immediately if we are not dispatching any events, 37 // 2. or after events to all controllers have dispatched (see notifyControllers()). 38 // This is to correctly handle the re-entrancy case when a controller is destroyed 39 // while the events are still being dispatched. 40 size_t index = m_controllers.find(controller); 41 if (index == kNotFound) 42 return; 43 44 m_controllers[index] = 0; 45 m_needsPurge = true; 46 47 if (!m_isDispatching) 48 purgeControllers(); 49 } 50 purgeControllers()51void PlatformEventDispatcher::purgeControllers() 52 { 53 ASSERT(m_needsPurge); 54 55 size_t i = 0; 56 while (i < m_controllers.size()) { 57 if (!m_controllers[i]) { 58 m_controllers[i] = m_controllers.last(); 59 m_controllers.removeLast(); 60 } else { 61 ++i; 62 } 63 } 64 65 m_needsPurge = false; 66 67 if (m_controllers.isEmpty()) 68 stopListening(); 69 } 70 notifyControllers()71void PlatformEventDispatcher::notifyControllers() 72 { 73 { 74 TemporaryChange<bool> changeIsDispatching(m_isDispatching, true); 75 // Don't notify controllers removed or added during event dispatch. 76 size_t size = m_controllers.size(); 77 for (size_t i = 0; i < size; ++i) { 78 if (m_controllers[i]) 79 m_controllers[i]->didUpdateData(); 80 } 81 } 82 83 if (m_needsPurge) 84 purgeControllers(); 85 } 86 87 } // namespace blink 88