diff options
author | James C. Norris <jnorris@gmail.com> | 2016-10-27 08:27:36 +0300 |
---|---|---|
committer | James C. Norris <jnorris@gmail.com> | 2016-10-27 08:27:36 +0300 |
commit | c439f261300c13786094a164936efe9991ab6c06 (patch) | |
tree | a53992a4c05f2d97fea67473368c0eb22d8c44c4 | |
parent | f1a5430b9467ff766f8a742ead1b410676c6da1d (diff) |
Add a class CWorkLimiter that isolates limiting work duration
CWorkLimiter limits the amount of work done on any idle cycle, exiting when a set amount of ticks has elapsed or when an input event is pending on the message queue.
-rw-r--r-- | windirstat/WorkLimiter.cpp | 60 | ||||
-rw-r--r-- | windirstat/WorkLimiter.h | 46 | ||||
-rw-r--r-- | windirstat/dirstatdoc.cpp | 4 | ||||
-rw-r--r-- | windirstat/dirstatdoc.h | 3 | ||||
-rw-r--r-- | windirstat/item.cpp | 18 | ||||
-rw-r--r-- | windirstat/item.h | 4 | ||||
-rw-r--r-- | windirstat/windirstat.cpp | 5 |
7 files changed, 128 insertions, 12 deletions
diff --git a/windirstat/WorkLimiter.cpp b/windirstat/WorkLimiter.cpp new file mode 100644 index 0000000..038e21e --- /dev/null +++ b/windirstat/WorkLimiter.cpp @@ -0,0 +1,60 @@ +#include "stdafx.h"
+#include "WorkLimiter.h"
+
+CWorkLimiter::CWorkLimiter()
+ : m_done()
+ , m_tickLimit()
+ , m_prevTicks()
+{
+}
+
+CWorkLimiter::~CWorkLimiter()
+{
+}
+
+void CWorkLimiter::Start(DWORD ticks)
+{
+ DWORD start = Now();
+ m_done = false;
+ m_tickLimit = start + ticks;
+ m_prevTicks = start;
+}
+
+bool CWorkLimiter::IsDone() const
+{
+ if (m_done) return true;
+
+ // check remaining ticks
+ DWORD now = Now();
+ // signed subtraction to deal with overflow
+ long remaining = m_tickLimit - now;
+ if (remaining <= 0)
+ {
+ m_done = true;
+ return true;
+ }
+
+ // check if there are any pending window messages
+ long elapsed = now - m_prevTicks;
+ if (elapsed > 10)
+ {
+ m_prevTicks = now;
+ MSG msg; + if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_QS_INPUT)) + { + m_done = true; + return true; + } + }
+
+ return false;
+}
+
+void CWorkLimiter::DoFileWork()
+{
+}
+
+DWORD CWorkLimiter::Now() const
+{
+ return ::GetTickCount();
+}
\ No newline at end of file diff --git a/windirstat/WorkLimiter.h b/windirstat/WorkLimiter.h new file mode 100644 index 0000000..ffda715 --- /dev/null +++ b/windirstat/WorkLimiter.h @@ -0,0 +1,46 @@ +// WorkLimiter.h - Declaration of CWorkLimiter +// +// WinDirStat - Directory Statistics +// Copyright (C) 2003-2005 Bernhard Seifert +// Copyright (C) 2004-2016 WinDirStat team (windirstat.info) +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//
+#ifndef __WDS_WORKLIMITER_H__ +#define __WDS_WORKLIMITER_H__ +#pragma once
+
+#include <WinDef.h>
+
+class CWorkLimiter
+{
+public:
+ CWorkLimiter();
+ ~CWorkLimiter();
+
+ void Start(DWORD ticks);
+ bool IsDone() const;
+ void DoFileWork();
+
+private:
+ DWORD Now() const;
+
+private:
+ mutable bool m_done;
+ DWORD m_tickLimit;
+ mutable DWORD m_prevTicks;
+};
+
+#endif
\ No newline at end of file diff --git a/windirstat/dirstatdoc.cpp b/windirstat/dirstatdoc.cpp index ee730e2..d116f82 100644 --- a/windirstat/dirstatdoc.cpp +++ b/windirstat/dirstatdoc.cpp @@ -358,7 +358,7 @@ void CDirstatDoc::ForgetItemTree() // This method does some work for ticks ms. // return: true if done or suspended. // -bool CDirstatDoc::Work(DWORD ticks) +bool CDirstatDoc::Work(CWorkLimiter* limiter) { if(NULL == m_rootItem) { @@ -372,7 +372,7 @@ bool CDirstatDoc::Work(DWORD ticks) if(!m_rootItem->IsDone()) { - m_rootItem->DoSomeWork(ticks); + m_rootItem->DoSomeWork(limiter); if(m_rootItem->IsDone()) { m_extensionDataValid = false; diff --git a/windirstat/dirstatdoc.h b/windirstat/dirstatdoc.h index 8145b9e..6924996 100644 --- a/windirstat/dirstatdoc.h +++ b/windirstat/dirstatdoc.h @@ -28,6 +28,7 @@ #include "options.h" class CItem; +class CWorkLimiter; // // The treemap colors as calculated in CDirstatDoc::SetExtensionColors() @@ -107,7 +108,7 @@ public: ULONGLONG GetRootSize(); void ForgetItemTree(); - bool Work(DWORD ticks); // return: true if done. + bool Work(CWorkLimiter* limiter); // return: true if done. bool IsDrive(CString spec); void RefreshMountPointItems(); void RefreshJunctionItems(); diff --git a/windirstat/item.cpp b/windirstat/item.cpp index b271359..2ee2abb 100644 --- a/windirstat/item.cpp +++ b/windirstat/item.cpp @@ -24,6 +24,7 @@ #include "dirstatdoc.h" // GetItemColor() #include "mainframe.h" #include "item.h" +#include "WorkLimiter.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -1043,18 +1044,22 @@ void CItem::AddTicksWorked(DWORD more) m_ticksWorked += more; } -void CItem::DoSomeWork(DWORD ticks) +void CItem::DoSomeWork(CWorkLimiter* limiter) { if(IsDone()) { return; } + if (limiter->IsDone()) + { + return; + } StartPacman(true); DriveVisualUpdateDuringWork(); - DWORD start = ::GetTickCount(); + const DWORD start = ::GetTickCount(); if(GetType() == IT_DRIVE || GetType() == IT_DIRECTORY) { @@ -1131,7 +1136,7 @@ void CItem::DoSomeWork(DWORD ticks) UpdateFreeSpaceItem(); } - if(::GetTickCount() - start > ticks) + if(limiter->IsDone()) { StartPacman(false); return; @@ -1154,7 +1159,7 @@ void CItem::DoSomeWork(DWORD ticks) } DWORD startChildren = ::GetTickCount(); - while(::GetTickCount() - start < ticks) + while(!limiter->IsDone()) { DWORD minticks = UINT_MAX; CItem *minchild = NULL; @@ -1176,10 +1181,9 @@ void CItem::DoSomeWork(DWORD ticks) SetDone(); break; } - DWORD tickssofar = ::GetTickCount() - start; - if(ticks > tickssofar) + if (!limiter->IsDone()) { - minchild->DoSomeWork(ticks - tickssofar); + minchild->DoSomeWork(limiter); } } AddTicksWorked(::GetTickCount() - startChildren); diff --git a/windirstat/item.h b/windirstat/item.h index 31951bd..9e5d0d5 100644 --- a/windirstat/item.h +++ b/windirstat/item.h @@ -29,6 +29,8 @@ #include "FileFindWDS.h" // CFileFindWDS #include <common/wds_constants.h> +class CWorkLimiter; + // Columns enum { @@ -184,7 +186,7 @@ public: void SetDone(); DWORD GetTicksWorked() const; void AddTicksWorked(DWORD more); - void DoSomeWork(DWORD ticks); + void DoSomeWork(CWorkLimiter* limiter); bool StartRefresh(); void UpwardSetUndone(); void RefreshRecycler(); diff --git a/windirstat/windirstat.cpp b/windirstat/windirstat.cpp index edc9df6..b62289c 100644 --- a/windirstat/windirstat.cpp +++ b/windirstat/windirstat.cpp @@ -29,6 +29,7 @@ #include "dirstatdoc.h"
#include "graphview.h"
#include "osspecific.h"
+#include "WorkLimiter.h"
#include <Dbghelp.h> // for mini dumps
#ifdef _DEBUG
@@ -737,7 +738,9 @@ BOOL CDirstatApp::OnIdle(LONG lCount) bool more = false;
CDirstatDoc *doc = GetDocument();
- if((doc) && (!doc->Work(600)))
+ CWorkLimiter limiter;
+ limiter.Start(600);
+ if((doc) && (!doc->Work(&limiter)))
{
more = true;
}
|