Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

372
LINES

< > BotCompany Repo | #1003886 // Random Main (v8)

JavaX fragment (include)

1  
static S generatorsID;
2  
3  
static JTable table, chatTable;
4  
static JTextArea chat;
5  
static JTextField input;
6  
static L<S> log = synchroList();
7  
static L<S> recommendations;
8  
static L<Thread> thinkThreads = synchroList();
9  
static JLabel status;
10  
11  
static int listDelay = 2000;
12  
static int maxLineLength = 1000;
13  
static int maxLongStringLength = 100*1000;
14  
15  
static Bool thinking;
16  
static new Thinker thinker;
17  
18  
static S systemPrefix = "[system]";
19  
20  
static S dialog = "new";
21  
22  
svoid randomMain {
23  
  //substanceLAF("EmeraldDusk"); // Too dark!
24  
  substanceLAF("ChallengerDeep");
25  
26  
  table = tableWithTooltips();
27  
  chat = autoScroll(wordWrapTextArea());
28  
  chatTable = tableWithTooltips();
29  
  input = new JTextField;
30  
  status = new JLabel(" ");
31  
  
32  
  JFrame frame = showFrame(vgrid(centerAndSouth(
33  
    jtabs(1, "Chat", chat, "Details", chatTable),
34  
    input), centerAndSouth(table, status)));
35  
  //setFrameIconLater(frame, "#1003593");
36  
  
37  
  onEnter(input, r {
38  
    post();
39  
  });
40  
  
41  
  onDoubleClick(table, voidfunc(int row) {
42  
    chooseSuggestion(row);
43  
  });
44  
  
45  
  for (int i = 1; i <= 12; i++) {
46  
    final int _i = i;
47  
    registerFunctionKey(frame, i, r {
48  
      chooseSuggestionForEditing(_i-1);
49  
    });
50  
    registerShiftFunctionKey(frame, i, r {
51  
      chooseSuggestion(_i-1);
52  
    });
53  
  }
54  
  
55  
  onUpdate(input, r { updateOnce(); });
56  
  
57  
  loadDialog();
58  
  logEvent("Starting");
59  
  
60  
  updateOnce();
61  
  
62  
  input.requestFocus();
63  
  
64  
  if (isAction(last(log)) && confirmYesNo(input, "Run action? " + last(log)))
65  
    action(last(log));
66  
}
67  
68  
static S getInput() {
69  
  ret joinLines(" # ", input.getText().trim());
70  
}
71  
72  
sv post() {
73  
  postAsUser(getInput(), null);
74  
}
75  
76  
static void postAsUser(S i, Map infos) {
77  
  if (inputAllowedByUser(i))
78  
    post(i, infos);
79  
}
80  
81  
svoid chooseSuggestionForEditing(int row) {
82  
  Map<S, S> map = getTableLineAsMap(table, row);
83  
  if (map == null) ret;
84  
  rankToTop(map);
85  
  S s = trim(unnull(map.get("Suggestion")));
86  
  logEvent("Suggestion chosen for editing", mapPlus(map, "Row", row+1, "Input", getInput(), "Top Suggesters", topSuggesters()));
87  
  input.setText(s);
88  
  input.selectAll();
89  
  input.requestFocus();
90  
}
91  
92  
svoid rankToTop(Map map) {
93  
  // Table cells have been structure'd by dataToTable
94  
  thinker.rankToTop(first((L<S>) unstructure(getString(map, "Suggesters"))));
95  
}
96  
97  
svoid chooseSuggestion(int row) {
98  
  Map<S, S> map = getTableLineAsMap(table, row);
99  
  if (map == null) ret;
100  
  rankToTop(map);
101  
  S s = trim(unnull(map.get("Suggestion")));
102  
  if (empty(s)) ret;
103  
104  
  //logEvent("Suggestion chosen", mapPlus(map, "Row", row+1, "Input", getInput(), "Top Suggesters", topSuggesters));
105  
  input.setText(s);
106  
  postAsUser(s, mapPlus(map, "Index", row+1));
107  
}
108  
109  
static L topSuggesters() {
110  
  int n = 20;
111  
  n = min(n, tableRows(table));
112  
  new L topSuggesters;
113  
  for (int i = 0; i < n; i++)
114  
    topSuggesters.add(getTableLineAsMap(table, i));
115  
  //if (empty(topSuggesters)) topSuggesters = null;
116  
  ret topSuggesters;
117  
}
118  
119  
svoid logEvent(S type) {
120  
  logEvent(type, litmap());
121  
}
122  
123  
svoid logEvent(S type, Map map) {
124  
  logStructure(new File(dialogDir(), "event.log"),
125  
    ll(type, chatTime(), map));
126  
}
127  
128  
static bool inputAllowedByUser(S i) {
129  
  ret !swic(i, systemPrefix);
130  
}
131  
132  
// may be called from other thread
133  
static void postSystemMessage(final S msg) {
134  
  if (empty(msg)) ret;
135  
  awtIfNecessary {
136  
    post(systemPrefix + " " + msg, litmap("By", "System"));
137  
  }
138  
}
139  
140  
static void post(S i, Map infos) {
141  
  try {
142  
    i = trim(i);
143  
    if (empty(i)) ret;
144  
    //i = escapeNewLines(i);
145  
    infos = mapPlus(infos, "Top Suggesters", topSuggesters());
146  
    
147  
    bool tooLong = l(i) > maxLongStringLength;
148  
    
149  
    if (l(i) > maxLineLength) {
150  
      S id = saveLongString(i);
151  
      i = substring(i, 0, maxLineLength) + "... [" + (tooLong ? "too " : "") + "long text " + id + "]";
152  
    }
153  
  } catch e {
154  
    printStackTrace(e);
155  
    i = systemPrefix + " " + exceptionToStringShort(e);
156  
  }
157  
  
158  
  S s = i + "\n";
159  
  chat.append(escapeNewLines(i) + "\n");
160  
  appendToFile(logFile(), "[" + chatTime() + "] " + s);
161  
  logEvent("Posting", litmap("Text", i, "Infos", infos));
162  
  log.add(i);
163  
  updateChatTable();
164  
  input.selectAll();
165  
  updateOnce();
166  
  try {
167  
    action(i);
168  
  } catch e {
169  
    printStackTrace(e);
170  
    postSystemMessage(exceptionToStringShort(e));
171  
  }
172  
}
173  
174  
static S dropActionPrefix(S s) {
175  
  if (s == null) null;
176  
  s = dropBracketPrefix(s); // e.g. "[bot]"
177  
  if (!s.startsWith("!")) null;
178  
  ret s.substring(1);
179  
}
180  
181  
static bool isAction(S s) {
182  
  ret dropActionPrefix(s) != null;
183  
}
184  
185  
static void action(S s) {
186  
  s = dropActionPrefix(s);
187  
  if (s == null) ret;
188  
189  
  final S _s = s;
190  
  thread "Action" {
191  
    loading {
192  
      try {
193  
        genLog_set(getLog()); // 'case user needs it
194  
        randomsOwnCmds(_s);
195  
        actionImpl(_s); // user must provide this
196  
      } catch e {
197  
        printStackTrace(e);
198  
        postSystemMessage("Error - " + exceptionToStringShort(e));
199  
      }
200  
    }
201  
  }
202  
}
203  
204  
static volatile bool again;
205  
206  
// This logic is bad...
207  
static void fillList(bool force) {
208  
  bool t = force || shouldUpdateList();
209  
  if (neq(t, thinking)) {
210  
    thinking = t;
211  
    setFrameIcon(table, t ? "#1003603" : "#1003593");
212  
  }
213  
  
214  
  if (!t) {
215  
    if (!force)
216  
      againl8r();
217  
  } else {
218  
    if (nempty(thinkThreads)) { again = true; ret; }
219  
    fillListImpl();
220  
  }
221  
}
222  
223  
static void fillListImpl() {
224  
  thread "Fill List" {
225  
    try {
226  
      thinkThreads.add(currentThread());
227  
      final new L<S> data;
228  
      thinker.makeListData(cloneList(log), getInput(), data);
229  
      
230  
      awt {
231  
        pcall {
232  
          dataToTable_uneditable(table, data);
233  
          tableColumnMaxWidth(table, 0, 30); // "Key" column
234  
        }
235  
        againl8r();
236  
      }
237  
    } finally {
238  
      thinkThreads.remove(currentThread());
239  
    if (again) { again = false; fillListImpl(); }
240  
    }
241  
  }
242  
}
243  
244  
static void updateOnce() { fillList(true); }
245  
246  
static void againl8r() {
247  
  swingAfter(table, listDelay, r { fillList(false); });
248  
}
249  
250  
static bool shouldUpdateList() {
251  
  bool result = false;
252  
  S text = " ";
253  
  if (getFrame(table).isFocused()) {
254  
    result = !mouseInComponent(table);
255  
    text = result ? " Thinking... "
256  
      : "Not thinking cause you got the mouse in there";
257  
  }
258  
  status.setText(text);
259  
  ret result;
260  
}
261  
262  
// also called from outside
263  
static L<S> loadLog() {
264  
  log.clear();
265  
  log.addAll(collect(scanEventLogForPosts(dialogDir()), "text"));
266  
  ret log;
267  
}
268  
269  
synchronized static L<S> getLastFromLog(int n) {
270  
  ret cloneList(getLast(log, n));
271  
}
272  
273  
synchronized static L<S> getLog() {
274  
  ret cloneList(log);
275  
}
276  
277  
static File dialogDir() {
278  
  ret prepareProgramFile(dialog);
279  
}
280  
281  
static File logFile() {
282  
  ret new File(dialogDir(), "log.txt");
283  
}
284  
285  
static void switchDialog(final S name) {
286  
  swingAndWait(r {
287  
    dialog = name;
288  
    loadDialog();
289  
  });
290  
}
291  
292  
static void loadDialog() {
293  
  loadLog();
294  
  thinker = new Thinker;
295  
  thinker.startUp(log);
296  
  chat.setText(joinLines(log));
297  
  updateChatTable();
298  
}
299  
300  
static void randomsOwnCmds(S s) {
301  
  new Matches m;
302  
  if "dialog *" {
303  
    switchDialog(m.unq(0));
304  
    // TODO: show current dialog somewhere else
305  
    //postSystemMessage("OK, dialog switched to " + quote(dialog));
306  
  }
307  
  
308  
  if "gen"
309  
    generators = null;
310  
  
311  
  if "delete"
312  
    updateChatTable();
313  
}
314  
315  
static void updateChatTable() {
316  
  assertAWT();
317  
  new L data;
318  
  L<L> l = scanLog_safeUnstructure(new File(dialogDir(), "event.log"));
319  
  for (int i = 0; i < l(l); i++) pcall {
320  
    L a = l.get(i), prev = get(l, i-1);
321  
    if (firstIs(a, "Posting")) {
322  
      Map map = cast get(a, 2);
323  
      S text = getString(map, "Text").trim();
324  
      if (eq(text, "!delete")) { removeLast(data); continue; }
325  
      S idx = "";
326  
      Map infos = cast map.get("Infos");
327  
      if (infos != null && infos.containsKey("Index"))
328  
        idx = str(infos.get("Index"));
329  
      else pcall {
330  
        //printStruct("prev: ", prev);
331  
        if (prev != null && firstIs(prev, "Suggestion chosen for editing")) {
332  
          Map m = getMap(prev, 2);
333  
          S suggestion = getString(m, "Suggestion");
334  
          //print("Suggestion: " + structure(suggestion));
335  
          idx = str(get(m, "Row"));
336  
          if (neq(suggestion, text))
337  
            idx += "?";
338  
        }
339  
      }
340  
      data.add(litorderedmap("Text", escapeNewLines(text), "SI" /* Suggestion Index */, idx));
341  
    }
342  
  }
343  
  dataToTable_uneditable(chatTable, data);
344  
  tableColumnMaxWidth(chatTable, 1, 40); // enough for 2 digits and a "?"
345  
  scrollTableDown(chatTable);
346  
}
347  
348  
static synchronized S saveLongString(S s) {
349  
  s = substring(s, 0, maxLongStringLength);
350  
  S id;
351  
  File f;
352  
  do {
353  
    id = randomID(10);
354  
    f = getProgramFile("long-strings/" + id);
355  
  } while (f.exists());
356  
  
357  
  saveTextFile(f, s);
358  
  ret id;
359  
}
360  
361  
static O generators;
362  
363  
static void makeGenerators(L<Gen> l, L<S> log) {
364  
  synchronized(main.class) {
365  
    if (!isSnippetID(generatorsID)) fail("No generators ID set");
366  
    if (generators == null)
367  
      generators = hotwire(generatorsID);
368  
  }
369  
  new L l2;
370  
  call(generators, "makeGenerators", l2, log);
371  
  l.addAll((L) quickImport(l2));
372  
}

Author comment

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: 744 / 895
Referenced in: [show references]