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

434
LINES

< > BotCompany Repo | #1033540 // GazelleHost + Stem

JavaX fragment (include) [tags: use-pretranspiled]

1  
lib 1400521 // FlatLAF
2  
3  
set flag PingV3.
4  
set flag NotifyingPrintLog.
5  
set flag SymbolAsString.
6  
7  
// Do the JavaX init
8  
svoid standaloneInit {
9  
  __javax = x30.class;
10  
  x30.__javax = x30.class; // for hotwire
11  
  x30_pkg.x30_util.__setJavaX(x30.class);
12  
  x30.cleanKillMsg = "";
13  
  callOnLoadMethods(mc());
14  
}
15  
16  
concept PrintLogModule > DynPrintLog {
17  
  *() { setModuleName("Print Log"); }
18  
  
19  
  S getPrintLog() {
20  
    ret printLog();
21  
  }
22  
  
23  
  bool useErrorHandling() { false; }
24  
}
25  
26  
concept Stem {
27  
  transient GazelleHost host;
28  
  DynModule module;
29  
  Rect frameRect;
30  
  bool maximized, alwaysOnTop, autoUpdate;
31  
  
32  
  transient JFrame window;
33  
  transient JButton btnMax;
34  
  
35  
  *() {}
36  
  *(GazelleHost *host) {}
37  
  *(GazelleHost *host, DynModule *module) {}
38  
  
39  
  Rect getFrameRect() {
40  
    ret toRect(getBounds(window));
41  
  }
42  
  
43  
  void saveFrameRect {
44  
    setField(frameRect := getFrameRect());
45  
  }
46  
  
47  
  void setAlwaysOnTop(bool alwaysOnTop) {
48  
    this.alwaysOnTop = alwaysOnTop;
49  
    change();
50  
    alwaysOnTop(window, alwaysOnTop);
51  
  }
52  
53  
  void setWindow(JFrame window) {  
54  
    this.window = window;
55  
    if (frameRect != null)  
56  
      setBounds(window, frameRect);
57  
    //onWindowClosing(window, -> host.cleanExit());
58  
    onBoundsChange(window, r saveFrameRect);
59  
    alwaysOnTop(window, alwaysOnTop);
60  
  }
61  
  
62  
  bool isMain() { ret this == host.stem; }
63  
  
64  
  void minimize {
65  
    if (host.trayIcon == null || !isMain())
66  
      minimizeWindow(window);
67  
    else
68  
      hideWindow(window);
69  
  }
70  
  
71  
  void deleteMe {
72  
    printAlsoToSystemOut = true;
73  
    print("deleteMe " + isMain());
74  
    if (isMain()) {
75  
      host.cleanExit();
76  
    } else {
77  
      disposeWindow(window);
78  
      dispose module;
79  
      cdelete(this);
80  
    }
81  
  }
82  
  
83  
  void grabWindowState {
84  
    setField(maximized := !isExtendedStateNormal(window));
85  
  }
86  
  
87  
  void updateBtnMax {
88  
    if (!isShowing(btnMax)) ret;
89  
    grabWindowState();
90  
    setText(btnMax, maximized ? "NORM" : "MAX");
91  
  }
92  
  
93  
  JComponent makeWindowBorderAndTitle(JComponent contents, S title) {
94  
    //ret jCenteredSection_fontSizePlus(10, title, vis);
95  
    
96  
    var icons = jline();
97  
    if (host.allowFrameMaximization) {
98  
      icons.add(btnMax = jbutton("", rThread {
99  
        maximizeOrRestoreFrame(window);
100  
        updateBtnMax();
101  
      }));
102  
      onFirstShowing(btnMax, r updateBtnMax);
103  
    }
104  
    
105  
    icons.add(jbutton("MIN", r minimize));
106  
    icons.add(jbutton("QUIT", rThread {
107  
      if (swingConfirm("Really quit Gazelle?"))
108  
        deleteMe();
109  
    }));
110  
    setHorizontalMarginForAllButtons(icons, 4);
111  
    icons.add(jPopDownButton_noText(flattenToList(
112  
      // restart + update
113  
      
114  
      !isMain() ? null : ll(
115  
        "Restart", rThread { host.restart() },
116  
        "Update Gazelle", rThread { host.upgradeGazelle() },
117  
      jCheckBoxMenuItem_dyn("Auto-Update",
118  
        -> autoUpdate,
119  
        b -> cset(Stem.this, autoUpdate := b)),
120  
      ),
121  
        
122  
      // always on top
123  
      
124  
      "---",
125  
      jCheckBoxMenuItem_dyn("Always on top",
126  
        -> alwaysOnTop,
127  
        alwaysOnTop -> setAlwaysOnTop(alwaysOnTop)),
128  
        
129  
      // debugging + screenshooting gazelle
130  
      
131  
      "---",
132  
      !isMain() ? null : ll(
133  
        "Screenshoot this window", rThread shootWindow,
134  
        "Dump threads", rThread { showText("User threads", renderUserThreadsWithStackTraces()); },
135  
        !isMain() ? null : "Print log", !isMain() ? null : rThread { host.showPrintLog() },
136  
      ),
137  
      
138  
      ccallOpt(module, "popDownItems")
139  
    )));
140  
    
141  
    var actualTitle = fontSizePlus(7, jCenteredLabel(title));
142  
    var spacer = gazelle_wavySpacer();
143  
    var titleBarMain = setOpaqueBackground(host.color1,
144  
      westCenterAndEastWithMargin(
145  
        jImage_scaledToHeight(24, host.trayIconImageID),
146  
        actualTitle,
147  
        setOpaqueBackground(host.color2, spacer));
148  
    
149  
    installWindowDragger(actualTitle);
150  
    installWindowDragger(spacer);
151  
    
152  
    var titleBar = setBackground(host.color2, centerAndEast(
153  
      titleBarMain,
154  
      icons));
155  
    
156  
    var border =
157  
      // createBevelBorder();
158  
      BorderFactory.createLineBorder(host.color1, host.borderSize);
159  
      
160  
    var outerPanel = withBorder(border,
161  
      northAndCenter(titleBar, contents));
162  
      
163  
    installWindowResizeDraggerOnBorder(outerPanel);
164  
    ret outerPanel;
165  
  }
166  
167  
  void startAndShow() {
168  
    module._host = this;
169  
    setOpt_raw(module, +threadPool); // only if the field exists
170  
    setOpt_raw(module, concepts := host.concepts);
171  
    copyLocalLog(module, mc());
172  
  
173  
    var vis, title = unpair makeVisAndTitle();
174  
    printWithMS("Show frame");
175  
176  
    JFrame frame = makeUndecoratedFrame(title, vis);
177  
    setFrameIcon(frame, host.trayIconImageID);
178  
    setWindow(frame);
179  
    showWindow(window);
180  
    if (maximized && host.allowFrameMaximization) maximizeFrame(window);
181  
  }
182  
  
183  
  Pair<JComponent, S> makeVisAndTitle() {
184  
    JComponent vis;
185  
    {
186  
      temp module.enter();
187  
      module.start();
188  
    
189  
      printWithMS("Visualize");
190  
      vis = swing(-> {
191  
        temp module.enter();
192  
        ret module.visualize();
193  
      });
194  
    }
195  
    
196  
    S title = host.windowTitle;
197  
    if (!isMain()) title += appendWithColon(module.moduleName());
198  
    vis = makeWindowBorderAndTitle(vis, title);
199  
    ret pair(vis, title);
200  
  }
201  
  
202  
  void revisualize {
203  
    if (window == null) ret;
204  
    
205  
    pcall {
206  
      module.unvisualize();
207  
    }
208  
    
209  
    var vis, title = unpair makeVisAndTitle();
210  
    setFrameContents(window, vis);
211  
  }
212  
  
213  
  void shootWindow {
214  
    var img = renderComponentToImage(window);
215  
    copyImageToClipboard(img);
216  
    saveInImageDirectoryWithCounter("Gazelle/Gazelle", img);
217  
  }
218  
} // end of Stem
219  
220  
// This replaces the Stefan's OS main class. It is not persisted
221  
transient sclass GazelleHost {
222  
  Stem stem;
223  
  DynModule gazelle;
224  
  
225  
  transient S windowTitle = "November Gazelle v1";
226  
  transient S trayIconImageID = #1103047;
227  
  transient int borderSize = 5;
228  
  transient Color color1 = awtColor("ADD8E6");
229  
  transient Color color2 = awtColor("EEEEEE");
230  
  transient Color color3 = awtColor("A3C0AA");
231  
  transient IF0<DynModule> moduleMaker;
232  
  transient ThreadPool threadPool;
233  
  
234  
  transient TrayIcon trayIcon;
235  
  transient TrayIconLastPosition trayIconLastPosition;
236  
  
237  
  transient Set<S> argsSet;
238  
  
239  
  transient Concepts concepts;
240  
  
241  
  // This caused problems, disabled for now
242  
  transient bool allowFrameMaximization;
243  
  
244  
  *(ThreadPool *threadPool, IF0<DynModule> *moduleMaker) {}
245  
246  
  void trayIconLeftClick {
247  
    activateFrame_v3(mainWindow());
248  
  }
249  
  
250  
  void makeTrayIcon {
251  
    pcall-short {
252  
      trayIcon_imageAutoSize = false;
253  
      trayIcon = installTrayIcon(trayIconImageID, windowTitle,
254  
        r trayIconLeftClick,
255  
        "Show Gazelle", r trayIconLeftClick,
256  
        "Exit Gazelle", r cleanExit
257  
      );
258  
      trayIconLastPosition = new TrayIconLastPosition(trayIcon);
259  
    }
260  
  }
261  
  
262  
  void run(S[] args) {
263  
    try {
264  
      run2(args);
265  
    } catch print e {
266  
      //messageBox(e);
267  
      hideTrayIcon(trayIcon);
268  
      onWindowClosing(-> systemExit(1), getWindow(
269  
        showText_fast_noWrap("Gazelle Error", renderStackTrace(e))));
270  
      //AutoVMExit.install();
271  
    }
272  
  }
273  
  
274  
  void run2(S[] args) {
275  
    argsSet = asSet(args);
276  
    
277  
    if (!argsSet.contains("noflatlaf"))
278  
      com.formdev.flatlaf.FlatLightLaf.setup();
279  
    
280  
    if (contains(args, "profile"))
281  
      profileToConsole(() -> actualMain(args));
282  
    else
283  
      actualMain(args);
284  
      
285  
    if (argsSet.contains("brexit")) System.exit(0);
286  
  }
287  
  
288  
  void actualMain(S... args) {
289  
    vm_generalMap_put(stefansOS := this);
290  
    
291  
    System.out.println(hmsWithColonsAndMS() + ": Init");
292  
    //x30.coreInit();
293  
    
294  
    // Ready to roll
295  
    
296  
    if (containsOneOf(argsSet, "upgrade", "update"))
297  
      ret with upgradeGazelle();
298  
  
299  
    makeTrayIcon();
300  
    
301  
    initAutoUpdate();
302  
    
303  
    // Test classFinder sanity
304  
    
305  
    set flag defaultDefaultClassFinder_debug.
306  
    assertEquals(callF(_defaultClassFinder(), "main$Stem"), Stem.class);
307  
308  
    // Start DB
309  
    
310  
    concepts = newConceptsWithClassFinder(programID);
311  
    concepts.fileLock().lockOrFail();
312  
    concepts.fileLock().deleteOnExit();
313  
    concepts.persist();
314  
    
315  
    print("Concepts loaded: " + map className(allConcepts(concepts));
316  
    
317  
    var stems = findConcepts(concepts, Stem);
318  
    print("Stems in DB: " + l(stems));
319  
    stem = first(stems);
320  
    if (stem == null) {
321  
      print("Starting new module");
322  
      makeModule();
323  
      stem = registerConcept(concepts, new Stem(this, gazelle));
324  
    }
325  
    gazelle = stem.module;
326  
327  
    for (stem : list Stem(concepts)) {
328  
      stem.host = this;
329  
      stem.startAndShow();
330  
    }
331  
    
332  
    printWithMS("Dudadoneski");
333  
  }
334  
  
335  
  void showPrintLog {
336  
    registerConcept(concepts, new Stem(this, new PrintLogModule)).startAndShow();
337  
  }
338  
  
339  
  JFrame mainWindow() {
340  
    ret stem?.window;
341  
  }
342  
  
343  
  O dm_getStem(O moduleOrID) {
344  
    ret stem;
345  
  }
346  
  
347  
  O resolveModule(O moduleOrID) { ret moduleOrID == stem ? gazelle : moduleOrID; }
348  
  
349  
  void cleanExit {
350  
    thread {
351  
      print("Saving DB for exit");
352  
      dispose concepts;
353  
      System.exit(0);
354  
    }
355  
  }
356  
  
357  
  File myJar() { ret getBytecodePathForClass(this); }
358  
  
359  
  void upgradeGazelle {
360  
    File myJar = myJar();
361  
    print(+myJar);
362  
    
363  
    S date = ymdMinusHMS();
364  
    File f = javaxCodeDir("Downloaded Updates/" + "gazelle-" + date + ".jar");
365  
    infoBox("Downloading Update...");
366  
    loadBinaryPageToFile(downloadURL(), f);
367  
    printFileInfo(f);
368  
    if (!isNonEmptySingleZip_byMagicHeader(f))
369  
      ret with  infoBox("Bad file downloaded... :(");
370  
      
371  
    bool replaced;
372  
    if (isFile(myJar)) {
373  
      print("Loaded " + nClasses(loadAllClassesInByteCodePath(myJar)));
374  
      print("Replacing with new version: " + myJar);
375  
      renameFile(myJar, fileInSubDir("old-code",
376  
        appendToBaseName(myJar, ".bak." + date)));
377  
      copyFile(f, myJar);
378  
      printFileInfo(myJar);
379  
      set replaced;
380  
    }
381  
      
382  
    infoBox(replaced
383  
      ? "Installed update, replaced " + f2s(myJar) + " - now starting"
384  
      : "Starting update, but could not replace originally downloaded jar");
385  
      
386  
    restart(replaced ? myJar : f);
387  
  }
388  
  
389  
  void restart(File jar default myJar()) {
390  
    S javaCmd = or2(currentProcessCommand(), "java");
391  
    S cmd = pqO(javaCmd) + " -jar " + pqO(jar);
392  
    print(cmd);
393  
    nohup(cmd);
394  
    cleanExit();
395  
  }
396  
  
397  
  void makeModule() {
398  
    if (gazelle == null)
399  
      gazelle = callF(moduleMaker);
400  
  }
401  
  
402  
  void reloadModuleInBackground(Stem mod) {
403  
    restart();
404  
  }
405  
406  
  void initAutoUpdate {  
407  
    print("Making SnippetUpdateConnector.");
408  
    snippetUpdateConnector(verbose := true);
409  
  
410  
    vmBus_onMessage snippetUpdate(voidfunc(L l) {
411  
      S uri = getString(l, 1);
412  
      new Matches m;
413  
      if (swic(uri, "/transpileOK/", m))
414  
        if (sameSnippetID(programID(), firstIntAsString(m.rest()))) {
415  
          if (stem.autoUpdate)
416  
            upgradeGazelle();
417  
          //infoBox("Gazelle can be updated!");
418  
        }
419  
    });
420  
  }
421  
  
422  
  S downloadURL() {
423  
    ret "https://botcompany.de/jar/" 
424  
      + psI(programID()) + "?withLibs=1&noCompiler=1"
425  
      + (downloadUncompressedJAR() ? "&uncompressed=1" : "");
426  
  }
427  
  
428  
  bool downloadUncompressedJAR() { false; }
429  
  
430  
  // called by DynModule
431  
  void revisualizeModule(Stem stem) {
432  
    stem.revisualize();
433  
  }
434  
} // end of GazelleHost

Author comment

Began life as a copy of #1033525

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1033540
Snippet name: GazelleHost + Stem
Eternal ID of this version: #1033540/130
Text MD5: 091cae0ad0e1775b6ea30631d606aff6
Author: stefan
Category: javax / gazelle v
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-01-11 18:39:24
Source code size: 11576 bytes / 434 lines
Pitched / IR pitched: No / No
Views / Downloads: 399 / 1179
Version history: 129 change(s)
Referenced in: [show references]