static S generatorsID;
static JTable table, chatTable;
static JTextArea chat;
static JTextField input;
static L<S> log = synchroList();
static L<S> recommendations;
static L<Thread> thinkThreads = synchroList();
static JLabel status;
static int listDelay = 2000;
static int maxLineLength = 1000;
static int maxLongStringLength = 100*1000;
static Bool thinking;
static new Thinker thinker;
static S systemPrefix = "[system]";
static S dialog = "new";
svoid randomMain {
//substanceLAF("EmeraldDusk"); // Too dark!
substanceLAF("ChallengerDeep");
table = tableWithTooltips();
chat = autoScroll(wordWrapTextArea());
chatTable = tableWithTooltips();
input = new JTextField;
status = new JLabel(" ");
JFrame frame = showFrame(vgrid(centerAndSouth(
jtabs(1, "Chat", chat, "Details", chatTable),
input), centerAndSouth(table, status)));
//setFrameIconLater(frame, "#1003593");
onEnter(input, r {
post();
});
onDoubleClick(table, voidfunc(int row) {
chooseSuggestion(row);
});
for (int i = 1; i <= 12; i++) {
final int _i = i;
registerFunctionKey(frame, i, r {
chooseSuggestionForEditing(_i-1);
});
registerShiftFunctionKey(frame, i, r {
chooseSuggestion(_i-1);
});
}
onUpdate(input, r { updateOnce(); });
loadDialog();
logEvent("Starting");
updateOnce();
input.requestFocus();
if (isAction(last(log)) && confirmYesNo(input, "Run action? " + last(log)))
action(last(log));
}
static S getInput() {
ret joinLines(" # ", input.getText().trim());
}
sv post() {
postAsUser(getInput(), null);
}
static void postAsUser(S i, Map infos) {
if (inputAllowedByUser(i))
post(i, infos);
}
svoid chooseSuggestionForEditing(int row) {
Map<S, S> map = getTableLineAsMap(table, row);
if (map == null) ret;
rankToTop(map);
S s = trim(unnull(map.get("Suggestion")));
logEvent("Suggestion chosen for editing", mapPlus(map, "Row", row+1, "Input", getInput(), "Top Suggesters", topSuggesters()));
input.setText(s);
input.selectAll();
input.requestFocus();
}
svoid rankToTop(Map map) {
// Table cells have been structure'd by dataToTable
thinker.rankToTop(first((L<S>) unstructure(getString(map, "Suggesters"))));
}
svoid chooseSuggestion(int row) {
Map<S, S> map = getTableLineAsMap(table, row);
if (map == null) ret;
rankToTop(map);
S s = trim(unnull(map.get("Suggestion")));
if (empty(s)) ret;
//logEvent("Suggestion chosen", mapPlus(map, "Row", row+1, "Input", getInput(), "Top Suggesters", topSuggesters));
input.setText(s);
postAsUser(s, mapPlus(map, "Index", row+1));
}
static L topSuggesters() {
int n = 20;
n = min(n, tableRows(table));
new L topSuggesters;
for (int i = 0; i < n; i++)
topSuggesters.add(getTableLineAsMap(table, i));
//if (empty(topSuggesters)) topSuggesters = null;
ret topSuggesters;
}
svoid logEvent(S type) {
logEvent(type, litmap());
}
svoid logEvent(S type, Map map) {
logStructure(new File(dialogDir(), "event.log"),
ll(type, chatTime(), map));
}
static bool inputAllowedByUser(S i) {
ret !swic(i, systemPrefix);
}
// may be called from other thread
static void postSystemMessage(final S msg) {
if (empty(msg)) ret;
awtIfNecessary {
post(systemPrefix + " " + msg, litmap("By", "System"));
}
}
static void post(S i, Map infos) {
try {
i = trim(i);
if (empty(i)) ret;
//i = escapeNewLines(i);
infos = mapPlus(infos, "Top Suggesters", topSuggesters());
bool tooLong = l(i) > maxLongStringLength;
if (l(i) > maxLineLength) {
S id = saveLongString(i);
i = substring(i, 0, maxLineLength) + "... [" + (tooLong ? "too " : "") + "long text " + id + "]";
}
} catch e {
printStackTrace(e);
i = systemPrefix + " " + exceptionToStringShort(e);
}
S s = i + "\n";
chat.append(escapeNewLines(i) + "\n");
appendToFile(logFile(), "[" + chatTime() + "] " + s);
logEvent("Posting", litmap("Text", i, "Infos", infos));
log.add(i);
updateChatTable();
input.selectAll();
updateOnce();
try {
action(i);
} catch e {
printStackTrace(e);
postSystemMessage(exceptionToStringShort(e));
}
}
static S dropActionPrefix(S s) {
if (s == null) null;
s = dropBracketPrefix(s); // e.g. "[bot]"
if (!s.startsWith("!")) null;
ret s.substring(1);
}
static bool isAction(S s) {
ret dropActionPrefix(s) != null;
}
static void action(S s) {
s = dropActionPrefix(s);
if (s == null) ret;
final S _s = s;
thread "Action" {
loading {
try {
genLog_set(getLog()); // 'case user needs it
randomsOwnCmds(_s);
actionImpl(_s); // user must provide this
} catch e {
printStackTrace(e);
postSystemMessage("Error - " + exceptionToStringShort(e));
}
}
}
}
static volatile bool again;
// This logic is bad...
static void fillList(bool force) {
bool t = force || shouldUpdateList();
if (neq(t, thinking)) {
thinking = t;
setFrameIcon(table, t ? "#1003603" : "#1003593");
}
if (!t) {
if (!force)
againl8r();
} else {
if (nempty(thinkThreads)) { again = true; ret; }
fillListImpl();
}
}
static void fillListImpl() {
thread "Fill List" {
try {
thinkThreads.add(currentThread());
final new L<S> data;
thinker.makeListData(cloneList(log), getInput(), data);
awt {
pcall {
dataToTable_uneditable(table, data);
tableColumnMaxWidth(table, 0, 30); // "Key" column
}
againl8r();
}
} finally {
thinkThreads.remove(currentThread());
if (again) { again = false; fillListImpl(); }
}
}
}
static void updateOnce() { fillList(true); }
static void againl8r() {
swingAfter(table, listDelay, r { fillList(false); });
}
static bool shouldUpdateList() {
bool result = false;
S text = " ";
if (getFrame(table).isFocused()) {
result = !mouseInComponent(table);
text = result ? " Thinking... "
: "Not thinking cause you got the mouse in there";
}
status.setText(text);
ret result;
}
// also called from outside
static L<S> loadLog() {
log.clear();
log.addAll(collect(scanEventLogForPosts(dialogDir()), "text"));
ret log;
}
synchronized static L<S> getLastFromLog(int n) {
ret cloneList(getLast(log, n));
}
synchronized static L<S> getLog() {
ret cloneList(log);
}
static File dialogDir() {
ret prepareProgramFile(dialog);
}
static File logFile() {
ret new File(dialogDir(), "log.txt");
}
static void switchDialog(final S name) {
swingAndWait(r {
dialog = name;
loadDialog();
});
}
static void loadDialog() {
loadLog();
thinker = new Thinker;
thinker.startUp(log);
chat.setText(joinLines(log));
updateChatTable();
}
static void randomsOwnCmds(S s) {
new Matches m;
if "dialog *" {
switchDialog(m.unq(0));
// TODO: show current dialog somewhere else
//postSystemMessage("OK, dialog switched to " + quote(dialog));
}
if "gen"
generators = null;
if "delete"
updateChatTable();
}
static void updateChatTable() {
assertAWT();
new L data;
L<L> l = scanLog_safeUnstructure(new File(dialogDir(), "event.log"));
for (int i = 0; i < l(l); i++) pcall {
L a = l.get(i), prev = get(l, i-1);
if (firstIs(a, "Posting")) {
Map map = cast get(a, 2);
S text = getString(map, "Text").trim();
if (eq(text, "!delete")) { removeLast(data); continue; }
S idx = "";
Map infos = cast map.get("Infos");
if (infos != null && infos.containsKey("Index"))
idx = str(infos.get("Index"));
else pcall {
//printStruct("prev: ", prev);
if (prev != null && firstIs(prev, "Suggestion chosen for editing")) {
Map m = getMap(prev, 2);
S suggestion = getString(m, "Suggestion");
//print("Suggestion: " + structure(suggestion));
idx = str(get(m, "Row"));
if (neq(suggestion, text))
idx += "?";
}
}
data.add(litorderedmap("Text", escapeNewLines(text), "SI" /* Suggestion Index */, idx));
}
}
dataToTable_uneditable(chatTable, data);
tableColumnMaxWidth(chatTable, 1, 40); // enough for 2 digits and a "?"
scrollTableDown(chatTable);
}
static synchronized S saveLongString(S s) {
s = substring(s, 0, maxLongStringLength);
S id;
File f;
do {
id = randomID(10);
f = getProgramFile("long-strings/" + id);
} while (f.exists());
saveTextFile(f, s);
ret id;
}
static O generators;
static void makeGenerators(L<Gen> l, L<S> log) {
synchronized(main.class) {
if (!isSnippetID(generatorsID)) fail("No generators ID set");
if (generators == null)
generators = hotwire(generatorsID);
}
new L l2;
call(generators, "makeGenerators", l2, log);
l.addAll((L) quickImport(l2));
}
Began life as a copy of #1003813
download show line numbers debug dex old transpilations
Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
| Snippet ID: | #1003886 |
| Snippet name: | Random Main (v8) |
| Eternal ID of this version: | #1003886/1 |
| Text MD5: | d3d0c7e391bfd4326bf51a6c9bc744a4 |
| Author: | stefan |
| Category: | javax / talking robots |
| Type: | JavaX fragment (include) |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2016-08-04 14:02:14 |
| Source code size: | 9213 bytes / 372 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 1196 / 1327 |
| Referenced in: | #1003887 - "Random" v8 #1004031 - Random Main v9 |