Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <assert.h>
21 :
22 : #include <tools/debug.hxx>
23 :
24 : #include <svl/hint.hxx>
25 : #include <svl/smplhint.hxx>
26 : #include <svl/lstner.hxx>
27 :
28 : #include <svl/brdcst.hxx>
29 : #include <algorithm>
30 :
31 : //====================================================================
32 : DBG_NAME(SfxBroadcaster)
33 20486 : TYPEINIT0(SfxBroadcaster);
34 :
35 : //====================================================================
36 :
37 : //====================================================================
38 : // broadcast immediately
39 :
40 88969 : void SfxBroadcaster::Broadcast( const SfxHint &rHint )
41 : {
42 : DBG_CHKTHIS(SfxBroadcaster, 0);
43 :
44 : // notify all registered listeners exactly once
45 569535 : for (size_t n = 0; n < m_Listeners.size(); ++n)
46 : {
47 480566 : SfxListener *const pListener = m_Listeners[n];
48 480566 : if (pListener) {
49 370032 : pListener->Notify( *this, rHint );
50 : }
51 : }
52 88969 : }
53 :
54 : // unregister all listeners
55 :
56 64363 : SfxBroadcaster::~SfxBroadcaster()
57 : {
58 : DBG_DTOR(SfxBroadcaster, 0);
59 :
60 29353 : Broadcast( SfxSimpleHint(SFX_HINT_DYING) );
61 :
62 : // remove all still registered listeners
63 43785 : for (size_t nPos = 0; nPos < m_Listeners.size(); ++nPos)
64 : {
65 14432 : SfxListener *const pListener = m_Listeners[nPos];
66 14432 : if (pListener) {
67 2297 : pListener->RemoveBroadcaster_Impl(*this);
68 : }
69 : }
70 35010 : }
71 :
72 : //--------------------------------------------------------------------
73 :
74 : // simple ctor of class SfxBroadcaster
75 :
76 39623 : SfxBroadcaster::SfxBroadcaster()
77 : {
78 : DBG_CTOR(SfxBroadcaster, 0);
79 39623 : }
80 :
81 : //--------------------------------------------------------------------
82 :
83 : // copy ctor of class SfxBroadcaster
84 :
85 :
86 0 : SfxBroadcaster::SfxBroadcaster( const SfxBroadcaster &rBC )
87 : {
88 : DBG_CTOR(SfxBroadcaster, 0);
89 :
90 0 : for (size_t n = 0; n < rBC.m_Listeners.size(); ++n)
91 : {
92 0 : SfxListener *const pListener = rBC.m_Listeners[n];
93 0 : if (pListener) {
94 0 : pListener->StartListening( *this );
95 : }
96 : }
97 0 : }
98 :
99 : //--------------------------------------------------------------------
100 :
101 : // add a new SfxListener to the list
102 :
103 54579 : void SfxBroadcaster::AddListener( SfxListener& rListener )
104 : {
105 : DBG_CHKTHIS(SfxBroadcaster, 0);
106 :
107 2704861 : for (size_t i = 0; i < m_Listeners.size(); ++i)
108 : {
109 2683547 : if (!m_Listeners[i]) // removed by RemoveListener?
110 : {
111 33265 : m_Listeners[i] = &rListener;
112 87844 : return;
113 : }
114 : }
115 21314 : m_Listeners.push_back(&rListener);
116 : }
117 :
118 : //--------------------------------------------------------------------
119 :
120 : // called, if no more listeners exists
121 :
122 7311 : void SfxBroadcaster::ListenersGone()
123 : {
124 : DBG_CHKTHIS(SfxBroadcaster,0);
125 7311 : }
126 :
127 : //--------------------------------------------------------------------
128 :
129 : // forward a notification to all registered listeners
130 :
131 68382 : void SfxBroadcaster::Forward(SfxBroadcaster& rBC, const SfxHint& rHint)
132 : {
133 124107 : for (size_t i = 0; i < m_Listeners.size(); ++i)
134 : {
135 55725 : SfxListener *const pListener = m_Listeners[i];
136 55725 : if (pListener) {
137 47849 : pListener->Notify( rBC, rHint );
138 : }
139 : }
140 68382 : }
141 :
142 : //--------------------------------------------------------------------
143 :
144 : // remove one SfxListener from the list
145 :
146 46205 : void SfxBroadcaster::RemoveListener( SfxListener& rListener )
147 : {
148 : {DBG_CHKTHIS(SfxBroadcaster, 0);}
149 : SfxListenerArr_Impl::iterator aIter = std::find(
150 46205 : m_Listeners.begin(), m_Listeners.end(), &rListener);
151 : assert(aIter != m_Listeners.end()); // "RemoveListener: Listener unknown"
152 : // DO NOT erase the listener, set the pointer to 0
153 : // because the current continuation may contain this->Broadcast
154 46205 : *aIter = 0;
155 :
156 46205 : if ( !HasListeners() )
157 7311 : ListenersGone();
158 46205 : }
159 :
160 46280 : bool SfxBroadcaster::HasListeners() const
161 : {
162 60550 : for (size_t i = 0; i < m_Listeners.size(); ++i)
163 : {
164 53164 : if (m_Listeners[i]) {
165 38894 : return true;
166 : }
167 : }
168 7386 : return false;
169 : }
170 :
171 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|