Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/windirstat.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames C. Norris <jnorris@gmail.com>2016-10-27 08:27:36 +0300
committerJames C. Norris <jnorris@gmail.com>2016-10-27 08:27:36 +0300
commitc439f261300c13786094a164936efe9991ab6c06 (patch)
treea53992a4c05f2d97fea67473368c0eb22d8c44c4
parentf1a5430b9467ff766f8a742ead1b410676c6da1d (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.cpp60
-rw-r--r--windirstat/WorkLimiter.h46
-rw-r--r--windirstat/dirstatdoc.cpp4
-rw-r--r--windirstat/dirstatdoc.h3
-rw-r--r--windirstat/item.cpp18
-rw-r--r--windirstat/item.h4
-rw-r--r--windirstat/windirstat.cpp5
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;
}