office-gobmx/include/svl/broadcast.hxx
Noel Grandin bde0cc68bd tdf#132454 some more improvements
Defer moving around the vector by tagging the last bit in the pointer.

This takes the undo operation from 10s to 8s on my machine.

Also re-organise the fields a little to improve packing.

Also add some design notes

Change-Id: I38fa9156705c00bb9f64e2fc59ea862eba522942
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97424
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2020-07-01 08:31:03 +02:00

96 lines
3.3 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#ifndef INCLUDED_SVL_BROADCAST_HXX
#define INCLUDED_SVL_BROADCAST_HXX
#include <svl/svldllapi.h>
#include <vector>
class SvtListener;
class SfxHint;
class SVL_DLLPUBLIC SvtBroadcaster
{
public:
friend class SvtListener;
typedef std::vector<SvtListener*> ListenersType;
private:
const SvtBroadcaster& operator=(const SvtBroadcaster &) = delete;
/**
* Ensure that the container doesn't contain any duplicated listener
* entries. As a side effect, the listeners get sorted by pointer values
* after this call.
*/
void Normalize() const;
void Add( SvtListener* p );
void Remove( SvtListener* p );
protected:
virtual void ListenersGone();
public:
SvtBroadcaster();
SvtBroadcaster( const SvtBroadcaster &rBC );
virtual ~SvtBroadcaster();
void Broadcast( const SfxHint &rHint );
ListenersType& GetAllListeners();
const ListenersType& GetAllListeners() const;
bool HasListeners() const;
/**
* Listeners and broadcasters are M:N relationship. If you want to
* destruct them, you easily end up in O(M*N) situation; where for every
* listener, you iterate all broadcasters, to remove that one listener.
*
* To avoid that, use this call to announce to the broadcaster it is going
* to die, and the listeners do not have to bother with removing
* themselves from the broadcaster - the broadcaster will not broadcast
* anything after the PrepareForDesctruction() call anyway.
*/
void PrepareForDestruction();
private:
/// contains only one of each listener, which is enforced by SvtListener
mutable ListenersType maListeners;
/// When the broadcaster is about to die, collect listeners that asked for removal.
mutable ListenersType maDestructedListeners;
mutable sal_Int32 mnEmptySlots;
// The first item in maListeners that is not sorted. The container can become large, so this optimizes sorting.
mutable sal_Int32 mnListenersFirstUnsorted;
/// Indicate that this broadcaster will be destructed (we indicate this on all ScColumn's broadcasters during the ScTable destruction, eg.)
bool mbAboutToDie:1;
bool mbDisposing:1;
// Whether maDestructedListeners is sorted or not.
mutable bool mbDestNormalized:1;
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */