[Libreoffice-commits] core.git: Branch 'feature/priorities' - include/vcl vcl/inc vcl/source

Tobias Madl tobias.madl.dev at gmail.com
Tue Jan 13 23:32:57 PST 2015


 include/vcl/idle.hxx     |   84 ++++++++++++++++++
 include/vcl/timer.hxx    |   41 --------
 vcl/inc/svdata.hxx       |    3 
 vcl/inc/window.h         |    1 
 vcl/source/app/idle.cxx  |  218 +++++++++++++++++++++++++++++++++++++++++++++++
 vcl/source/app/svapp.cxx |    3 
 vcl/source/app/timer.cxx |   98 ---------------------
 7 files changed, 310 insertions(+), 138 deletions(-)

New commits:
commit f23d12b5fc9e1750972b0f67cff8b6ac40538469
Author: Tobias Madl <tobias.madl.dev at gmail.com>
Date:   Wed Jan 14 08:29:37 2015 +0100

    Idle: Idle and Timer completely independend
    
    Now the Idle and Timer are divided in two seperate classes. But now all changed
    idles need a new import, before the programm is working again.
    
    Change-Id: I5be7424622b6fcc993c621fa4a11fbee1b6d9bf2

diff --git a/include/vcl/idle.hxx b/include/vcl/idle.hxx
new file mode 100644
index 0000000..9da8414
--- /dev/null
+++ b/include/vcl/idle.hxx
@@ -0,0 +1,84 @@
+/* -*- 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_VCL_IDLE_HXX
+#define INCLUDED_VCL_IDLE_HXX
+
+#include <tools/link.hxx>
+#include <tools/solar.h>
+#include <vcl/dllapi.h>
+
+struct ImplIdleData;
+struct ImplSVData;
+
+enum class IdlePriority {
+    VCL_IDLE_PRIORITY_HIGHEST   = 0, // -> 0ms
+    VCL_IDLE_PRIORITY_HIGH      = 1,    // -> 1ms
+    VCL_IDLE_PRIORITY_REPAINT   = 2, // -> 30ms
+    VCL_IDLE_PRIORITY_RESIZE    = 3,  // -> 50ms
+    VCL_IDLE_PRIORITY_MEDIUM    = 4,  // -> 50ms
+    VCL_IDLE_PRIORITY_LOW       = 5,     // -> 100ms
+    VCL_IDLE_PRIORITY_LOWER     = 6,   // -> 200ms
+    VCL_IDLE_PRIORITY_LOWEST    = 7   // -> 400ms
+};
+
+
+// To port from Timer -> Idle switch class name,
+// s/Timeout/DoIdle/ etc. and select priority
+class VCL_DLLPUBLIC Idle
+{
+protected:
+    ImplIdleData*   mpIdleData;
+    IdlePriority    mePriority;
+    bool            mbActive;
+    Link            maIdleHdl;
+
+    friend struct ImplIdleData;
+
+public:
+    Idle();
+    Idle( const Idle& rIdle );
+    virtual ~Idle();
+
+    void SetPriority( IdlePriority ePriority ) { mePriority = ePriority; }
+    IdlePriority GetPriority() const { return mePriority; }
+
+    /// Make it possible to associate a callback with this idle handler
+    /// of course, you can also sub-class and override 'DoIdle'
+    void            SetIdleHdl( const Link& rLink ) { maIdleHdl = rLink; }
+    const Link&     GetIdleHdl() const              { return maIdleHdl; }
+
+    virtual void    DoIdle();
+
+    void            Start();
+    void            Stop();
+
+    bool            IsActive() const { return mbActive; }
+
+    Idle&          operator=( const Idle& rIdle );
+    static void ImplDeInitIdle();
+    static void ImplIdleCallbackProc();
+
+    /// Process all pending idle tasks ahead of time in priority order.
+    static void ProcessAllIdleHandlers();
+};
+
+#endif // INCLUDED_VCL_IDLE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/timer.hxx b/include/vcl/timer.hxx
index 11e8f3f..ea65d6f 100644
--- a/include/vcl/timer.hxx
+++ b/include/vcl/timer.hxx
@@ -35,7 +35,6 @@ protected:
     sal_uLong       mnTimeout;
     bool            mbActive;
     bool            mbAuto;
-    bool            mbIdle;
     Link            maTimeoutHdl;
 
     friend struct ImplTimerData;
@@ -63,9 +62,6 @@ public:
 
     static void ImplDeInitTimer();
     static void ImplTimerCallbackProc();
-
-    /// Process all pending idle tasks ahead of time in priority order.
-    static void ProcessAllIdleHandlers();
 };
 
 /// An auto-timer is a multi-shot timer re-emitting itself at
@@ -78,43 +74,6 @@ public:
 
     AutoTimer&      operator=( const AutoTimer& rTimer );
 };
-
-enum IdlePriority {
-    VCL_IDLE_PRIORITY_HIGHEST, // -> 0ms
-    VCL_IDLE_PRIORITY_HIGH,    // -> 1ms
-    VCL_IDLE_PRIORITY_REPAINT, // -> 30ms
-    VCL_IDLE_PRIORITY_RESIZE,  // -> 50ms
-    VCL_IDLE_PRIORITY_MEDIUM,  // -> 50ms
-    VCL_IDLE_PRIORITY_LOW,     // -> 100ms
-    VCL_IDLE_PRIORITY_LOWER,   // -> 200ms
-    VCL_IDLE_PRIORITY_LOWEST   // -> 400ms
-};
-
-
-// To port from Timer -> Idle switch class name,
-// s/Timeout/DoIdle/ etc. and select priority
-class VCL_DLLPUBLIC Idle : public Timer
-{
- public:
-    Idle();
-    Idle( IdlePriority ePriority );
-    virtual ~Idle();
-
-    void SetPriority( IdlePriority ePriority );
-
-    /// Make it possible to associate a callback with this idle handler
-    /// of course, you can also sub-class and override 'DoIdle'
-    void            SetIdleHdl( const Link& rLink ) { SetTimeoutHdl( rLink ); }
-    const Link&     GetIdleHdl() const              { return GetTimeoutHdl(); }
-
-    void            Start() { Timer::Start(); }
-    void            Stop()  { Timer::Stop();  }
-
-    virtual void    DoIdle();
-
-    virtual void    Timeout() SAL_OVERRIDE { DoIdle(); }
-};
-
 #endif // INCLUDED_VCL_TIMER_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index dd76b85..fc49591 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -48,6 +48,7 @@
 #include <config_version.h>
 
 struct ImplTimerData;
+struct ImplIdleData;
 struct ImplConfigData;
 class ImplDirectFontSubstitution;
 struct ImplHotKey;
@@ -65,6 +66,7 @@ class AllSettings;
 class NotifyEvent;
 class Timer;
 class AutoTimer;
+class Idle;
 class Help;
 class ImageList;
 class Image;
@@ -310,6 +312,7 @@ struct ImplSVData
     sal_uLong               mnThreadCount;                  // is VCL MultiThread enabled
     ImplConfigData*         mpFirstConfigData;              // pointer to the first config block
     ImplTimerData*          mpFirstTimerData;               // list of all running timers
+    ImplIdleData*           mpFirstIdleData;                // list of all running idles
     SalTimer*               mpSalTimer;                     // interface to sal event loop/timers
     SalI18NImeStatus*       mpImeStatus;                    // interface to ime status window
     SalSystem*              mpSalSystem;                    // SalSystem interface
diff --git a/vcl/inc/window.h b/vcl/inc/window.h
index 6e6129b..5454ae8 100644
--- a/vcl/inc/window.h
+++ b/vcl/inc/window.h
@@ -34,6 +34,7 @@
 #include <vcl/pointr.hxx>
 #include <vcl/salnativewidgets.hxx>
 #include <vcl/timer.hxx>
+#include <vcl/idle.hxx>
 #include <vcl/vclevent.hxx>
 #include <vector>
 
diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx
new file mode 100644
index 0000000..bf715fb
--- /dev/null
+++ b/vcl/source/app/idle.cxx
@@ -0,0 +1,218 @@
+/* -*- 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 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <vcl/idle.hxx>
+
+#include <svdata.hxx>
+#include <salinst.hxx>
+
+struct ImplIdleData
+{
+    ImplIdleData*   mpNext;         // Pointer to the next Instance
+    Idle*           mpIdle;        // Pointer to VCL Idle instance
+    bool            mbDelete;       // Was Idle deleted during Update()?
+    bool            mbInIdle;    // Are we in a idle handler?
+
+    void Invoke()
+    {
+        if (mbDelete || mbInIdle )
+            return;
+
+        mbDelete = true;
+        mpIdle->mbActive = false;
+
+        // invoke it
+        mbInIdle = true;
+        mpIdle->DoIdle();
+        mbInIdle = false;
+    }
+
+    static ImplIdleData *GetFirstIdle()
+    {
+        ImplSVData*     pSVData = ImplGetSVData();
+        ImplIdleData *pMostUrgent = NULL;
+
+        for ( ImplIdleData *p = pSVData->mpFirstIdleData; p; p = p->mpNext )
+        {
+            if ( !p->mpIdle || p->mbDelete )
+                continue;
+            if (!pMostUrgent)
+                pMostUrgent = p;
+            else
+            {
+                // Find the highest priority one somehow.
+                if ( p->mpIdle->GetPriority() < pMostUrgent->mpIdle->GetPriority() )
+                    pMostUrgent = p;
+            }
+        }
+
+        return pMostUrgent;
+    }
+};
+
+void Idle::ImplDeInitIdle()
+{
+    ImplSVData*     pSVData = ImplGetSVData();
+    ImplIdleData*  pIdleData = pSVData->mpFirstIdleData;
+
+    if ( pIdleData )
+    {
+        do
+        {
+            ImplIdleData* pTempIdleData = pIdleData;
+            if ( pIdleData->mpIdle )
+            {
+                pIdleData->mpIdle->mbActive = false;
+                pIdleData->mpIdle->mpIdleData = NULL;
+            }
+            pIdleData = pIdleData->mpNext;
+            delete pTempIdleData;
+        }
+        while ( pIdleData );
+
+        pSVData->mpFirstIdleData   = NULL;
+    }
+}
+
+void Idle::ProcessAllIdleHandlers()
+{
+    // process all pending Idle
+    ImplIdleData* pIdleData;
+    ImplIdleData* pPrevIdleData;
+    while (pIdleData = ImplIdleData::GetFirstIdle())
+    {
+        pIdleData->Invoke();
+    }
+
+    pIdleData = pSVData->mpFirstIdleData;
+    while ( pIdleData )
+    {
+        // Was timer destroyed in the meantime?
+        if ( pIdleData->mbDelete )
+        {
+            if ( pPrevIdleData )
+                pPrevIdleData->mpNext = pIdleData->mpNext;
+            else
+                pSVData->mpFirstIdleData = pIdleData->mpNext;
+            if ( pIdleData->mpIdle )
+                pIdleData->mpIdle->mpIdleData = NULL;
+            ImplIdleData* pTempIdleData = pIdleData;
+            pIdleData = pIdleData->mpNext;
+            delete pTempIdleData;
+        }
+        else
+        {
+            pPrevIdleData = pIdleData;
+            pIdleData = pIdleData->mpNext;
+        }
+    }
+}
+
+void Idle::DoIdle()
+{
+    maIdleHdl.Call( this );
+}
+
+void Idle::Start()
+{
+    mbActive = true;
+
+    ImplSVData* pSVData = ImplGetSVData();
+    if ( !mpIdleData )
+    {
+        // insert timer and start
+        mpIdleData = new ImplIdleData;
+        mpIdleData->mpIdle        = this;
+        mpIdleData->mbDelete       = false;
+        mpIdleData->mbInIdle    = false;
+
+        // insert last due to SFX!
+        ImplIdleData* pPrev = NULL;
+        ImplIdleData* pData = pSVData->mpFirstIdleData;
+        while ( pData )
+        {
+            pPrev = pData;
+            pData = pData->mpNext;
+        }
+        mpIdleData->mpNext = NULL;
+        if ( pPrev )
+            pPrev->mpNext = mpIdleData;
+        else
+            pSVData->mpFirstIdleData = mpIdleData;
+    }
+    else if( !mpIdleData->mpIdle ) // TODO: remove when guilty found
+    {
+        OSL_FAIL( "Idle::Start() on a destroyed Idle!" );
+    }
+    else
+    {
+        mpIdleData->mbDelete        = false;
+    }
+}
+
+void Idle::Stop()
+{
+    mbActive = false;
+
+    if ( mpIdleData )
+        mpIdleData->mbDelete = true;
+}
+
+Idle& Idle::operator=( const Idle& rIdle )
+{
+    if ( IsActive() )
+        Stop();
+
+    mbActive        = false;
+    mePriority       = rIdle.mePriority;
+    maIdleHdl    = rIdle.maIdleHdl;
+
+    if ( rIdle.IsActive() )
+        Start();
+
+    return *this;
+}
+
+Idle::Idle():
+    mpIdleData(NULL),
+    mePriority(VCL_IDLE_PRIORITY_HIGH),
+    mbActive(false)
+{
+}
+
+Idle::Idle( const Idle& rIdle ):
+    mpIdleData(NULL),
+    mePriority(rIdle.mePriority),
+    mbActive(false),
+    maIdleHdl(rIdle.maIdleHdl)
+{
+    if ( rIdle.IsActive() )
+        Start();
+}
+
+Idle::~Idle()
+{
+    if ( mpIdleData )
+    {
+        mpIdleData->mbDelete = true;
+        mpIdleData->mpIdle = NULL;
+    }
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index cba619a..6e3cd12 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -45,6 +45,7 @@
 #include "vcl/cvtgrf.hxx"
 #include "vcl/unowrap.hxx"
 #include "vcl/timer.hxx"
+#include "vcl/idle.hxx"
 #include "vcl/unohelp.hxx"
 #include "vcl/lazydelete.hxx"
 
@@ -357,7 +358,7 @@ inline void ImplYield( bool i_bWait, bool i_bAllEvents )
     }
 
     //Process all idles
-    Timer::Timer::ProcessAllIdleHandlers();
+    Idle::Idle::ProcessAllIdleHandlers();
 
     pSVData->maAppData.mnDispatchLevel++;
     // do not wait for events if application was already quit; in that
diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx
index 0348543..50023cb 100644
--- a/vcl/source/app/timer.cxx
+++ b/vcl/source/app/timer.cxx
@@ -59,27 +59,6 @@ struct ImplTimerData
     {
         return mnUpdateTime + mpTimer->mnTimeout;
     }
-    static ImplTimerData *GetFirstIdle()
-    {
-        ImplSVData*     pSVData = ImplGetSVData();
-        ImplTimerData *pMostUrgent = NULL;
-
-        for ( ImplTimerData *p = pSVData->mpFirstTimerData; p; p = p->mpNext )
-        {
-            if ( !p->mpTimer || p->mbDelete || !p->mpTimer->mbIdle )
-                continue;
-            if (!pMostUrgent)
-                pMostUrgent = p;
-            else
-            {
-                // Find the highest priority one somehow.
-                if ( p->GetDeadline() < pMostUrgent->GetDeadline() )
-                    pMostUrgent = p;
-            }
-        }
-
-        return pMostUrgent;
-    }
 };
 
 void Timer::ImplDeInitTimer()
@@ -151,7 +130,7 @@ void Timer::ImplTimerCallbackProc()
         // If the timer is not new, was not deleted, and if it is not in the timeout handler, then
         // call the handler as soon as the time is up.
         if ( (pTimerData->mnTimerUpdate < pSVData->mnTimerUpdate) &&
-             !pTimerData->mbDelete && !pTimerData->mbInTimeout && !pTimerData->mpTimer->mbIdle)
+             !pTimerData->mbDelete && !pTimerData->mbInTimeout)
         {
             // time has expired
             if ( pTimerData->GetDeadline() <= nTime )
@@ -231,23 +210,11 @@ void Timer::ImplTimerCallbackProc()
     pSVData->mbNotAllTimerCalled = false;
 }
 
-void Timer::ProcessAllIdleHandlers()
-{
-    // process all pending Idle timers
-    ImplTimerData* pTimerData;
-    while (pTimerData =
-                ImplTimerData::GetFirstIdle())
-    {
-        pTimerData->Invoke();
-    }
-}
-
 Timer::Timer():
     mpTimerData(NULL),
     mnTimeout(1),
     mbActive(false),
-    mbAuto(false),
-    mbIdle(false)
+    mbAuto(false)
 {
 }
 
@@ -256,7 +223,6 @@ Timer::Timer( const Timer& rTimer ):
     mnTimeout(rTimer.mnTimeout),
     mbActive(false),
     mbAuto(false),
-    mbIdle(false),
     maTimeoutHdl(rTimer.maTimeoutHdl)
 {
     if ( rTimer.IsActive() )
@@ -382,64 +348,4 @@ AutoTimer& AutoTimer::operator=( const AutoTimer& rTimer )
     Timer::operator=( rTimer );
     return *this;
 }
-
-Idle::Idle()
-    : Timer()
-{
-    mbIdle = true;
-    SetPriority(VCL_IDLE_PRIORITY_LOWEST);
-}
-
-Idle::Idle( IdlePriority ePriority )
-    : Timer()
-{
-    mbIdle = true;
-    SetPriority( ePriority );
-}
-
-void Idle::SetPriority( IdlePriority ePriority )
-{
-    sal_uLong nTimeoutMS = 0;
-
-    // Ultimately this will just be a sort key in a work queue.
-    switch (ePriority) {
-    case VCL_IDLE_PRIORITY_HIGHEST:
-        nTimeoutMS = 0;
-        break;
-    case VCL_IDLE_PRIORITY_HIGH:
-        nTimeoutMS = 1;
-        break;
-    case VCL_IDLE_PRIORITY_REPAINT:
-        nTimeoutMS = 30;
-        break;
-    case VCL_IDLE_PRIORITY_RESIZE:
-        nTimeoutMS = 50;
-        break;
-    case VCL_IDLE_PRIORITY_MEDIUM:
-        nTimeoutMS = 50;
-        break;
-    case VCL_IDLE_PRIORITY_LOW:
-        nTimeoutMS = 100;
-        break;
-    case VCL_IDLE_PRIORITY_LOWER:
-        nTimeoutMS = 200;
-        break;
-    case VCL_IDLE_PRIORITY_LOWEST:
-    default:
-        nTimeoutMS = 400;
-        break;
-    }
-    SetTimeout( nTimeoutMS );
-}
-
-void Idle::DoIdle()
-{
-    maTimeoutHdl.Call( this );
-}
-
-
-Idle::~Idle()
-{
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list