[Pkg-haskell-commits] [SCM] haskell-testpack branch, master, updated. debian/1.0.2-1-4-gb0d6b36
John Goerzen
jgoerzen at complete.org
Fri Apr 23 15:11:12 UTC 2010
The following commit has been merged in the master branch:
commit dcf4993f6be36c8d0f12d2e485ad30427b87eb5e
Author: John Goerzen <jgoerzen at complete.org>
Date: Fri Oct 13 22:27:46 2006 +0100
More work and add parent support
diff --git a/MissingH/ProgressTracker.hs b/MissingH/ProgressTracker.hs
index 54b90e5..0238ff8 100644
--- a/MissingH/ProgressTracker.hs
+++ b/MissingH/ProgressTracker.hs
@@ -53,21 +53,23 @@ status and are intended to do things like update on-screen status displays.
-}
-module MissingH.ProgressTracker (-- * Types
- ProgressStatus(..),
- Progress, ProgressTimeSource,
- ProgressCallback,
- ProgressStatuses,
+module MissingH.ProgressTracker (
-- * Creation and Options
newProgress, newProgress',
+ addCallback, addParent,
-- * Updating
incrP, incrP', setP, setP', incrTotal,
- setTotal,
+ setTotal, finishP,
-- * Reading and Processing
getSpeed,
withStatus,
getETR,
getETA,
+ -- * Types
+ ProgressStatus(..),
+ Progress, ProgressTimeSource,
+ ProgressCallback,
+ ProgressStatuses,
-- * Utilities
defaultTimeSource
)
@@ -83,7 +85,15 @@ import Data.Ratio
----------------------------------------------------------------------
type ProgressTimeSource = IO Integer
-type ProgressCallback = ProgressRecord -> ProgressRecord -> IO ()
+
+{- | The type for a callback function for the progress tracker.
+When given at creation time to 'newProgress\'' or when added via 'addCallback',
+these functions get called every time the status of the tracker changes.
+
+This function is passed two 'ProgressStatus' records: the first
+reflects the status prior to the update, and the second reflects
+the status after the update. -}
+type ProgressCallback = ProgressStatus -> ProgressStatus -> IO ()
{- | The main progress status record. -}
data ProgressStatus =
@@ -157,6 +167,45 @@ newProgress' news newcb =
callbacks = newcb, status = news}
return (Progress r)
+{- | Adds an new callback to an existing 'Progress'. -}
+addCallback :: Progress -> ProgressCallback -> IO ()
+addCallback (Progress mpo) cb = modifyMVar_ mpo $ \po ->
+ return $ po {callbacks = cb : callbacks po}
+
+{- | Adds a new parent to an existing 'Progress'. The parent
+will automatically have its completed and total counters incremented
+by the value of those counters in the existing 'Progress'. -}
+addParent :: Progress -- ^ The child object
+ -> Progress -- ^ The parent to add to this child
+ -> IO ()
+addParent (Progress mcpo) ppo = modifyMVar_ mcpo $ \cpo ->
+ do incrP' ppo (completedUnits . status $ cpo)
+ incrTotal ppo (totalUnits . status $ cpo)
+ return $ cpo {parents = ppo : parents cpo}
+
+{- | Call this when you are finished with the object. It is especially
+important to do this when parent objects are involved.
+
+This will simply set the totalUnits to the current completedUnits count,
+but will not call the callbacks. It will additionally propogate
+any adjustment in totalUnits to the parents, whose callbacks /will/ be
+called.
+
+This ensures that the total expected counts on the parent are always correct.
+Without doing this, if, say, a transfer ended earlier than expected, ETA
+values on the parent would be off since it would be expecting more data than
+actually arrived. -}
+finishP :: Progress -> IO ()
+finishP (Progress mp) =
+ modifyMVar_ mp modfunc
+ where modfunc :: ProgressRecord -> IO ProgressRecord
+ modfunc oldpr =
+ do let adjustment = (completedUnits . status $ oldpr)
+ - (totalUnits . status $ oldpr)
+ callParents oldpr (\x -> incrTotal x adjustment)
+ return $ oldpr {status = (status oldpr)
+ {totalUnits = completedUnits . status $ oldpr}}
+
----------------------------------------------------------------------
-- Updating
----------------------------------------------------------------------
@@ -226,7 +275,9 @@ object. This is in the IO monad because the speed is based on the current
time.
Example:
->getSpeed progressobj >>= print
+
+> getSpeed progressobj >>= print
+
-}
getSpeed :: (ProgressStatuses a (IO b), Fractional b) => a -> IO b
getSpeed po = withStatus po $ \status ->
@@ -281,7 +332,11 @@ modStatus :: Progress -> (ProgressStatus -> ProgressStatus) -> IO ()
modStatus (Progress mp) func =
modifyMVar_ mp modfunc
where modfunc :: ProgressRecord -> IO ProgressRecord
- modfunc pr =
- do let newpr = pr {status = func (status pr)}
- mapM_ (\x -> x pr newpr) (callbacks pr)
+ modfunc oldpr =
+ do let newpr = oldpr {status = func (status oldpr)}
+ mapM_ (\x -> x (status oldpr) (status newpr))
+ (callbacks oldpr)
return newpr
+
+callParents :: ProgressRecord -> (Progress -> IO ()) -> IO ()
+callParents pr func = mapM_ func (parents pr)
\ No newline at end of file
--
haskell-testpack
More information about the Pkg-haskell-commits
mailing list