!7 sclass SimpleSnippetSearch extends DynModule { S query; L result; transient Q q; transient int maxInputLength = 120; transient WaitForStableValue waitForStableValue = new(1.0); transient volatile bool calculating; transient JTable table; transient ReliableSingleThread rst; transient SimpleLiveValue lvQuery = stringLiveValue(); JComponent visualize() { ret jLiveValueSection(lvQuery, dataToTable_uneditable(result, table = sexyTable())); } void unvisualize2() { table = null; } void start { lvQuery.set(query); q = startQ(); ownTimer(doEvery(500, r update)); } void update { lock programLock(); S s = dm_getInterestingString(); if (nempty(s) && l(s) <= maxInputLength) waitForStableValue.set(s); fS q = waitForStableValue!; if (nempty(q) && neq(q, query) && allowedToSearch()) this.q.add(r { calc(q) }); } void calc(S q) { if (eq(query, q)) ret; query = q; result = null; lvQuery.set(q); calculating = true; try { L l = tbSearch(q); result = map(l, func(Snippet s) -> SS { litorderedmap("ID + Title" := snippetWithTitle(s), "Type" := snippetTypeName(s.type)) }); JTable t = table; if (t != null) dataToTable_uneditable(result, t); } finally { calculating = false; } } bool allowedToSearch() { true; } }