using Toybox.Application.Properties; using Toybox.Graphics as Gfx; using Toybox.Math; using Toybox.System as Sys; using Toybox.Time; using Toybox.Time.Gregorian; import Toybox.Lang; import Toybox.StringUtil; import Toybox.WatchUi; (:glance) module L { // // What string to create from an epoch second // public const TS_HOUR = 0x1; public const TS_MIN = 0x2; public const TS_SEC = 0x4; public const TS_HMS = TS_HOUR | TS_MIN | TS_SEC; public const TS_MS = TS_MIN | TS_SEC; // // Debug levels // public const DBG_NONE = 0x00; public const DBG_BASIC = 0x01; public const DBG_ALL = 0xff; const LOG_SIZE = 64; var log_buf as Array = new [LOG_SIZE]; var log_size = LOG_SIZE; var log_next = 0; var log_full = false; // // Debug mode // (:debug) var debug = DBG_BASIC; (:release) var debug = DBG_NONE; public function clear() { log_next = 0; log_full = false; log_buf = new [LOG_SIZE]; } public function max() { return log_full ? log_size : log_next; } public function get(idx) { if (log_full) { idx += log_next; if (idx >= log_size) { idx -= log_size; } } return log_buf[idx]; } public function put(str) { log_buf[log_next] = str; log_next += 1; if (log_next >= log_size) { log_next = 0; log_full = true; } } public function ts2str(now, show) { var tinf = Gregorian.info(new Time.Moment(now), Time.FORMAT_SHORT); var pre = ""; var r = ""; if ((show & TS_HOUR) != 0) { r += pre + tinf.hour; pre = ":"; } if ((show & TS_MIN) != 0) { r += pre + tinf.min.format("%02d"); pre = ":"; } if ((show & TS_SEC) != 0) { r += pre + tinf.sec.format("%02d"); } return r; } public function log_lvl(lvl, s) { if ((lvl & debug) != 0) { Sys.println("DDD(" + ts2str(Time.now().value(), TS_MS) + ") " + s); } put(s); } public function log(s) { log_lvl(DBG_BASIC, s); } public function pr_memory(pre, suf) { var total, used, free; var scale; if (suf == null) { suf = 'u'; } switch (suf) { case 'k': case 'K': scale = 1000; break; case 'm': case 'M': scale = 1000*1000; break; case 'g': case 'G': scale = 1000*1000*1000; break; default: scale = 1; suf = ""; break; } var stats = Sys.getSystemStats(); total = stats.totalMemory / scale; used = stats.usedMemory / scale; free = stats.freeMemory / scale; log_lvl(DBG_BASIC, pre + ":" + total + suf + "=" + used + suf + "+" + free + suf); } public function pr_mem(pre) { pr_memory(pre, 'k'); } function compareTo(s1, s2) { var n; var b1 = s1.toUtf8Array() as Array; var l1 = b1.size(); var b2 = s2.toUtf8Array() as Array; var l2 = b2.size(); var len = (l1 < l2) ? l1 : l2; for (var i = 0; i < len; i += 1) { n = b2[i] - b1[i]; if (n != 0) { return n; } } if (l1 == l2) { return 0; } else if (l1 < l2) { return 1; } else { return -1; } } // // Simple bubble sort of an list of Strings // function sort(list as Array) { var tmp; for (var i = 0; i < list.size() - 1; i += 1) { for (var j = i + 1; j < list.size(); j += 1) { if (compareTo(list[i], list[j]) < 0) { tmp = list[i]; list[i] = list[j]; list[j] = tmp; } } } } function dict2str(d as Lang.Dictionary, pretty) { var r; var pre = ""; r = pretty ? "\n " : ""; var keys = d.keys(); sort(keys); for (var i = 0; i < keys.size(); i++) { r += pre + keys[i] + "=>" + d[keys[i]]; pre = pretty ? ",\n " : ","; } return r; } function pr_obj(txt, obj) { var r; if (obj instanceof Number) { r = "Number"; } else if (obj instanceof Long) { r = "Long"; } else if (obj instanceof Float) { r = "Float"; } else if (obj instanceof Double) { r = "Double"; } else if (obj instanceof Boolean) { r = "Boolean"; } else if (obj instanceof String) { r = "String"; } else if (obj instanceof Array) { r = "Array(" + obj.size() + ")"; } else if (obj instanceof Dictionary) { r = dict2str(obj as Dictionary, true); } else if (obj == null) { r = "null"; } else { r = "?"; } log_lvl(DBG_BASIC, txt + r); } }