rough work in progress; may not build
[tripe-android] / progress.scala
diff --git a/progress.scala b/progress.scala
new file mode 100644 (file)
index 0000000..ddd2b6a
--- /dev/null
@@ -0,0 +1,90 @@
+/* -*-scala-*-
+ *
+ * Reporting progress for long-running jobs
+ *
+ * (c) 2018 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the Trivial IP Encryption (TrIPE) Android app.
+ *
+ * TrIPE 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 3 of the License, or (at your
+ * option) any later version.
+ *
+ * TrIPE 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 TrIPE.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package uk.org.distorted.tripe; package object progress;
+
+/*----- Imports -----------------------------------------------------------*/
+
+import Math.ceil;
+import System.currentTimeMillis;
+import System.{err => stderr};         // FIXME: split out terminal progress
+
+/*----- Main code ---------------------------------------------------------*/
+
+def formatTime(t: Int): String =
+  if (t < -1) "???"
+  else {
+    val (s, t1) = (t%60, t/60);
+    val (m, h) = (t1%60, t1/60);
+    if (h > 0) f"$h%d:$m%02d:$s%02d"
+    else f"$m%02d:$s%02d"
+  }
+
+private val UDATA = Seq("kB", "MB", "GB", "PB", "EB");
+def formatBytes(n: Long): String = {
+  val (x, u) = (n.toDouble, "B ") /: UDATA {
+    case ((x, u), name) if x >= 1024.0 => (x/1024.0, name)
+    case (xu, _) => xu
+  }
+  f"$x%6.1f$u%s"
+}
+
+trait Eyecandy {
+  def set(line: String);
+  def clear();
+  def commit();
+  def commit(line: String) { commit(); set(line); commit(); }
+
+  def begin(job: Job);
+}
+
+
+trait Job with Publisher[ {
+  def what: String;                    // imperative for what we're doing
+  def cur: Long;                       // current position in work
+  def max: Long;                       // maximum work to do
+  def format: String;                  // describe progress in useful terms
+
+  private[this] val t0 = currentTimeMillis;
+
+  def eta: Int =
+    /* Report the estimated time remaining in seconds, or -1 if no idea.
+     *
+     * The model here is very stupid.  Weird jobs should override this and do
+     * something more sensible.
+     */
+
+    if (max < 0 || cur <= 0) -1
+    else ceil((currentTimeMillis - t0)/1000.0 *
+             (max - cur)/cur.toDouble).toInt;
+}
+
+object TerminalEyecandy extends Eyecandy {
+  private var last = "";
+  var eyecandyp = 
+  
+}
+
+/*----- That's all, folks -------------------------------------------------*/