chiark / gitweb /
Makefile: Move all artifacts into a subdirectory.
[tripe-android] / progress.scala
1 /* -*-scala-*-
2  *
3  * Reporting progress for long-running jobs
4  *
5  * (c) 2018 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of the Trivial IP Encryption (TrIPE) Android app.
11  *
12  * TrIPE is free software: you can redistribute it and/or modify it under
13  * the terms of the GNU General Public License as published by the Free
14  * Software Foundation; either version 3 of the License, or (at your
15  * option) any later version.
16  *
17  * TrIPE is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20  * for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with TrIPE.  If not, see <https://www.gnu.org/licenses/>.
24  */
25
26 package uk.org.distorted.tripe; package object progress;
27
28 /*----- Imports -----------------------------------------------------------*/
29
30 import Math.ceil;
31 import System.currentTimeMillis;
32 import System.{err => stderr};          // FIXME: split out terminal progress
33
34 /*----- Main code ---------------------------------------------------------*/
35
36 def formatTime(t: Int): String =
37   if (t < -1) "???"
38   else {
39     val (s, t1) = (t%60, t/60);
40     val (m, h) = (t1%60, t1/60);
41     if (h > 0) f"$h%d:$m%02d:$s%02d"
42     else f"$m%02d:$s%02d"
43   }
44
45 private val UDATA = Seq("kB", "MB", "GB", "PB", "EB");
46 def formatBytes(n: Long): String = {
47   val (x, u) = (n.toDouble, "B ") /: UDATA {
48     case ((x, u), name) if x >= 1024.0 => (x/1024.0, name)
49     case (xu, _) => xu
50   }
51   f"$x%6.1f$u%s"
52 }
53
54 trait Eyecandy {
55   def set(line: String);
56   def clear();
57   def commit();
58   def commit(line: String) { commit(); set(line); commit(); }
59
60   def begin(job: Job);
61 }
62
63
64 trait Job with Publisher[ {
65   def what: String;                     // imperative for what we're doing
66   def cur: Long;                        // current position in work
67   def max: Long;                        // maximum work to do
68   def format: String;                   // describe progress in useful terms
69
70   private[this] val t0 = currentTimeMillis;
71
72   def eta: Int =
73     /* Report the estimated time remaining in seconds, or -1 if no idea.
74      *
75      * The model here is very stupid.  Weird jobs should override this and do
76      * something more sensible.
77      */
78
79     if (max < 0 || cur <= 0) -1
80     else ceil((currentTimeMillis - t0)/1000.0 *
81               (max - cur)/cur.toDouble).toInt;
82 }
83
84 object TerminalEyecandy extends Eyecandy {
85   private var last = "";
86   var eyecandyp = 
87   
88 }
89
90 /*----- That's all, folks -------------------------------------------------*/