ifdef NotifyingPrintLog static volatile new NotifyingStringBuffer local_log; // not redirected svoid _onLoad_print() { // doesn't work yet? print_autoRotate(); } endifdef ifndef NotifyingPrintLog static volatile new StringBuffer local_log; // not redirected endifndef static volatile Appendable print_log = local_log; // might be redirected, e.g. to main bot // in bytes - will cut to half that static volatile int print_log_max = 1024*1024; static volatile int local_log_max = 100*1024; static boolean print_silent; // total mute if set static new O print_byThread_lock; static volatile ThreadLocal print_byThread; // special handling by thread - prefers F1 static volatile O print_allThreads; static volatile O print_preprocess; static void print() { print(""); } static A print(S s, A o) { print((endsWithLetterOrDigit(s) ? s + ": " : s) + o); ret o; } // slightly overblown signature to return original object... static A print(A o) { ping_okInCleanUp(); if (print_silent) return o; String s = String.valueOf(o) + "\n"; print_noNewLine(s); return o; } static void print_noNewLine(String s) { ifndef LeanMode O f = getThreadLocal(print_byThread_dontCreate()); if (f == null) f = print_allThreads; if (f != null) // We do need the general callF machinery here as print_byThread is sometimes shared between modules if (isFalse( ifclass F1 f instanceof F1 ? f/F1.get(s) : endif callF(f, s))) ret; endifndef print_raw(s); } static void print_raw(String s) { ifndef LeanMode if (print_preprocess != null) s = (S) callF(print_preprocess, s); s = fixNewLines(s); endifndef Appendable loc = local_log; Appendable buf = print_log; int loc_max = print_log_max; if (buf != loc && buf != null) { print_append(buf, s, print_log_max); loc_max = local_log_max; } if (loc != null) print_append(loc, s, loc_max); System.out.print(s); } svoid print_autoRotate() { ifdef NotifyingPrintLog makeNotifyingStringBufferRotate(local_log, () -> local_log_max); endifdef }