rough work in progress; may not build
[tripe-android] / progress.scala
CommitLineData
c8292b34
MW
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
26package uk.org.distorted.tripe; package object progress;
27
28/*----- Imports -----------------------------------------------------------*/
29
30import Math.ceil;
31import System.currentTimeMillis;
32import System.{err => stderr}; // FIXME: split out terminal progress
33
34/*----- Main code ---------------------------------------------------------*/
35
36def 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
45private val UDATA = Seq("kB", "MB", "GB", "PB", "EB");
46def 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
54trait 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
64trait 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
84object TerminalEyecandy extends Eyecandy {
85 private var last = "";
86 var eyecandyp =
87
88}
89
90/*----- That's all, folks -------------------------------------------------*/