summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2021-08-12 13:06:25 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2021-08-12 14:17:15 +0200
commitdf6a8b15a67baa6e2717a7de7755ac93fdb46723 (patch)
treef00335d58e5ccb400a6ca5d7d110981fae7715d1
parenta72f2dcf73df9b9f4420cc93aa57a77c165a0fcb (diff)
tdf#95549 speed up xls open
Remove the m_wThis field, and instead just check the ref count to know if we are being called from our own destructor. Also re-order ScCellRangesBase::Notify so we do the cheap checks first. This shaves 2% off the load time Change-Id: Ie95a4ff46bacba583ec4b3a934f98a9aac3551b9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120385 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r--sc/inc/cellsuno.hxx1
-rw-r--r--sc/source/ui/unoobj/cellsuno.cxx145
2 files changed, 58 insertions, 88 deletions
diff --git a/sc/inc/cellsuno.hxx b/sc/inc/cellsuno.hxx
index b29da7c92c0b..7f1b1a0106ad 100644
--- a/sc/inc/cellsuno.hxx
+++ b/sc/inc/cellsuno.hxx
@@ -176,7 +176,6 @@ class SC_DLLPUBLIC ScCellRangesBase :
friend class ooo::vba::excel::ScVbaCellRangeAccess;
private:
- css::uno::WeakReference<css::uno::XInterface> m_wThis;
const SfxItemPropertySet* pPropSet;
ScDocShell* pDocShell;
std::unique_ptr<ScLinkListener> pValueListener;
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 8828d4dd2af8..6e829f2568eb 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -1377,15 +1377,6 @@ ScCellRangesBase::ScCellRangesBase(ScDocShell* pDocSh, const ScRange& rR) :
bGotDataChangedHint( false ),
aValueListeners( 0 )
{
- // this is a hack to get m_wThis initialized; ideally there would be
- // factory functions doing this but there are so many subclasses of this...
- osl_atomic_increment(&m_refCount);
- {
- m_wThis = uno::Reference<uno::XInterface>(
- static_cast<cppu::OWeakObject*>(this));
- }
- osl_atomic_decrement(&m_refCount);
-
ScRange aCellRange(rR);
aCellRange.PutInOrder();
aRanges.push_back( aCellRange );
@@ -1409,15 +1400,6 @@ ScCellRangesBase::ScCellRangesBase(ScDocShell* pDocSh, const ScRangeList& rR) :
bGotDataChangedHint( false ),
aValueListeners( 0 )
{
- // this is a hack to get m_wThis initialized; ideally there would be
- // factory functions doing this but there are so many subclasses of this...
- osl_atomic_increment(&m_refCount);
- {
- m_wThis = uno::Reference<uno::XInterface>(
- static_cast<cppu::OWeakObject*>(this));
- }
- osl_atomic_decrement(&m_refCount);
-
if (pDocShell) // Null if created with createInstance
{
ScDocument& rDoc = pDocShell->GetDocument();
@@ -1513,17 +1495,65 @@ const ScMarkData* ScCellRangesBase::GetMarkData()
void ScCellRangesBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
- uno::Reference<uno::XInterface> const xThis(m_wThis);
- if (!xThis.is())
- { // fdo#72695: if UNO object is already dead, don't revive it with event
- if (SfxHintId::Dying == rHint.GetId())
- { // if the document dies, must reset to avoid crash in dtor!
- ForgetCurrentAttrs();
- pDocShell = nullptr;
+ const SfxHintId nId = rHint.GetId();
+ if ( nId == SfxHintId::Dying )
+ {
+ // if the document dies, must reset to avoid crash in dtor!
+ ForgetCurrentAttrs();
+ pDocShell = nullptr; // invalid
+
+ // fdo#72695: if UNO object is already dead, don't revive it with event
+ if ( m_refCount > 0 && !aValueListeners.empty() )
+ {
+ // dispose listeners
+
+ lang::EventObject aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ for (uno::Reference<util::XModifyListener> & xValueListener : aValueListeners)
+ xValueListener->disposing( aEvent );
+
+ aValueListeners.clear();
+
+ // The listeners can't have the last ref to this, as it's still held
+ // by the DocShell.
}
- return;
}
- if ( auto pRefHint = dynamic_cast<const ScUpdateRefHint*>(&rHint) )
+ else if ( nId == SfxHintId::DataChanged )
+ {
+ // document content changed -> forget cached attributes
+ ForgetCurrentAttrs();
+
+ if ( bGotDataChangedHint && pDocShell )
+ {
+ // This object was notified of content changes, so one call
+ // for each listener is generated now.
+ // The calls can't be executed directly because the document's
+ // UNO broadcaster list must not be modified.
+ // Instead, add to the document's list of listener calls,
+ // which will be executed directly after the broadcast of
+ // SfxHintId::DataChanged.
+
+ lang::EventObject aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+
+ // the EventObject holds a Ref to this object until after the listener calls
+
+ ScDocument& rDoc = pDocShell->GetDocument();
+ for (const uno::Reference<util::XModifyListener> & xValueListener : aValueListeners)
+ rDoc.AddUnoListenerCall( xValueListener, aEvent );
+
+ bGotDataChangedHint = false;
+ }
+ }
+ else if ( nId == SfxHintId::ScCalcAll )
+ {
+ // broadcast from DoHardRecalc - set bGotDataChangedHint
+ // (SfxHintId::DataChanged follows separately)
+
+ if ( !aValueListeners.empty() )
+ bGotDataChangedHint = true;
+ }
+ else if ( auto pRefHint = dynamic_cast<const ScUpdateRefHint*>(&rHint) )
{
ScDocument& rDoc = pDocShell->GetDocument();
std::unique_ptr<ScRangeList> pUndoRanges;
@@ -1535,7 +1565,7 @@ void ScCellRangesBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
if ( pRefHint->GetMode() == URM_INSDEL
&& aRanges.size() == 1
- && comphelper::getUnoTunnelImplementation<ScTableSheetObj>(xThis)
+ && dynamic_cast<ScTableSheetObj*>(this)
)
{
// #101755#; the range size of a sheet does not change
@@ -1568,65 +1598,6 @@ void ScCellRangesBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
bGotDataChangedHint = true; // need to broadcast the undo, too
}
}
- else
- {
- const SfxHintId nId = rHint.GetId();
- if ( nId == SfxHintId::Dying )
- {
- ForgetCurrentAttrs();
- pDocShell = nullptr; // invalid
-
- if ( !aValueListeners.empty() )
- {
- // dispose listeners
-
- lang::EventObject aEvent;
- aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
- for (uno::Reference<util::XModifyListener> & xValueListener : aValueListeners)
- xValueListener->disposing( aEvent );
-
- aValueListeners.clear();
-
- // The listeners can't have the last ref to this, as it's still held
- // by the DocShell.
- }
- }
- else if ( nId == SfxHintId::DataChanged )
- {
- // document content changed -> forget cached attributes
- ForgetCurrentAttrs();
-
- if ( bGotDataChangedHint && pDocShell )
- {
- // This object was notified of content changes, so one call
- // for each listener is generated now.
- // The calls can't be executed directly because the document's
- // UNO broadcaster list must not be modified.
- // Instead, add to the document's list of listener calls,
- // which will be executed directly after the broadcast of
- // SfxHintId::DataChanged.
-
- lang::EventObject aEvent;
- aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
-
- // the EventObject holds a Ref to this object until after the listener calls
-
- ScDocument& rDoc = pDocShell->GetDocument();
- for (const uno::Reference<util::XModifyListener> & xValueListener : aValueListeners)
- rDoc.AddUnoListenerCall( xValueListener, aEvent );
-
- bGotDataChangedHint = false;
- }
- }
- else if ( nId == SfxHintId::ScCalcAll )
- {
- // broadcast from DoHardRecalc - set bGotDataChangedHint
- // (SfxHintId::DataChanged follows separately)
-
- if ( !aValueListeners.empty() )
- bGotDataChangedHint = true;
- }
- }
}
void ScCellRangesBase::RefChanged()