• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()13 PlatformEventDispatcher::PlatformEventDispatcher()
14     : m_needsPurge(false)
15     , m_isDispatching(false)
16 {
17 }
18 
~PlatformEventDispatcher()19 PlatformEventDispatcher::~PlatformEventDispatcher()
20 {
21 }
22 
addController(PlatformEventController * controller)23 void 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)32 void 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()51 void 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()71 void 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