LCOV - code coverage report
Current view: top level - svl/source/notify - broadcast.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 65 79 82.3 %
Date: 2015-06-13 12:38:46 Functions: 12 13 92.3 %
Legend: Lines: hit not hit

          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 <svl/broadcast.hxx>
      21             : #include <svl/listener.hxx>
      22             : #include <svl/smplhint.hxx>
      23             : #include <algorithm>
      24             : 
      25       31676 : void SvtBroadcaster::Normalize() const
      26             : {
      27       31676 :     if (!mbNormalized)
      28             :     {
      29       15794 :         std::sort(maListeners.begin(), maListeners.end());
      30       15794 :         ListenersType::iterator itUniqueEnd = std::unique(maListeners.begin(), maListeners.end());
      31       15794 :         maListeners.erase(itUniqueEnd, maListeners.end());
      32       15794 :         mbNormalized = true;
      33             :     }
      34             : 
      35       31676 :     if (!mbDestNormalized)
      36             :     {
      37       12482 :         std::sort(maDestructedListeners.begin(), maDestructedListeners.end());
      38       12482 :         ListenersType::iterator itUniqueEnd = std::unique(maDestructedListeners.begin(), maDestructedListeners.end());
      39       12482 :         maDestructedListeners.erase(itUniqueEnd, maDestructedListeners.end());
      40       12482 :         mbDestNormalized = true;
      41             :     }
      42       31676 : }
      43             : 
      44       20593 : void SvtBroadcaster::Add( SvtListener* p )
      45             : {
      46       20593 :     maListeners.push_back(p);
      47       20593 :     mbNormalized = false;
      48       20593 : }
      49             : 
      50       20267 : void SvtBroadcaster::Remove( SvtListener* p )
      51             : {
      52       20267 :     if (mbDisposing)
      53       18802 :         return;
      54             : 
      55       16212 :     if (mbAboutToDie)
      56             :     {
      57       10692 :         maDestructedListeners.push_back(p);
      58       10692 :         mbDestNormalized = false;
      59       10692 :         return;
      60             :     }
      61             : 
      62        5520 :     Normalize();
      63             :     std::pair<ListenersType::iterator,ListenersType::iterator> r =
      64        5520 :         std::equal_range(maListeners.begin(), maListeners.end(), p);
      65             : 
      66        5520 :     if (r.first != r.second)
      67        5520 :         maListeners.erase(r.first, r.second);
      68        5520 :     if (maListeners.empty())
      69        2714 :         ListenersGone();
      70             : }
      71             : 
      72       12420 : SvtBroadcaster::SvtBroadcaster() : mbAboutToDie(false), mbDisposing(false), mbNormalized(false), mbDestNormalized(false) {}
      73             : 
      74           0 : SvtBroadcaster::SvtBroadcaster( const SvtBroadcaster &rBC ) :
      75             :     maListeners(rBC.maListeners), maDestructedListeners(rBC.maDestructedListeners),
      76             :     mbAboutToDie(rBC.mbAboutToDie), mbDisposing(false),
      77           0 :     mbNormalized(rBC.mbNormalized), mbDestNormalized(rBC.mbDestNormalized)
      78             : {
      79           0 :     if (mbAboutToDie)
      80           0 :         Normalize();
      81             : 
      82           0 :     ListenersType::iterator dest(maDestructedListeners.begin());
      83           0 :     for (ListenersType::iterator it(maListeners.begin()); it != maListeners.end(); ++it)
      84             :     {
      85           0 :         bool bStart = true;
      86             : 
      87           0 :         if (mbAboutToDie)
      88             :         {
      89             :             // skip the destructed ones
      90           0 :             while (dest != maDestructedListeners.end() && (*dest < *it))
      91           0 :                 ++dest;
      92             : 
      93           0 :             bStart = (dest == maDestructedListeners.end() || *dest != *it);
      94             :         }
      95             : 
      96           0 :         if (bStart)
      97           0 :             (*it)->StartListening(*this);
      98             :     }
      99           0 : }
     100             : 
     101       33032 : SvtBroadcaster::~SvtBroadcaster()
     102             : {
     103       12265 :     mbDisposing = true;
     104       12265 :     Broadcast( SfxSimpleHint(SFX_HINT_DYING) );
     105             : 
     106       12265 :     Normalize();
     107             : 
     108             :     // now when both lists are sorted, we can linearly unregister all
     109             :     // listeners, with the exception of those that already asked to be removed
     110             :     // during their own destruction
     111       12265 :     ListenersType::iterator dest(maDestructedListeners.begin());
     112       27012 :     for (ListenersType::iterator it(maListeners.begin()); it != maListeners.end(); ++it)
     113             :     {
     114             :         // skip the destructed ones
     115       32712 :         while (dest != maDestructedListeners.end() && (*dest < *it))
     116        3218 :             ++dest;
     117             : 
     118       14747 :         if (dest == maDestructedListeners.end() || *dest != *it)
     119        4055 :             (*it)->EndListening(*this);
     120             :     }
     121       20767 : }
     122             : 
     123       13717 : void SvtBroadcaster::Broadcast( const SfxHint &rHint )
     124             : {
     125       13717 :     Normalize();
     126             : 
     127       13717 :     ListenersType::iterator dest(maDestructedListeners.begin());
     128       13717 :     ListenersType aListeners(maListeners); // this copy is important to avoid erasing entries while iterating
     129       72047 :     for (ListenersType::iterator it(aListeners.begin()); it != aListeners.end(); ++it)
     130             :     {
     131             :         // skip the destructed ones
     132      119878 :         while (dest != maDestructedListeners.end() && (*dest < *it))
     133        3218 :             ++dest;
     134             : 
     135       58330 :         if (dest == maDestructedListeners.end() || *dest != *it)
     136       47638 :             (*it)->Notify(rHint);
     137       13717 :     }
     138       13717 : }
     139             : 
     140        2711 : void SvtBroadcaster::ListenersGone() {}
     141             : 
     142         173 : SvtBroadcaster::ListenersType& SvtBroadcaster::GetAllListeners()
     143             : {
     144         173 :     Normalize();
     145         173 :     return maListeners;
     146             : }
     147             : 
     148           1 : const SvtBroadcaster::ListenersType& SvtBroadcaster::GetAllListeners() const
     149             : {
     150           1 :     Normalize();
     151           1 :     return maListeners;
     152             : }
     153             : 
     154        3287 : bool SvtBroadcaster::HasListeners() const
     155             : {
     156        3287 :     return !maListeners.empty();
     157             : }
     158             : 
     159        7850 : void SvtBroadcaster::PrepareForDestruction()
     160             : {
     161        7850 :     mbAboutToDie = true;
     162        7850 :     maDestructedListeners.reserve(maListeners.size());
     163        7850 : }
     164             : 
     165             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11