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

1957
LINES

< > BotCompany Repo | #1016478 // Stefan's OS v6

JavaX source code (desktop) [tags: use-pretranspiled] - run with: x30.jar

Download Jar. Uses 1177K of libraries. Click here for Pure Java version (43793L/303K).

1  
!7
2  
3  
set flag print_rst. // speed up printing a lot
4  
5  
set flag jCheckBoxMenuItem_dyn_debug.
6  
7  
set flag InOSCore.
8  
set flag NotifyingPrintLog.
9  
10  
sS defaultBackground = #1101488; //#1101303; //#1101465; //#1101438; //#1101355; // #1009931;
11  
sS background = defaultBackground;
12  
sS mainIconID = #1102666, moduleDefaultIconID = #1101337;
13  
sS laf;
14  
static double minLoadScreenShowingTime = 2;
15  
sbool loadBackgroundLater = true;
16  
static double backgroundLoadDelay = 2.0;
17  
sbool showLoadingScreen = false;
18  
static JDesktopPane desktop;
19  
sbool useCodeSharing = true; // share code between identical modules
20  
21  
static int autoSaveInterval = -10000; // 10 seconds plus slowdown logic
22  
static int persistenceDelayPerModule = 10000; // 10 seconds
23  
24  
static int systemErrorsToKeep = 10;
25  
26  
// OUTDATED
27  
static ReliableSingleThread rstUpdateModules = new(r { systemQ.add(r updateModules) });
28  
sS lastTopInput;
29  
static ReliableSingleThread rstTopInputChanged = rstWithDelay(250, r {
30  
  S s = getText(tfTopInput);
31  
  if (neq(lastTopInput, s))
32  
    vmBus_send('topInputChanged, lastTopInput = s);
33  
});
34  
35  
static volatile long updateCycles;
36  
static L systemErrors = synchroList();
37  
static int systemErrors_pointer;
38  
static new Flag stopRequested;
39  
static SimpleLiveValue<S> systemStatus = stringLiveValue("loading");
40  
static bool firstModuleShown;
41  
static Map<O, GhostModule> ghostModules = weakHashMap(); // key is main class (if dynamic module) or instance (if static module)
42  
static Q systemQ;
43  
static AccessControlContext globalACC;
44  
static volatile Module activeModule;
45  
static JTextField tfTopInput; // the input field in the OS menu bar
46  
static long tfTopInput_dontSelectAll; // sysNow timestamp
47  
static StefansOS_ConnectToServer connector;
48  
static Map generalMap = synchroMap();
49  
static L<Component> trayAreaComponents = synchroList();
50  
sbool printOnPersistContents, verboseCleanUp;
51  
static JMenuBar menuBar;
52  
sbool katze_send = true, katze_sendTyped;
53  
sO makeReloadingComponent; // F1<Module, Component>
54  
static long startTime;
55  
static NotTooOften backgroundGCFrequency = everyTenMinutes();
56  
static Set<S> hideFeatures;
57  
static LS standardModules;
58  
sS botName = "Stefan's OS.";
59  
sS osName;
60  
sbool showTopInput = true;
61  
static Runnable shutdownConsole; // instead of showConsole()
62  
sbool verboseModuleDeletes, cacheTranspilationsDuringBoot = true;
63  
sO confirmOSExit; // func -> bool or null
64  
sO gc_subcondition; // disable GC by module; func -> bool or null
65  
sbool showTimeInPrintLog = true;
66  
static JCheckBoxMenuItem miEnableQuickSearches;
67  
sbool debugFrameSizes;
68  
69  
// if you want other initial modules
70  
sO initialModules_override; // VF1<OS reference>
71  
72  
static Runnable restarter_override;
73  
static O onStart;
74  
75  
static S[] mainArgs;
76  
77  
static Set<S> disabledModuleIDs;
78  
static Set<DynamicModule> modulesBeingReloaded = syncSet();
79  
80  
p {
81  
  startTime = sysNow();
82  
  
83  
  // Just load all my classes so we are not dependent on jar or
84  
  // classes files on disk.
85  
  time "loadAllClasses" {
86  
    loadAllClasses();
87  
  }
88  
  
89  
  mainArgs = args;
90  
  vm_generalMap_put(stefansOS := mc());
91  
  callF(onStart, mc());
92  
  
93  
  //set getServerTranspiled_printStackTrace;
94  
  
95  
  print(headless() ? "We are headless." : "Starting GUI.");
96  
  
97  
  if (!headless()) showControls(jbutton("TROUBLESHOOTING", r { stopRequested.raise() }));
98  
  noRegularGC(); // not while we're loading
99  
  
100  
  /*if (onLocallyInferiorJavaX()) {
101  
    print("Restarting to use standard JavaX");
102  
    restart();
103  
  }*/
104  
  
105  
  checkMaxWindowBoundsBug();
106  
  
107  
  if (!eq("0", trim(loadTextFile(javaxDataDir("compile-on-server")))))
108  
    set hotwire_compileOnServer;
109  
  
110  
  /*if (isLinux() && isRoot())
111  
    addToDefaultVMArgs("-XX:ThreadPriorityPolicy");*/
112  
    
113  
  /*if (java10OrHigher()) {
114  
    addStandardAddOpensFlags();
115  
    addPermitIllegalAccessesFlag();
116  
      // needed for URLClassLoader and Swing stuff
117  
    if (!hasStandardAddOpensFlagsInCurrentVM()) {
118  
      print("RESTARTING with proper JDK 11+ arguments");
119  
      restart();
120  
    }
121  
  }*/
122  
  
123  
  if (java8OrHigher() && !containsOneOf(defaultVMArgs(), "+UseZGC", "+ShenandoahGC"))
124  
    addToDefaultVMArgs(smallHeapArgs());
125  
  
126  
  //laf = 'webLAF; // Let's not generally use it, is sluggish on my machine
127  
  //laf = 'nimbus;
128  
  laf = 'platform;
129  
  
130  
  //if (isMac()) laf = 'platform; // because https://github.com/michael-hagen/JTattoo/issues/1
131  
  if (isMac()) vmGeneralMap_set('iconifyBroken, true);
132  
  if (isLinux()) laf = 'jtattoo;
133  
  
134  
  /*if (vmArgs().contains("-XX:+PrintAssembly")) pcall {
135  
    teeSystemOutAndErrToFile(programFile("os.log"));
136  
  }*/
137  
  
138  
  if (!hasClass("x30_pkg.x30_util")) {
139  
    if (!zipFileContains_falseOnError(pathToJavaxJar(), "x30_pkg/x30_util.class"))
140  
      upgradeJavaXAndRestart();
141  
    else
142  
      restart();
143  
  }
144  
  
145  
  _handleException_addHandler(voidfunc(Throwable e) {
146  
    try {
147  
      synchronized(systemErrors) {
148  
        listSet(systemErrors, systemErrors_pointer, e);
149  
        systemErrors_pointer = (systemErrors_pointer+1) % systemErrorsToKeep;
150  
      }
151  
    } catch e2 {
152  
      printStackTrace(e2);
153  
    }
154  
    infoBox("Error: " + exceptionToStringShort(e));
155  
    LastErrors lastErrors = first(staticModulesOfType(LastErrors));
156  
    if (lastErrors != null) lastErrors.addError(e);
157  
  });
158  
  
159  
  timeJumpDetector();
160  
  
161  
  vm_generalMap_put('consoleInUse, true); // bots made by modules should not handle console
162  
163  
  monitorThreadAllocatedMemory();
164  
  
165  
  // Solve deadlocks every 10 to be sure
166  
  doEvery(10000, r printDeadlocksAndSolve);
167  
  
168  
  print("Data dir: " + javaxDataDir());
169  
  vm_setGlobalACC(globalACC = acc_current());
170  
  
171  
  // TODO: FIX, not working
172  
  if (swic(activateFramesOf(programIDPlusHome()), "OK")) {
173  
    print("OS already running!");
174  
    cleanKill();
175  
  }
176  
  
177  
  framesBot();
178  
  if (nempty(botName)) makeBot(botName);
179  
  
180  
  S printLogSize = trim(loadTextFile(javaxDataDir("os-print-log-size.txt")));
181  
  if (isInteger(printLogSize)) printLogMaxChars(parseInt(printLogSize));
182  
  
183  
  please include function allAWTComponents.
184  
  
185  
  vm_generalMap_put('newSwingComponentRegistry, voidfunc(Component c) {
186  
    allAWTComponents_extraList.add(c)
187  
  });
188  
  
189  
  connector = new StefansOS_ConnectToServer;
190  
  connector.start();
191  
  
192  
  // in case we sub to it later
193  
  connector.onLine = voidfunc(S line) {
194  
    new Matches m;
195  
    if (startsWith(line, "snippetUpdates:", m)) {
196  
      S msg = m.rest();
197  
      printWithIndent("<< ", msg);
198  
      logQuoted(programLogFile(#1019239), msg); // using this file for hysterical reasons
199  
      vmBus_send snippetUpdate(safeUnstruct(msg));
200  
    }
201  
  };
202  
  
203  
  //substance();
204  
  final SimpleLiveValue<S> lvDetails = stringLiveValue();
205  
  lvDetails.onChange(r { print(lvDetails!) });
206  
  stefansOS_loadingAnimation_fullScreen = startInFullScreen() && !isWindows() /* bug */;
207  
  final Component loadingAnim = showLoadingScreen ? stefansOS_loadingAnimation(r {
208  
    stopRequested.raise()
209  
  }, lvDetails) : null;
210  
  
211  
  try {
212  
    long start = sysNow();
213  
    systemQ = startQ("System Q");
214  
    useDBOf(#1015871);
215  
    lvDetails.set("Loading database");
216  
    db(autoSaveInterval);
217  
    db_mainConcepts().quietSave = true;
218  
    if (!headless()) {
219  
      // if you use Processing
220  
      JPopupMenu.setDefaultLightWeightPopupEnabled(false);
221  
  
222  
      lvDetails.set("Loading background");
223  
      background = or2(trim(loadTextFile(javaxDataDir("os-background.txt"))), background);
224  
      if (!isSnippetID(background))
225  
        background = fileToURI(new File(background));
226  
      try {
227  
        if (eq(settings().backgroundMode, "fit"))
228  
          desktop = loadBackgroundLater
229  
            ? jDesktopPaneWithFitPicture_smooth_cacheScaled_loadLater(background, delay := backgroundLoadDelay)
230  
            : jDesktopPaneWithFitPicture_smooth_cacheScaled(background);
231  
        else if (eq(settings().backgroundMode, "center"))
232  
          desktop = setBackground(settings().backgroundColor,
233  
            jDesktopPaneWithCenteredPicture(background));
234  
        else
235  
          desktop = jDesktopPaneWithSkyPicture/*_autoUnload*/(background, settings().backgroundColor);
236  
      } catch print e {
237  
        try {
238  
          desktop = jDesktopPaneWithFitPicture_smooth(defaultBackground);
239  
        } catch print e2 {
240  
          desktop = jDesktopPane();
241  
        }
242  
      }
243  
      setMainDesktopPane(desktop);
244  
      autoFixDesktopPane(desktop);
245  
      
246  
      // Allow frame switching from AI bar & similar components
247  
      installInternalFrameSwitcher_v3(desktop).shouldSwitch =
248  
        func -> bool { sameComponentOrDeepChildOf(getFocusOwner(), menuBar) };
249  
    }
250  
    
251  
    long ms = consoleShowing() ? toMS(minLoadScreenShowingTime) : 0;
252  
    long remaining = start+ms-sysNow();
253  
    if (remaining <= 0)
254  
      lvDetails.set("Done loading");
255  
    else {
256  
      S seconds = formatDouble(toSeconds(remaining), 1);
257  
      lvDetails.set("Done loading, but will wait if you hit the troubleshooting button for " + seconds + " more second" + (eq(seconds, "1") ? "" : "s"));
258  
    }
259  
    //if (loadingAnim != null)
260  
      waitUntilSysTimeOrFlag(start+ms, stopRequested);
261  
  } catch e {
262  
    _handleException(e);
263  
    stopRequested.raise();
264  
  }
265  
  
266  
  try {
267  
    bool flag = stopRequested.isUp(); // get before closing animation
268  
    if (flag)
269  
      ret with showFrame("Stop screen",
270  
        centerAndSouthWithMargins(
271  
          jcenteredlabel("More troubleshooting options will go here."),
272  
          jcenteredbuttons(
273  
            "Start " + osName() + " normally", r restart,
274  
            //"Switch to " + otherVersionName(), r startOtherVersion,
275  
            eq(programID(), #1016478) ? null: "Switch to v6", r { nohupJavax(#1016478) },
276  
            eq(programID(), #1024932) ? null: "Switch to v7", r { nohupJavax(#1024932) },
277  
            "Use last session backup", rThread useLastSessionBackup,
278  
            jPopDownButton_noText(
279  
              "Delete session", disableButtonWhileCalcing(func -> bool {
280  
              if (!fileExists(conceptsFile()))
281  
                ret false with infoBox("Session already empty.");
282  
              if (!confirmOKCancel("Really delete your current session?")) false;
283  
              cleanMeUp_concepts();
284  
              renameFileToSomeBackupName(conceptsFile());
285  
              infoBox("Session deleted. Starting again.");
286  
              disableAllButtonsInWindow(heldInstance(JButton));
287  
              sleepSeconds(3);
288  
              restart();
289  
              false;
290  
            })))));
291  
  
292  
    //autoRestart();
293  
    thread { serverAutoRestartMD5(); } // just a short ping
294  
    
295  
    pcall { setLookAndFeel(); }
296  
    
297  
    showDesktop();
298  
  } finally {
299  
    disposeWindow(loadingAnim);
300  
  }
301  
    
302  
  initAfterDBLoad();
303  
  setOpt(javax(), regularGC_firstDelay := 60000);
304  
  call(javax(), 'regularGC);
305  
  if (!headless()) {
306  
    setOpt(javax(), regularGC_condition := func -> bool {
307  
      if (isFalse(callF(gc_subcondition))) false;
308  
      if (backgroundGCFrequency! || vmHasActiveFrame())
309  
        ret true /*with print("GC")*/;
310  
      else
311  
        ret false /* with print("Skipping GC (not in foreground)") */;
312  
    });
313  
  }
314  
  hideConsole();
315  
  manualConsole();
316  
  //clearConsole();
317  
  if (headless()) sleep();
318  
}
319  
320  
sbool startInFullScreen() {
321  
  ret eq("1", trim(loadTextFile(javaxDataDir("start-os-in-full-screen.txt"))));
322  
}
323  
324  
svoid setStartInFullScreen(bool b) {
325  
  saveTextFile(javaxDataDir("start-os-in-full-screen.txt"), b ? "1" : "0");
326  
}
327  
sbool showDesktop_first = true;
328  
329  
svoid showDesktop {
330  
  if (headless()) ret;
331  
  bool done = false;
332  
  
333  
  S title;
334  
  if (nempty(osName)) title = osName;
335  
  else {
336  
    title = osName(); //programName();
337  
    S subDir = javaxVirtualSpaceName();
338  
    if (subDir != null) title = "[" + subDir + "] " + title;
339  
  }
340  
341  
  if (showDesktop_first && startInFullScreen()) pcall {
342  
    showFullScreen(title, desktop);
343  
    done = true;
344  
  }
345  
346  
  if (!done) {
347  
    showMaximizedFrame(title, desktop);
348  
    titlePopupMenu_top(desktop, voidfunc(JPopupMenu menu) {
349  
      addMenuItems(menu,
350  
        "New Session", rThreadPcallMessageBox(r deleteAllModules),
351  
        "Restore Initial Modules", r initialModules,
352  
      );
353  
    });
354  
  }
355  
  
356  
  if (showTopInput)
357  
    registerFunctionKey(getFrame(desktop), 1, r { requestFocus(tfTopInput) });
358  
  
359  
  fillMenuBar();
360  
  doNothingOnClose(getFrame(desktop));
361  
  frameIcon(mainIconID, desktop);
362  
  showDesktop_first = false;
363  
  cleanExitOnFrameClose_ifStillInSameFrame(desktop,
364  
    () -> (Bool) callF(confirmOSExit));
365  
}
366  
367  
sbool inFullScreen() {
368  
  ret isFullScreen(desktop);
369  
}
370  
371  
svoid fullScreenOff() {
372  
  if (inFullScreen()) fullScreenOnOff();
373  
}
374  
375  
svoid fullScreenOnOff {
376  
  // Don't screw up window positions while adjusting from/to fullscreen
377  
  autoFixDesktopPane_exclude.add(desktop);
378  
  temp tempAfterwards(r { autoFixDesktopPane_exclude.remove(desktop) });
379  
  
380  
  Window w = getWindow(desktop);
381  
  if (!inFullScreen()) {
382  
    showFullScreen(frameTitle(desktop), desktop);
383  
    pcall { frameIcon(mainIconID, desktop); }
384  
    cleanExitOnFrameClose_ifStillInSameFrame(desktop);
385  
    fillMenuBar();
386  
    setStartInFullScreen(true);
387  
  } else {
388  
    removeFromParent(desktop);
389  
    showDesktop();
390  
    setStartInFullScreen(false);
391  
  }
392  
  
393  
  // Allow closing empty "zombie" windows (why do we have these?)
394  
  final JFrame f = getFrame(desktop);
395  
  onFrameClosing(f, r { if (isEmptyFrame(f)) {
396  
    removeListener();
397  
    disposeWindow(f);
398  
  }});
399  
  
400  
  disposeWindow(w);
401  
  fixDesktopPane(desktop);
402  
}
403  
404  
svoid updateMenuBar() swing {
405  
  //temp tempRememberFocusedComponent();
406  
  JMenuBar mb = getMenuBar(desktop);
407  
  if (mb == null) {
408  
    mb = addMenuBar(desktop);
409  
    mb.setLayout(new javax.swing.plaf.basic.DefaultMenuLayout(menuBar, BoxLayout.X_AXIS));
410  
  } 
411  
  keepComponentsByPred(mb, func(Component c) -> bool {
412  
    c instanceof JMenu || c == tfTopInput
413  
  });
414  
  //clearMenuBar();
415  
  fillMenuBar();
416  
}
417  
418  
svoid fillMenuBar() swing {
419  
  menuBar = addMenuBar(desktop);
420  
  set jmenuItem_newThreads;
421  
  S version = version();
422  
  S name = osName();
423  
  //S subDir = userHomeSubDirName();
424  
  //if (subDir != null) name += " [" + subDir + "]";
425  
  addMenuIfNempty(desktop, empty(osName) ? "OS" : trim(name),
426  
    featureMenuItem("Screenshot"), r stefansOS_screenshot,
427  
    featureMenuItem("Full screen on/off"), r fullScreenOnOff,
428  
    featureMenuItem("Switch OS version", "Switch to " + otherVersionName()), r {
429  
      innerCleanUp();
430  
      startOtherVersion();
431  
      cleanKill();
432  
    },
433  
    "---",
434  
    featureMenuItem("Restart OS", "Restart " + or2(osName, "Stefan's OS")), r { showConsole(); restart(); },
435  
    featureMenuItem("Exit"), r cleanKill
436  
  );
437  
  
438  
  L moduleMenu = ll(
439  
    featureMenuItem("Other Module..."), r stefansOS_addDynamicModuleDialog,
440  
    "Show selected module's menu", r showCurrentModuleMenu
441  
  );
442  
    
443  
  for (int i = 0; i+1 < l(standardModules); i += 2) {
444  
    moduleMenu.add(standardModules.get(i));
445  
    S id = standardModules.get(i+1);
446  
    moduleMenu.add(r { makeOrShowModule(id) });
447  
  }
448  
    
449  
  moduleMenu.addAll(ll(
450  
    featureMenuItem("Welcome Screen"), r { makeOrShowModule("#1016067/WelcomeScreen") },
451  
    featureMenuItem("Quick Module Search"), r addQuickModuleSearch,
452  
    //"Hello (input field for everything)", r { makeOrShowModule("Hello") },
453  
    featureMenuItem("Auto Module Upgrade"), r { makeOrShowModule("#1021905/AutoReloadButtons") },
454  
    featureMenuItem("Task Bar"), r { makeOrShowModule("#1019954/TaskBar_dev") },
455  
    featureMenuItem("System Print Log"), r { makeOrShowModule("#1018866/SystemPrintLog") },
456  
    hideFeature("Internal Types") ? null : jmenu("Internal Types", map(myNonAbstractClassesImplementing(Module), func(final Class c) -> JMenuItem {
457  
      jMenuItem(shortClassName(c), rThread { makeOrShowStaticModuleOfType(c) })
458  
    })),
459  
    featureMenuItem("Module Classes"), r {  makeOrShowStaticModuleOfType(ModuleClasses) },
460  
    "---",
461  
    jDynamicScrollingMenu("Loaded Modules", voidfunc(JPopupMenu menu) {
462  
      for (final Module m : sortedByMethodIC('moduleName, onModules()))
463  
        addMenuItem(menu, m.moduleName(), rThread { showModule(m) });
464  
    })
465  
  ));
466  
  
467  
  addMenu(desktop, "Modules", asObjectArray(moduleMenu));
468  
  
469  
  // TODO - need to generate menu items differently in enhanceFrame
470  
  //addFullyDynamicMenu(desktop, "Current module",
471  
  
472  
  addMenu(desktop, "More",
473  
    featureMenuItem("Start External JavaX Program..."), r stefansOS_startExternalJavaXProgram,
474  
    "---",
475  
    featureMenuItem("Run 10 Second Profiler"), r tenSecondProfileAndShowInFrame,
476  
    featureMenuItem("Find memory leaks", "Find memory leaks (PID: " + getPID() + ")"), r stefansOS_findMemoryLeaks,
477  
    "Computer ID: " + computerID(), r { copyTextToClipboard_infoBox(computerID()) },
478  
    featureMenuItem("Show console"), rThread showConsole,
479  
    featureMenuItem("System Version"), r { makeOrShowModule_early("#1016442/SystemVersion") },
480  
    featureMenuItem("Remove moduleless frames"), rThread dm_closeModuleLessFrames,
481  
    featureMenuItem("Clean disk caches"), rThread stefansOS_cleanDiskCaches,
482  
    hideFeature("Enable quick searches") ? null : (miEnableQuickSearches = menuItem_enableQuickSearches()),
483  
    featureMenuItem("Hard exit"), rHardExit(),
484  
  );
485  
    
486  
  // Add the fancy stuff
487  
  
488  
  JMenuBar menuBar = cast call(getFrame(desktop), 'getJMenuBar);
489  
  
490  
  if (tfTopInput == null && showTopInput) {
491  
    tfTopInput = jcenteredtextfield(uniq(TopInput).text);
492  
    setFontSize(tfTopInput, 16);
493  
    selectAllOnFocusIf(tfTopInput, func -> bool {
494  
      elapsedTime(tfTopInput_dontSelectAll) >= 2000
495  
    });
496  
    onChange(tfTopInput, r {
497  
      cset(uniq(TopInput), text := getText(tfTopInput));
498  
      rstTopInputChanged.trigger();
499  
    });
500  
    onEnter(tfTopInput, r {
501  
      S info = cast generalMap.get('topInputInfo);
502  
      temp dm_generalMap_tempPut(topInputInfo := or2(info, "typed"));
503  
      S text = getText(tfTopInput);
504  
      vmBus_send('topInput, text);
505  
      logQuotedWithDate(topInputsLogFile(), text);
506  
      if (katze_send)
507  
        if (nempty(info))
508  
          katze_userSaid(info, text);
509  
        else if (katze_sendTyped)
510  
          katze_userTyped(text);
511  
    });
512  
    componentPopupMenu(tfTopInput, voidfunc(JPopupMenu menu) {
513  
      menu.add(menuItem_enableQuickSearches());
514  
    });
515  
  }
516  
    
517  
  if (showTopInput && getParent(tfTopInput) == null) {
518  
    menuBar.add(Box.createHorizontalStrut(20));
519  
    menuBar.add(tfTopInput);
520  
  }
521  
  
522  
  if (!containsChildOfType(menuBar, JLabel.class)) { // look for clock label
523  
    if (!showTopInput)
524  
      menuBar.add(Box.createHorizontalGlue());
525  
    else {
526  
      menuBar.add(Box.createHorizontalStrut(5));
527  
      menuBar.add(onClick(setToolTip([[Simulate pressing Enter key in input field to the left ("AI bar")]], jimage(#1101426)), r { simulateEnter(tfTopInput) }));
528  
    }
529  
    //menuBar.add(jhgrid(null, tfTopInput));
530  
    //menuBar.add(jhgrid(tfTopInput, null));
531  
    menuBar.add(Box.createHorizontalStrut(20));
532  
    for i over trayAreaComponents: {
533  
      Component c = trayAreaComponents.get(i);
534  
      continue if c == null;
535  
      menuBar.add(c);
536  
      menuBar.add(Box.createHorizontalStrut(i == l(trayAreaComponents)-1 ? 20 : 6));
537  
    }
538  
    menuBar.add(jLiveValueLabel(clockTimeLiveValue()));
539  
    menuBar.add(Box.createHorizontalStrut(6));
540  
  }
541  
}
542  
543  
svoid addQuickModuleSearch {
544  
  makeOrShowModule("#1016702/LoadedModuleSearch");
545  
  makeOrShowModule("#1016932/ServerModuleSearch");
546  
}
547  
548  
static JCheckBoxMenuItem menuItem_enableQuickSearches() {
549  
  ret jCheckBoxMenuItem("Enable quick searches", quickSearchesEnabled(), voidfunc(bool b) {
550  
    cset(uniq(TopInput), quickSearchesEnabled := b);
551  
    setChecked(miEnableQuickSearches, b);
552  
  });
553  
}
554  
555  
static tempDisposeInternalFrame_obj<JLabel> tempBusyAnimation(fS text) {
556  
  ret vmExiting() ? null : tempBusyAnimation(stringLiveValue(text));
557  
}
558  
559  
static tempDisposeInternalFrame_obj<JLabel> tempBusyAnimation(LiveValue<S> text) {
560  
  if (headless()) null;
561  
  final JLabel anim = jBackground(Color.white, jAnimation_liveValueText(#1101316, text));
562  
  swing {
563  
    addInternalFrame_dontSelect.set(true);
564  
    addInternalFrame_layer.set(JLayeredPane.POPUP_LAYER);
565  
    addInternalFrame(desktop, "", null, anim);
566  
    packInternalFrameInTopRightCorner(anim);
567  
    JInternalFrame f = getInternalFrame(anim);
568  
    //print("Have busy animation: " + f + " in " + getParent(f));
569  
  }
570  
  ret tempDisposeInternalFrame(anim);
571  
}
572  
573  
svoid allRegularFixes {
574  
  applyStandardSwingFixes();
575  
  cleanDefunctACCsInAllThreads();
576  
  cleanDefunctACCsInAllSwingComponents();
577  
}
578  
579  
svoid gcWithFixes {
580  
  allRegularFixes();
581  
  gc();
582  
  allRegularFixes();
583  
}
584  
585  
svoid initAfterDBLoad {
586  
  doEvery(30000, r allRegularFixes);
587  
  doEvery(600000, r clearSnippetTitleCacheIfOnline);
588  
  set cleanUp_interruptThreads; 
589  
  
590  
  // for Java Chrome
591  
  classForNameOpt("java.util.prefs.FileSystemPreferences");
592  
  
593  
  SimpleLiveValue<S> lvText = stringLiveValue(jlabel_textAsHTML_center("Restoring Session"));
594  
  temp final tempDisposeInternalFrame_obj<JLabel> anim = tempBusyAnimation(lvText);
595  
  JLabel animComponent = anim == null ? null : anim.component;
596  
  if (anim != null) {
597  
    onResizeAndNow(animComponent, r {
598  
      setVerticalAlignment(
599  
        animComponent.getHeight() >= 150 ? JLabel.CENTER : JLabel.TOP,
600  
        animComponent)
601  
    });
602  
    growInternalFrameLeft(animComponent, 50);
603  
    growInternalFrameSouth(animComponent, 50);
604  
  }
605  
  
606  
  disabledModuleIDs = asSet(tlft(loadTextFile(javaxDataDir("stefans-os/disabled-modules.txt"))));
607  
  
608  
  initialModules();
609  
  
610  
  UpdateCycles uc = conceptWhere(UpdateCycles);
611  
  if (uc != null) updateCycles = uc.value;
612  
  
613  
  stefansOS_installQuickSearchHelper();
614  
  
615  
  // START ALL MODULES
616  
  
617  
  L<Module> modules = startOrder(onModules());
618  
  
619  
  AutoCloseable disposeTempCache2 = cacheTranspilationsDuringBoot ? tempSetMCOpt(getServerTranspiled2_tempCache :=  syncMap()) : null;
620  
  
621  
  if (cacheTranspilationsDuringBoot) thread {
622  
    for (Module m : modules) pcall {
623  
      if (m cast DynamicModule) {
624  
        print("Preloading " + m.moduleID);
625  
        getServerTranspiled2(m.moduleID);
626  
      }
627  
    }
628  
    print("Preloading done");
629  
  }
630  
631  
  AutoCloseable disposeTempCache = tempSetTL(loadLibraryOrSrcLib_tempCache, new Map);
632  
  
633  
  int i = 0;
634  
  for (Module m : modules) {
635  
    ++i;
636  
    int _i = i;
637  
    systemQ.add(new Runnable { 
638  
      run {
639  
        if (isShuttingDown()) ret;
640  
        lvText.set(jlabel_textAsHTML_center(
641  
          "Starting module " + _i + "/" + l(modules) + ":\n"
642  
          + m.moduleName()));
643  
        startModule(m);
644  
      }
645  
      
646  
      toString { ret "Start module " + m.id; }
647  
    });
648  
  }
649  
  
650  
  if (anim != null) anim.disableAutoDisposal();
651  
  systemQ.add(r {
652  
    close(disposeTempCache);
653  
    close(disposeTempCache2);
654  
    disposeInternalFrame(animComponent);
655  
    if (isShuttingDown()) ret;
656  
    systemStatus.set("running");
657  
    print("== STARTED IN " + iceil(elapsedSeconds(/*vmStartTime_sys()*/startTime)) + " SECONDS ==");
658  
  });
659  
}
660  
661  
static L<Module> startOrder(L<Module> modules) {
662  
  ret sortedByComparator(
663  
    combineComparators(
664  
      main.<Module> fieldComparator('loadOrder),
665  
      main.<Module> descFieldComparator('visible),
666  
      main.<Module> fieldComparator('zOrder)),
667  
    modules);
668  
}
669  
670  
svoid initialModules {
671  
  if (initialModules_override != null)
672  
    ret with pcallF(initialModules_override, mc());
673  
  initialModules_base();
674  
}
675  
676  
svoid initialModules_base {
677  
  if (headless()) {
678  
    makeOrShowModule("#1016576/ConnectToServer");
679  
    ret;
680  
  }
681  
    
682  
  if (empty(onModules())) {
683  
    //makeOrShowModule(#1016081/WelcomeScreen");
684  
    showModule_noFocus(getModuleByID(makeModule("#1018866/SystemPrintLog")));
685  
    showModule_noFocus(getModuleByID(makeModule("#1019954/TaskBar_dev")));
686  
    //makeModule("#1016872/SnippetsDB");
687  
    makeModule("#1016932/ServerModuleSearch");
688  
    makeModule("#1016702/LoadedModuleSearch");
689  
    //makeModule("#1018602/QuickAudioRecord");
690  
    makeModule("#1019326/WitAILastRecording");
691  
    makeModule("#1019400/SpeechRecogConfirmation");
692  
    makeModule("#1021905/AutoReloadButtons");
693  
  }
694  
}
695  
696  
svoid triggerUpdate { rstUpdateModules.trigger(); }
697  
698  
// not done anymore
699  
svoid updateModules {
700  
  /*++updateCycles;
701  
  for (Module m : onModules())
702  
    updateModule(m);*/
703  
}
704  
705  
svoid updateModule(Module m) {
706  
  if (m == null) ret;
707  
  temp m.enter();
708  
  pcall { m.update(); }
709  
}
710  
711  
svoid updateModules(final Collection<Module> l) {
712  
  systemQ.add(r {
713  
    for (Module m : unnull(l)) updateModule(m);
714  
  });
715  
}
716  
717  
svoid saveZOrder {
718  
  for (Module m)
719  
    cset(m, zOrder := getComponentZOrder(getInternalFrame(m.vis)));
720  
}
721  
722  
svoid cleanMeUp {
723  
  saveZOrder();
724  
  autoConsole();
725  
  if (shutdownConsole == null) showConsole(); else pcallF(shutdownConsole);
726  
  killProgram(#1019683); // stop watch dog
727  
  systemStatus.set("shutting down");
728  
  temp tempBusyAnimation("Shutting Down");
729  
  
730  
  print("PRE-CLEAN UP");
731  
  preCleanUp(list(Module));
732  
  for (Module m) {
733  
    if (m.vis != null) pcall {
734  
      print("UNVISUALIZING " + moduleIDAndName(m));
735  
      m.unvisualize();
736  
      print("UNVISUALIZED " + moduleIDAndName(m));
737  
    }
738  
    print("CLEANING UP " + moduleIDAndName(m));
739  
    cleanUp(m);
740  
    print("CLEANED UP " + moduleIDAndName(m));
741  
  }
742  
  print("CLEAN UP DONE");
743  
  cleanedUp = true;
744  
}
745  
746  
static L<Module> onModules() { ret asList(conceptsWhere(Module, on := true)); }
747  
748  
sbool hasModuleWithFields(Class<? extends Module> c, O... params) {
749  
  ret hasConcept(c, concatArrays(new O[] {on := true}, params));
750  
}
751  
752  
sbool startModule_reloading, startModule_doShare;
753  
sO startModule_beforeStart;
754  
755  
svoid startModule(Module m) {
756  
  runInSystemQAndWait(r-pcall {
757  
    //addIfNotThere(modules, m);
758  
    //print("startModule " + m);
759  
    temp m.enter();
760  
    if (m.started) ret;
761  
    if (m.startedWithError) print("Module " + m + " started with error");
762  
    
763  
    temp tempSet(m, starting := true);
764  
    print("Starting module " + m.moduleName());
765  
    try {
766  
      if (m cast DynamicModule)
767  
        if (contains(disabledModuleIDs, m.moduleID))
768  
          failWithInfoBox("Not starting disabled module " + m);
769  
      m.start();
770  
      m.started = true;
771  
    } catch e {
772  
      m.startedWithError = true;
773  
      m.setError(e);
774  
      _handleException(e);
775  
    }
776  
    vmBus_send('moduleStarted, m.moduleID());
777  
    //rstUpdateModules.trigger();
778  
    if (m.visible) {
779  
      showModule(m);
780  
      if (m.poppedOut) stefansOS_popOutModule(m);
781  
    }
782  
  });
783  
}
784  
785  
static Module showModule(final Module m) {
786  
  ret showModule(m, true);
787  
}
788  
789  
static Module showModule_noFocus(final Module m) {
790  
  ret showModule(m, false);
791  
}
792  
793  
svoid runInSystemQAndWait(Runnable r) {
794  
  if (isAWTThread()) ret with callF(r);
795  
  runInQAndWait(systemQ, r);
796  
}
797  
798  
sO evalInSystemQ_gen(O f) {
799  
  ret evalInSystemQ(toF0(f));
800  
}
801  
802  
static <A> A evalInSystemQ(F0<A> f) {
803  
  if (isAWTThread()) ret callF(f);
804  
  ret evalInQ(systemQ, f);
805  
}
806  
807  
static Module showModule(final Module m, final bool focus) {
808  
  if (m == null) ret m;
809  
  runInSystemQAndWait(r {
810  
    startModule(m);
811  
    if (headless()) ret;
812  
    temp m.enter();
813  
    if (m.vis != null) {
814  
      if (focus && !isLoading())
815  
        if (stefansOS_moduleIsPoppedOut(m))
816  
          activateFrame(m.vis);
817  
        else
818  
          activateInternalFrame(m.vis);
819  
      ret;
820  
    }
821  
    csetAndStatusChange(m, visible := true);
822  
    visualizeModule(m);
823  
    if (m.vis != null) swing {
824  
      Rect r = m.frameRect;
825  
      /*if (r == null) r = randomRect(desktop.getWidth(), desktop.getHeight(), 10, 150, 100);
826  
      if (r == null) r = makeDefaultRectForModule(m);
827  
      print("Showing frame at " + r);*/
828  
      S frameTitle = m.moduleName();
829  
      final JInternalFrame f;
830  
      bool toBack = isLoading() && firstModuleShown;
831  
      bool activate = focus && !toBack;
832  
      {
833  
        temp tempSetThreadLocal(addInternalFrame_toBack, toBack);
834  
        temp tempSetThreadLocal(addInternalFrame_dontSelect, !activate);
835  
        f = showInternalFrame(desktop, frameTitle, r, m.vis);
836  
        set firstModuleShown;
837  
      }
838  
      if (r == null) {
839  
        if (debugFrameSizes) print("Setting initial size for module " + m);
840  
        Pt p = m.getMinSize();
841  
        if (debugFrameSizes) print("Minimum size: " + p);
842  
        if (isTrue(callOpt(resolveModule(m), "_usePreferredSizeInitially"))) {
843  
          p = toPt(getPreferredSize(m.vis));
844  
          if (debugFrameSizes) print("Using preferred size: " + p);
845  
        }
846  
          
847  
        centerPackInternalFrameWithMinSize(f, p);
848  
      }
849  
      f.setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
850  
      
851  
      onInternalFrameIconified(f, r { hideModule(m) });
852  
      onInternalFrameClosing(f, rThread { deleteModule(m) });
853  
      onInternalFrameActivated(f, r { setActiveModule(m) });
854  
      onInternalFrameDeactivated(f, r { if (activeModule == m) setActiveModule(null) });
855  
      onBoundsChange(f, r { m.grabFrameRect() });
856  
      internalFrameIcon(f, or2(m.iconID, moduleDefaultIconID));
857  
      m.enhanceFrame(f);
858  
      if (activate) setActiveModule(m);
859  
    }
860  
  });
861  
  ret m;
862  
}
863  
864  
static Rect makeDefaultRectForModule(Module m) {
865  
  ret Rect(10, 10, 200, 100);
866  
}
867  
868  
svoid showModules(L<? extends Module> l) {
869  
  for (Module m : unnull(l)) showModule(m);
870  
}
871  
872  
sbool deleteModule(Module m) {
873  
  pcall {
874  
    bool warn = isTrue(callOpt(resolveModule(m), 'warnOnDelete));
875  
    if (warn && !confirmOKCancel("Really delete module " + m + "?"))
876  
      false;
877  
  }
878  
  deleteModule_noConfirm(m);
879  
  true;
880  
}
881  
882  
svoid deleteModule_noConfirm(Module m) {
883  
  runInSystemQAndWait(r {
884  
    if (verboseModuleDeletes) print("delete phase 1");
885  
    O m2 = unwrapDynamicModule(m);
886  
    vmBus_send('deletingModule, m2);
887  
    ghostModules.put(m == m2 ? m : m2.getClass(), nu(GhostModule,
888  
      name := m.moduleName(),
889  
      created := m.created,
890  
      deleted := now(),
891  
      instance := new WeakReference(m2)));
892  
    if (verboseModuleDeletes) print("delete phase 2");
893  
    pcall { m.unvisualize(); }
894  
    if (verboseModuleDeletes) print("delete phase 3");
895  
    removeConcept(m); // generates oStruct
896  
    vmBus_send('moduleDeleted, m);
897  
    if (verboseModuleDeletes) print("delete phase 4");
898  
    pcall {
899  
      S snippetID = m instanceof DynamicModule ? m/DynamicModule.moduleID : "internal_" + shortClassName(m);
900  
      logStructure(deletedModulesLogFile(snippetID), litmap(
901  
        globalID := aGlobalID(),
902  
        deleted := now(),
903  
        module := m));
904  
    }
905  
    //triggerUpdate();
906  
  });
907  
}
908  
909  
svoid visualizeModule(Module m) {
910  
  pcall {
911  
    if (m.vis == null) m.vis = m.visualize();
912  
  }
913  
  pcall {
914  
    if (m.vis == null) m.vis = defaultVisualize(m);
915  
  }
916  
  vmBus_send('moduleVisualized, m);
917  
}
918  
919  
svoid hideModule(final Module m) {
920  
  if (m == null) ret;
921  
  runInSystemQAndWait(r {
922  
    temp m.enter();
923  
    csetAndStatusChange(m, visible := false);
924  
    pcall { m.unvisualize(); }
925  
  });
926  
}
927  
928  
svoid csetAndStatusChange(Module m, O... params) {
929  
  if (cset(m, params) > 0)
930  
    vmBus_send('moduleStatusChange, m, params);
931  
}
932  
933  
svoid revisualizeModule(Module m) {
934  
  pcall {
935  
    if (m == null) ret;
936  
    temp m.enter();
937  
    JInternalFrame frame = getInternalFrame(m.vis);
938  
    if (frame == null) ret;
939  
    m.unvisualize1b();
940  
    m.unvisualize2();
941  
    visualizeModule(m);
942  
    setInternalFrameContents(frame, m.vis);
943  
  }
944  
}
945  
946  
abstract concept Module {
947  
  transient JComponent vis;
948  
  transient bool starting, started, startedWithError;
949  
  transient Lock lock = lock();
950  
  
951  
  static int ALWAYSONTOPWHENPOPPEDOUT = 1;
952  
953  
  bool on = true, visible, poppedOut;
954  
  int flags;
955  
  Rect frameRect;
956  
  int zOrder;
957  
  S iconID;
958  
  PersistableThrowable error;
959  
  int loadOrder;
960  
  
961  
  //transient Set timers;
962  
  
963  
  JComponent visualize() { null; }
964  
  void unvisualize() {
965  
    pcall { unvisualize1(); }
966  
    pcall { unvisualize2(); }
967  
    vmBus_send('moduleUnvisualized, this);
968  
  }
969  
  void enhanceFrame(JInternalFrame frame) {}
970  
  void start() {}
971  
  void unvisualize1() {
972  
    disposeInternalFrame(getInternalFrame(vis));
973  
    unvisualize1b();
974  
  }
975  
  
976  
  void unvisualize1b() {
977  
    grabFrameRect();
978  
    vis = null;
979  
  }
980  
  void unvisualize2() {}
981  
  void update() {}
982  
  
983  
  void grabFrameRect() {
984  
    JInternalFrame f = getInternalFrame(vis);
985  
    if (f != null)
986  
      cset(this, frameRect := toRect(getBounds(f)));
987  
  }
988  
  
989  
  Rect getFrameRect() {
990  
    grabFrameRect();
991  
    ret frameRect;
992  
  }
993  
  
994  
  void cleanMeUp_started() { started = startedWithError = false; }
995  
996  
  void delete() {
997  
    unvisualize();
998  
    cleanUp(this);
999  
    super.delete();
1000  
  }
1001  
1002  
  S sourceCode() {  
1003  
    ret javaxSourceOfMyClass1(shortClassName(this));
1004  
  }
1005  
  
1006  
  // for all modules
1007  
  void triggerUpdate { rstUpdateModules.trigger(); }
1008  
  
1009  
  void setModuleIcon(S iconID) {
1010  
    if (eq(iconID, this.iconID)) ret;
1011  
    this.iconID = iconID;
1012  
    internalFrameIcon(vis, iconID);
1013  
  }
1014  
  
1015  
  O resolve() { ret this; }
1016  
  O getError() { ret error; }
1017  
  S moduleID() { ret str(id); }
1018  
  
1019  
  void setError(Throwable e) {
1020  
    cset(this, error := persistableThrowable(e));
1021  
  }
1022  
  
1023  
  AutoCloseable enter() { null; }
1024  
  
1025  
  JComponent vis() { ret vis; }
1026  
  
1027  
  static bool needsParameters() { false; }
1028  
  
1029  
  S moduleName() {
1030  
    ret humanizeFormLabel(shortClassName(this));
1031  
  }
1032  
  
1033  
  bool hasFlag(int flag) { ret anyCommonBits(flags, flag); }
1034  
  void setFlag(int flag) { _setField(flags := flags | flag); }
1035  
  void clearFlag(int flag) { _setField(flags := flags & ~flag); }
1036  
  
1037  
  // minimum size of JInternalFrame
1038  
  Pt getMinSize() { null; }
1039  
} // END CONCEPT MODULE
1040  
1041  
static JComponent defaultVisualize(Module m) {
1042  
  ret jCenteredMultiLineLabel(renderConcept(m)); 
1043  
}
1044  
1045  
static <A extends Module> A findModule(Class<A> c) {
1046  
  ret findConcept(c, on := true);
1047  
}
1048  
1049  
// ignores snippet ID, just checks for module (inner) class name
1050  
// returns module ID
1051  
sS findDynModuleOfType(S type) {
1052  
  S suffix = "$" + type;
1053  
  DynamicModule m = firstThat(conceptsWhere DynamicModule(on := true), mod -> endsWith(mod._className, suffix));
1054  
  ret m?.moduleID();
1055  
}
1056  
1057  
sbool moduleTypeIs(Module m, S type) {
1058  
  if (m == null) false;
1059  
  ret endsWith(moduleResolvedClassName(m), "$" + type);
1060  
}
1061  
1062  
sS moduleResolvedClassName(Module m) {
1063  
  if (m == null) null;
1064  
  if (m instanceof DynamicModule)
1065  
    ret m/DynamicModule._className;
1066  
  ret className(m);
1067  
}
1068  
1069  
// returns module ID
1070  
sS findClosestModuleTo(O searcher, S type) {
1071  
  JInternalFrame f = getInternalFrame(dm_getVisualization(searcher));
1072  
  if (f == null) null;
1073  
  Pt p = centerOfRect(toRect(getBounds(f)));
1074  
  new Lowest<S> best;
1075  
  for (Module m : onModules()) {
1076  
    JInternalFrame f2 = getInternalFrame(m.vis);
1077  
    if (f2 == null || f2 == f) continue;
1078  
    if (type != null && !moduleTypeIs(m, type)) continue;
1079  
    Rect r2 = toRect(getBounds(f2));
1080  
    best.put(m.moduleID(), rectPointDistance(r2, p));
1081  
  }
1082  
  ret best!;
1083  
}
1084  
1085  
static <A extends Module> L<A> staticModulesOfType(Class<A> type) {
1086  
  ret asList(conceptsWhere(type, on := true));
1087  
}
1088  
1089  
static <A extends Module> L<A> staticModulesOfExactType(Class<A> type) {
1090  
  ret filterByExactType(type, staticModulesOfType(type));
1091  
}
1092  
1093  
static L listModules() {
1094  
  ret map unwrapDynamicModule(onModules());
1095  
}
1096  
1097  
static int moduleCount() {
1098  
  ret l(onModules());
1099  
}
1100  
1101  
static L visibleModules() {
1102  
  ret map unwrapDynamicModule(objectsWhere(onModules(), visible := true));
1103  
}
1104  
1105  
static O unwrapDynamicModule(Module m) {
1106  
  ret m instanceof DynamicModule ? or(m/DynamicModule.o, m) : m;
1107  
}
1108  
1109  
sbool moduleStillThere(O o) {
1110  
  Module m = o instanceof Module ? o/Module : (Module) get(o, '_host);
1111  
  ret isConceptRegistered(mainConcepts, m);
1112  
}
1113  
1114  
static O getDynModuleByID(S moduleID) {
1115  
  if (moduleID == null) null;
1116  
  ret resolveModule(getConcept(Module, parseLong(moduleID)));
1117  
}
1118  
  
1119  
static Module getModuleByID(S moduleID) {
1120  
  if (moduleID == null) null;
1121  
  ret getConcept(Module, parseLong(moduleID));
1122  
}
1123  
  
1124  
sS getInterestingString {
1125  
  InterestingString m = findModule(InterestingString);
1126  
  ret m == null ? getText(tfTopInput) : m.theString;
1127  
}
1128  
1129  
sS modulesSessionGrab() {
1130  
  grabFrameRects();
1131  
  ret struct(ll(programID(), localDateWithMilliseconds())) + "\n"
1132  
    + mainConcepts.xfullgrab();
1133  
}
1134  
1135  
svoid autoSaveModulesSession() {
1136  
  infoBox("Auto-saving session.");
1137  
  S grab;
1138  
  logQuoted(javaxBackupDir(fsI(programID()) + "/auto-saved-sessions.txt"), grab = modulesSessionGrab());
1139  
  infoBox("Auto-save done (" + l(grab) + " chars)");
1140  
}
1141  
1142  
svoid deleteAllModules() {
1143  
  autoSaveModulesSession();
1144  
  deleteConcepts(Module);
1145  
  initialModules();
1146  
}
1147  
1148  
svoid restoreModulesSession(S text) {
1149  
  autoSaveModulesSession();
1150  
  systemStatus.set("shutting down");
1151  
  infoBox("Releasing session");
1152  
  cleanMeUp();
1153  
  cleanUp(mainConcepts);
1154  
  mainConcepts = null;
1155  
  //sleepSeconds(1);
1156  
  infoBox("Loading session");
1157  
  systemStatus.set("loading");
1158  
  mainConcepts = new Concepts().load(dropFirstLine(text));
1159  
  initAfterDBLoad();
1160  
  infoBox("Session restore done");
1161  
}
1162  
1163  
svoid grabFrameRects {
1164  
  for (Module m : onModules()) m.grabFrameRect();
1165  
}
1166  
1167  
concept DynamicModule extends Module {
1168  
  // moduleID is the snippet ID
1169  
  // "className" is taken by DynamicObject; _className == null for old-style dyn module
1170  
  S moduleID, _className;
1171  
  
1172  
  S oStruct; // serialized dynamic object
1173  
  sbool reload_replaceFrame = true;
1174  
  
1175  
  transient Class c;
1176  
  transient O o;
1177  
  transient bool contentsDirty = true;
1178  
  transient ReliableSingleThread rstPersist = rstWithDelay(persistenceDelayPerModule, r persistContents);
1179  
  transient O reloadData; // data held for module during reload
1180  
1181  
  *() {}
1182  
  *(S *moduleID, S *_className) {}
1183  
  *(S *moduleID, S *_className, Class *c) {}
1184  
  
1185  
  static bool needsParameters() { true; }
1186  
    
1187  
  AutoCloseable enter() {
1188  
    ret castForTemp(callOpt(o, 'enter));
1189  
  }
1190  
1191  
  JComponent visualize() {
1192  
    temp enter();
1193  
    ret (JComponent) callOpt(o, 'visualize);
1194  
  }
1195  
  
1196  
  void enhanceFrame(final JInternalFrame f) {
1197  
    final WeakReference<JInternalFrame> fRef = new(f);
1198  
    final WeakReference<DynamicModule> mRef = new(this);
1199  
    S idText = str(id);
1200  
    
1201  
    if (isTrue(vmGeneralMap_get('iconifyBroken)))
1202  
      internalFrameTitlePopupMenuItem(f, "Hide/Minimize", r { hideModule(mRef!) });
1203  
    
1204  
    idText += "/" + moduleLibID();
1205  
    if (!hideFeature("Show source code"))
1206  
      internalFrameTitlePopupMenuItem(f, "Source code [Module ID: " + idText + "]", r-thread { pcall {
1207  
        if (empty(mRef->moduleID)) ret with infoBox("No source code found");
1208  
        dm_openSnippetInEditor(mRef->moduleID);
1209  
      }});
1210  
    
1211  
    internalFrameTitlePopupMenuItem(f, "Reload", r reload);
1212  
    internalFrameTitlePopupMenuItem(f, "Duplicate", rThread { duplicateModule(DynamicModule.this) });
1213  
    if (!hideFeature("Retranspile"))
1214  
      internalFrameTitlePopupMenuItem(f, "Medium Retranspile", rThread { transpileOnServerWithErrorWindow(moduleID, true, r reload) });
1215  
    if (!hideFeature("Pop Out")) internalFrameTitlePopupMenuItem(f, "Pop Out", r {
1216  
      clearFlag(ALWAYSONTOPWHENPOPPEDOUT);
1217  
      stefansOS_popOutModule(DynamicModule.this);
1218  
    });
1219  
    if (!hideFeature("Pop Out + Always On Top")) internalFrameTitlePopupMenuItem(f, "Pop Out + Always On Top", r {
1220  
      setFlag(ALWAYSONTOPWHENPOPPEDOUT);
1221  
      stefansOS_popOutModule(DynamicModule.this);
1222  
    });
1223  
    
1224  
    internalFrameTitlePopupMenu(f, (IVF1<JPopupMenu>) menu -> {
1225  
      LS sisterModules = dm_sisterModules(this);
1226  
      if (empty(sisterModules)) ret;
1227  
      JMenu subMenu = jmenu("Sister modules");
1228  
      for (S mod : sisterModules)
1229  
        addMenuItem(subMenu, dm_moduleName(mod), rThread { dm_showModule(mod) });
1230  
      menu.add(subMenu);
1231  
    });
1232  
    
1233  
    {
1234  
      temp enter();
1235  
      pcallOpt(o, 'enhanceFrame, f);
1236  
    }
1237  
    internalFrameTitle(f, moduleName());
1238  
  }
1239  
  
1240  
  S moduleLibID() {
1241  
    ret moduleID + "/" + afterLastDollar(_className);
1242  
  }
1243  
  
1244  
  S moduleName() {
1245  
    S name = (S) callOpt(o, 'moduleName);
1246  
    if (nempty(name)) ret name;
1247  
    ret originalModuleName();
1248  
  }
1249  
  
1250  
  S originalModuleName() {
1251  
    S title = snippetTitle_cached(moduleID);
1252  
    //ret dropSuffixICTrimOneOf(title, "[Dyn Module]", "[Dyn Module, OK]", "[Dyn Module, shortened]");
1253  
    ret stefansOS_cleanModuleName(title);
1254  
  }
1255  
  
1256  
  void start() {
1257  
    try {
1258  
      start_impl();
1259  
    } catch e {
1260  
      setError(e);
1261  
      _handleException(e);
1262  
    }
1263  
  }
1264  
  
1265  
  void start_impl {
1266  
    if (moduleID == null) ret;
1267  
    if (c == null)
1268  
      c = startModule_reloading && !startModule_doShare
1269  
        ? hotwireModule(moduleID)
1270  
        : hotwireModule_withSharing(moduleID);
1271  
    replaceACCInClassLoader(c, globalACC);
1272  
    if (oStruct != null) pcall {
1273  
      Map<S, O> renames = cast getOpt(c, '_renameClasses);
1274  
      //print("Class renames: " + sfu(renames));
1275  
      S renamed = migrateClassesInStructureText(oStruct, renames);
1276  
      //print("Renamed: " + renamed);
1277  
      
1278  
      // notify module that we are loading (dev.)
1279  
      /*ThreadLocal tlLoading = cast getOpt(getClass(c, "loadableUtils.utils"), 'dynamicObjectIsLoading);
1280  
      temp tempSetTL(tlLoading, true);*/
1281  
      
1282  
      // load
1283  
      o = unstructureInRealm(renamed, c);
1284  
      S className = shortClassName(o);
1285  
      if (eq(className, "DynamicObject"))
1286  
        print("Warning: Module didn't unstructure to target class");
1287  
      else
1288  
        // Update module lib ID after module class rename
1289  
        setField(_className := className(o));
1290  
    }
1291  
    if (o == null)
1292  
      if (_className == null)
1293  
        o = c; // old-style - just a class
1294  
      else {
1295  
        o = nu(getClass_vmName(c, _className)); // new-style (module is an object)
1296  
        if (!stefansOS_checkModuleInstance(o)) { // TODO: doesn't seem to trigger for modules with wrong class name
1297  
          o = null;
1298  
          S msg = this + " failed to load - " + className(o) + " not an instance of DynModule";
1299  
          infoBox(msg);
1300  
          error = persistableThrowable(new RuntimeException(msg));
1301  
          ret;
1302  
        }
1303  
      }
1304  
    setOptAll(o, _host := this, lock := lock);
1305  
    
1306  
    // call module's start() method
1307  
    
1308  
    temp enter();
1309  
1310  
    // this is set when making a module with params
1311  
    callF(startModule_beforeStart, this);
1312  
    
1313  
    // some modules need the reload data before starting
1314  
    if (reloadData != null)
1315  
      callOpt(o, '_setReloadData_early, reloadData);
1316  
1317  
    if (o instanceof Class)
1318  
      callMain(o);
1319  
    else
1320  
      callOpt(o, 'start);
1321  
  }
1322  
  
1323  
  void unvisualize2() { callOpt(o, 'unvisualize); }
1324  
  
1325  
  void update() { callOpt(o, 'update); }
1326  
  
1327  
  // TODO - only when called from DynModule
1328  
  // (works for now, but should be renamed)
1329  
  public void change :: after {
1330  
    vmBus_send moduleChanged(this);
1331  
    contentsDirty = true;
1332  
    if (rstPersist != null)
1333  
      rstPersist.trigger();
1334  
  }
1335  
  
1336  
  void persistContents() enter {
1337  
    if (_concepts != null && contentsDirty) {
1338  
      vmBus_send persistingModuleContents(this);
1339  
      contentsDirty = false;
1340  
      //oStruct = null;
1341  
      pcall {
1342  
        if (o != null && !o instanceof Class) {
1343  
          cset(this, oStruct := struct(o));
1344  
          if (printOnPersistContents)
1345  
            print("Persisted contents: " + moduleID + " - " + l(oStruct) + " chars");
1346  
          callOpt(o, 'onPersisted);
1347  
        }
1348  
      }
1349  
    }
1350  
  }
1351  
  
1352  
  void cleanMeUp() {
1353  
    persistContents();
1354  
    if (verboseCleanUp)
1355  
      print("o: " + className(o) + ". Cleaning up main class: " + mainClass(o));
1356  
    if (mainClass(o) == mc()) // anomalous object
1357  
      cleanUp(o);
1358  
    else enter {
1359  
      if (classLoadedInOtherModule(mainClass(o), this)) {
1360  
        print("KEEPING code (loaded in other module)");
1361  
        cleanUp(o);
1362  
      } else
1363  
        cleanUpObjectAndItsMainClass(o);
1364  
    }
1365  
    o = null;
1366  
    c = null;
1367  
  }
1368  
  
1369  
  void reload() {
1370  
    reloadModuleInBackground(this);
1371  
  }
1372  
  
1373  
  // don't call directly - runs in system queue
1374  
  void reload_impl() {
1375  
    temp tempAddToCollection(modulesBeingReloaded, this);
1376  
    
1377  
    if (reloadData == null) {
1378  
      temp enter();
1379  
      reloadData = callOpt(o, '_getReloadData);
1380  
    }
1381  
1382  
    if (poppedOut) stefansOS_popInModule(this);
1383  
    JInternalFrame frame = getInternalFrame(vis);
1384  
    unvisualize1b();
1385  
    unvisualize2();
1386  
    
1387  
    if (o != null)
1388  
      ghostModules.put(o.getClass(), nu(GhostModule,
1389  
        name := moduleName(),
1390  
        created := created,
1391  
        deleted := now(),
1392  
        instance := new WeakReference(o)));
1393  
1394  
    cleanUp(this); // also sets started to false
1395  
    
1396  
    if (frame != null)
1397  
      setInternalFrameContents(frame,
1398  
        makeReloadingComponent != null
1399  
          ? callF(makeReloadingComponent, this)
1400  
          : makeStandardReloadingComponent(this));
1401  
          
1402  
    visible = false;
1403  
    
1404  
    {
1405  
      temp tempSetMC(startModule_reloading := true);
1406  
      startModule(this);
1407  
    }
1408  
    
1409  
    if (reloadData != null) {
1410  
      temp enter();
1411  
      callOpt(o, '_setReloadData, reloadData);
1412  
      reloadData = null;
1413  
    }
1414  
    
1415  
    if (frame != null) {
1416  
      if (reload_replaceFrame) { // avoids some bugs
1417  
        cset(this, frameRect := toRect(getBounds(frame)));
1418  
        disposeInternalFrame(frame);
1419  
        showModule(this);
1420  
      } else {
1421  
        csetAndStatusChange(this, visible := true);
1422  
        visualizeModule(this);
1423  
        //print("New content: " + vis);
1424  
        setInternalFrameContents(frame, vis);
1425  
      }
1426  
    }
1427  
    
1428  
    if (poppedOut) stefansOS_popOutModule(this);
1429  
1430  
    vmBus_send moduleReloaded(this);
1431  
  }
1432  
  
1433  
  S sourceCode() {  
1434  
    ret loadSnippet(moduleID);
1435  
  }
1436  
  
1437  
  O resolve() { ret o; }
1438  
  O getError() {
1439  
    if (o != null) {
1440  
      O error = callOpt(o, 'getError);
1441  
      if (error != null) ret error;
1442  
    }
1443  
    ret super.getError();
1444  
  }
1445  
  
1446  
  toString {
1447  
    ret "DynModule " + moduleID + "/" + shortenClassName(_className);
1448  
  }
1449  
  
1450  
  void setError(Throwable e) {
1451  
    if (o != null && isTrue(callOpt(o, 'setError, e))) ret;
1452  
    super.setError(e);
1453  
  }
1454  
  
1455  
  Pt getMinSize() {
1456  
    ret shallowCloneToClass Pt(callOpt(o, 'minimumSize));
1457  
  }
1458  
} // END CONCEPT DYNAMICMODULE
1459  
1460  
/*static L resolvedModules() {
1461  
  new L l;
1462  
  for (Module m : onModules())
1463  
    l.add(m.resolve());
1464  
  ret l;
1465  
}*/
1466  
1467  
static S moduleID(Module m) {
1468  
  ret m == null ? null : m.moduleID();
1469  
}
1470  
1471  
static O resolveModule(O m) {
1472  
  ret m instanceof Module ? m/Module.resolve() : m;
1473  
}
1474  
1475  
static S makeModule(Class<? extends Module> moduleClass) {
1476  
  ret makeModule(shortClassName(moduleClass));
1477  
}
1478  
1479  
static S makeModule(S moduleLibID) {
1480  
  ret makeOrShowModule(moduleLibID, false);
1481  
}
1482  
1483  
static S makeOrShowModule(S moduleLibID) {
1484  
  ret makeOrShowModule(moduleLibID, true);
1485  
}
1486  
1487  
sS makeOrShowModule_early(S moduleLibID) {
1488  
  ret makeOrShowModule_early(moduleLibID, true);
1489  
}
1490  
1491  
sS makeOrShowModule(fS moduleLibID, final bool orShow) {
1492  
  ret evalInQ(systemQ, func -> S { // XXX - changed 2019/07/10
1493  
    makeOrShowModule_impl(moduleLibID, orShow)
1494  
  });
1495  
}
1496  
1497  
// add to beginning of system queue
1498  
sS makeOrShowModule_early(fS moduleLibID, bool orShow) {
1499  
  ret evalInQ_first(systemQ, func -> S {
1500  
    makeOrShowModule_impl(moduleLibID, orShow)
1501  
  });
1502  
}
1503  
1504  
sS makeOrShowModule_impl(fS moduleLibID, final bool orShow) {
1505  
  // makes dynamic & static modules
1506  
  
1507  
  if (isIdentifier(moduleLibID))
1508  
    ret moduleID(makeOrShowStaticModuleOfType(moduleLibID, orShow));
1509  
  
1510  
  L<S> l = splitAtSlash(moduleLibID);
1511  
  if (!isSnippetID(first(l)))
1512  
    fail("Unknown module lib ID: " + moduleLibID);
1513  
    
1514  
    
1515  
  // TODO: handle dm_require cycles
1516  
  //if (makingModuleLibIDs.contains(moduleLibID))
1517  
  //temp tempAdd(makingModuleLibIDs, moduleLibID);
1518  
  
1519  
  S snippetID = fsI(first(l)), className = second(l);
1520  
  S classNameSuffix = className == null ? null : "$" + className;
1521  
  DynamicModule m = firstThat(conceptsWhere DynamicModule(on := true, moduleID := snippetID), 
1522  
    mod -> className == null ? mod._className == null : endsWith(mod._className, classNameSuffix));
1523  
  if (m == null) {
1524  
    Class c = hotwireModule_withSharing(snippetID);
1525  
    S fullClassName = c.getName() + classNameSuffix;
1526  
    printVars(+snippetID, +fullClassName, +classNameSuffix, +c);
1527  
    m = cregister(DynamicModule(snippetID, fullClassName, c));
1528  
    print("Made module: " + m.id);
1529  
    vmBus_send('moduleLoaded, m);
1530  
  }
1531  
  if (orShow) showModule(m); else startModule(m);
1532  
  ret moduleID(m);
1533  
}
1534  
1535  
// beforeStart: voidfunc(DynamicModule)
1536  
sS makeNewModule(fS moduleLibID, final bool show, O... _) {
1537  
  temp tempSetMC(startModule_beforeStart := optPar beforeStart(_));
1538  
  ret evalInSystemQ(func -> S {
1539  
    print("Loading module " + moduleLibID);
1540  
    
1541  
    if (isIdentifier(moduleLibID))
1542  
      ret moduleID(makeNewStaticModuleOfType(moduleLibID, show));
1543  
    
1544  
    L<S> l = splitAtSlash(moduleLibID);
1545  
    if (!isSnippetID(first(l)))
1546  
      fail("Unknown module lib ID: " + moduleLibID);
1547  
      
1548  
    S snippetID = first(l), className = second(l);
1549  
1550  
    Class c = hotwireModule_withSharing(snippetID);
1551  
    className = className == null ? null : c.getName() + "$" + className;
1552  
    print(+className);
1553  
    Module m = cregister(DynamicModule(snippetID, className, c));
1554  
    print("Made module: " + m.id);
1555  
    startModule(m);
1556  
    if (show && !stefansOS_shouldStartMinimized(m))
1557  
      showModule(m);
1558  
    ret moduleID(m);
1559  
  });
1560  
}
1561  
1562  
// dynamic only
1563  
sS findModuleByLibID(S moduleLibID) {
1564  
  LS l = splitAtSlash(moduleLibID);
1565  
  if (!isSnippetID(first(l)))
1566  
    fail("Unknown module lib ID: " + moduleLibID);
1567  
    
1568  
  S snippetID = first(l), className = second(l);
1569  
  
1570  
  Cl<DynamicModule> list = findConcepts(DynamicModule, on := true, moduleID := snippetID);
1571  
  S classNameSuffix = className == null ? null : "$" + className;
1572  
  DynamicModule m = firstThat(list, mod -> className == null ? mod._className == null : endsWith(mod._className, classNameSuffix));
1573  
  if (m != null) ret moduleID(m);
1574  
  if (className != null) null;
1575  
  ret moduleID(first(list));
1576  
}
1577  
1578  
static Module makeOrShowStaticModuleOfType(S s) {
1579  
  ret makeOrShowStaticModuleOfType(s, true);
1580  
}
1581  
1582  
static Module makeOrShowStaticModuleOfType(S s, bool orShow) {
1583  
  ret makeOrShowStaticModuleOfType(classForName("main$" + s), orShow);
1584  
}
1585  
  
1586  
static Module makeOrShowStaticModuleOfType(Class<? extends Module> c) {
1587  
  ret makeOrShowStaticModuleOfType(c, true);
1588  
}
1589  
1590  
static Module makeOrShowStaticModuleOfType(Class<? extends Module> c, bool orShow) {
1591  
  final L<? extends Module> l = staticModulesOfExactType(c);
1592  
  Module m = empty(l) ? nu(c) : first(l);
1593  
  if (orShow) showModule(m); else startModule(m);
1594  
  ret m;
1595  
}
1596  
1597  
static Module makeNewStaticModuleOfType(S type, bool show) {
1598  
  Class c = classForName("main$" + type);
1599  
  Module m = cast nu(c);
1600  
  if (show) showModule(m); else startModule(m);
1601  
  ret m;
1602  
}
1603  
1604  
//!include once #1016217 // Sticky Libs
1605  
!include once #1020744 // Sticky Libs & Src Libs
1606  
1607  
static Class hotwireModule(S snippetID) {
1608  
  hotwire_autoStickyLibs();
1609  
  ret hotwire(snippetID, lambda1 mainClassNameForClassLoader);
1610  
}
1611  
1612  
static Class hotwireModule_withSharing(S snippetID) {
1613  
  Class c = null;
1614  
  if (useCodeSharing) {
1615  
    c = findLoadedCodeBySnippetID(snippetID);
1616  
    if (c != null)
1617  
      print("SHARING code for " + snippetID);
1618  
  }
1619  
  if (c == null)
1620  
    c = hotwireModule(snippetID);
1621  
  ret c;
1622  
}
1623  
1624  
// Make modules print with their module ID
1625  
1626  
set flag hotwire_copyOver_extend.
1627  
svoid hotwire_copyOver_extend(Class c) {
1628  
  S progID = getProgramID(c);
1629  
  if (nempty(progID) && fieldType(c, 'print_log) == Appendable.class)
1630  
    setOpt(c, 'print_log, makeSubModulePrint(c, progID));
1631  
}
1632  
1633  
static swappable _SubModulePrint makeSubModulePrint(Class c, S progID) {
1634  
  _SubModulePrint p = new("[" + progID + "] ");
1635  
  p.makePrefix = () ->
1636  
    showTimeInPrintLog ? "[" + progID + " " + timeWithMilliseconds() + "] " : p.prefix;
1637  
  ret p;
1638  
}
1639  
1640  
sbool isLoading() {
1641  
  ret eq(systemStatus!, "loading");
1642  
}
1643  
1644  
sbool isShuttingDown() {
1645  
  ret eq(systemStatus!, "shutting down");
1646  
}
1647  
1648  
svoid doInGlobalContext(final Runnable r) {
1649  
  final new Flag flag;
1650  
  systemQ.add(r {
1651  
    callF(r);
1652  
    flag.raise();
1653  
  });
1654  
  flag.waitUntilUp();
1655  
}
1656  
1657  
!include once #1015842 // SavedSessions
1658  
!include once #1015885 // Standard Modules
1659  
!include once #1015959 // More Standard Modules
1660  
1661  
please include function renderConcept.
1662  
please include function restart.
1663  
1664  
svoid setLookAndFeel() {
1665  
  if (cic(mainArgs, "-nolaf")) ret;
1666  
  new Matches m;
1667  
  S laf = or2(getLAF(), main.laf);
1668  
  if (isSnippetID(laf))
1669  
    runDependent(laf);
1670  
  else if (eq(laf, 'webLAF))
1671  
    installWebLAF();
1672  
  else if (eq(laf, 'nimbus))
1673  
    nimbus();
1674  
  else if (eq(laf, 'jtattoo))
1675  
    jtattoo_mcWin();
1676  
  else if (eq(laf, 'platform))
1677  
    systemLAF();
1678  
  else if (eq(laf, 'substance))
1679  
    call(hotwire(#1025722), 'substance);
1680  
  else if (startsWith_trim(laf, "substance ", m))
1681  
    call(hotwire(#1025722), 'substance, $1);
1682  
  else
1683  
    print("Unknown LAF: " + laf);
1684  
    
1685  
  pcall {
1686  
    S scale = trim(loadTextFile(javaxDataDir("os-font-scale.txt")));
1687  
    if (nempty(scale))
1688  
      swingFontScale(parseDouble(scale));
1689  
  }
1690  
}
1691  
1692  
please include function myTranspilationDate.
1693  
1694  
// should happen in swing thread
1695  
svoid setActiveModule(Module m) {
1696  
  if (activeModule != m) {
1697  
    activeModule = m;
1698  
    vmBus_send('newActiveModule, m);
1699  
  }
1700  
}
1701  
1702  
static O unwrappedActiveModule() {
1703  
  ret unwrapDynamicModule(activeModule);
1704  
}
1705  
1706  
concept TopInput {
1707  
  S text;
1708  
  bool quickSearchesEnabled = true;
1709  
}
1710  
1711  
concept LAF {
1712  
  S laf; // 'platform etc. or module ID
1713  
}
1714  
1715  
svoid nohupJavax(S javaxArgs) {
1716  
  nohupJavax(javaxArgs, javaxDefaultVMArgs());
1717  
}
1718  
1719  
sbool cleanedUp;
1720  
1721  
svoid nohupJavax(S javaxArgs, S vmArgs) {
1722  
  if (desktop != null && !cleanedUp) pcall { fullScreenOff(); }
1723  
  directNohupJavax(javaxArgs, vmArgs);
1724  
}
1725  
1726  
sbool isDevVersion() {
1727  
  ret neq(programID(), #1016478);
1728  
}
1729  
1730  
svoid startOtherVersion {
1731  
  nohupJavax(isDevVersion() ? #1016478 : #1024932);
1732  
}
1733  
1734  
sS otherVersionName() {
1735  
  ret isDevVersion() ? "v6" : "v7";
1736  
}
1737  
1738  
sS restoreModule(S structure) {
1739  
  if (structure == null) null;
1740  
  
1741  
  print(shorten(500, structure));
1742  
  
1743  
  O mod = safeUnstructure(structure);
1744  
  if (mod instanceof Map)
1745  
    mod = get((Map) mod, 'module);
1746  
    
1747  
  S shortName = dynShortName(mod);
1748  
  if (!eq(shortName, "DynamicModule"))
1749  
    fail("Can't restore static modules yet [" + shortName + "]");
1750  
    
1751  
  S snippetID = getString(mod, "moduleID");
1752  
  S className = getString(mod, "_className");
1753  
  
1754  
  print("Restoring " + snippetID + "/" + className);
1755  
  
1756  
  Class c = hotwireModule_withSharing(snippetID);
1757  
  DynamicModule m = cregister(DynamicModule(snippetID, className, c));
1758  
  copyFields(mod, m, 'iconID);
1759  
  m.frameRect = (Rect) restruct(getOpt(m, 'frameRect));
1760  
  m.oStruct = getString(mod, "oStruct");
1761  
  showModule(m);
1762  
  ret moduleID(m);
1763  
}
1764  
1765  
sS moduleStructForDuplication(DynamicModule m) {
1766  
  if (m == null) null;
1767  
  m.persistContents();
1768  
  S struct = struct(m);
1769  
  fO resolved = resolveModule(m);
1770  
  
1771  
  if (hasMethod(resolved, '_modifyStructForDuplication, struct))
1772  
    struct = jreplace_first_dyn(struct, "oStruct=*", func(LS tok, int i) -> S {
1773  
      S s = unquote(tok.get(i+4));
1774  
      s = (S) callOpt(resolved, '_modifyStructForDuplication, s);
1775  
      if (s == null) fail("Module does not want to be duplicated");
1776  
      ret "oStruct=" + quote(s);
1777  
    });
1778  
    
1779  
  ret struct;
1780  
}
1781  
1782  
sS duplicateModule(DynamicModule m) {
1783  
  ret restoreModule(moduleStructForDuplication(m));
1784  
}
1785  
1786  
static O dm_current_mandatory() { fail(); }
1787  
1788  
// for modules
1789  
please include function mechList_opt_raw.
1790  
please include function mechList_clearCache.
1791  
please include function mechLists_clearCache.
1792  
1793  
// This is only answered from localhost
1794  
answer {
1795  
  if "is stefan's os" ret "yes";
1796  
  
1797  
  if "show module * with params *" {
1798  
    ret dm_showModuleWithParams(unstructString($1), unstructObjectArray($2));
1799  
  }
1800  
  
1801  
  if (swic(s, "restore module:", m))
1802  
    ret ok2(restoreModule(m.rest()));
1803  
1804  
  if "swing latency" { ret str(swingLatency()); }
1805  
  
1806  
  if "activate frames" {
1807  
    awt { activateMyFrames(); }
1808  
    ret "OK";
1809  
  }
1810  
  
1811  
  if "program id" ret programID();
1812  
  if "main program id" ret mainProgramID();
1813  
  
1814  
  if "enable remote control from *" {
1815  
    O mod = getDynModuleByID(makeOrShowModule("#1017127/RemoteControlled"));
1816  
    call(mod, 'setFields, new O[] {new O[] {controllingComputers := $1, enabled := true}});
1817  
    ret "OK";
1818  
  }
1819  
  
1820  
  if "stack traces"
1821  
    ret renderAllThreadsWithStackTraces();
1822  
}
1823  
1824  
srecord Service(O module, O worker) {}
1825  
1826  
static new MultiMap<S, Service> registeredServices;
1827  
1828  
static bool callService(S name, O... args) {
1829  
  for (Service service : cloneList(registeredServices.get(name)))
1830  
    if (isTrue(pcallF(service.worker, name, args))) true;
1831  
  false;
1832  
}
1833  
1834  
static void registerService(O module, S name, O service) {
1835  
  registeredServices.put(name, Service(module, service));
1836  
}
1837  
1838  
static void unregisterService(O module, S name, O service) {
1839  
  registeredServices.remove(name, Service(module, service));
1840  
}
1841  
1842  
static O dm_os() { ret main.class; }
1843  
1844  
please include function robot_keyPress.
1845  
please include function robot_keyRelease.
1846  
please include function robot_safetyKeyReleaser.
1847  
1848  
svoid showCurrentModuleMenu {
1849  
  swing {
1850  
    showInternalFramePopupMenu(desktop.getSelectedFrame());
1851  
  }
1852  
}
1853  
1854  
svoid inSystemQ(Runnable r) {
1855  
  systemQ.add(r);
1856  
}
1857  
1858  
svoid reloadModuleInBackground(final DynamicModule m) {
1859  
  if (m == null) ret;
1860  
  vmBus_send reloadingModule(m);
1861  
  inSystemQ(r { m.reload_impl() });
1862  
}
1863  
1864  
svoid deleteModuleInBackground(final DynamicModule m) {
1865  
  if (m == null) ret;
1866  
  inSystemQ(r { deleteModule(m) });
1867  
}
1868  
1869  
svoid restart {
1870  
  if (restarter_override != null)
1871  
    ret with callF(restarter_override);
1872  
  restartWithDefaultVMArgs();
1873  
  sleep();
1874  
}
1875  
1876  
static Component makeStandardReloadingComponent(Module m) {
1877  
  ret jcenteredlabel("Reloading...");
1878  
}
1879  
1880  
sbool classLoadedInOtherModule(Class mainClass, Module mod) {
1881  
  for (DynamicModule m)
1882  
    if (m != mod && mainClass(m.o) == mainClass)
1883  
      true;
1884  
  false;
1885  
}
1886  
1887  
static Class findLoadedCodeBySnippetID(S snippetID) {
1888  
  for (Module m : onModules())
1889  
    if (m cast DynamicModule)
1890  
      if (sameSnippetID(m.moduleID, snippetID) && m.c != null)
1891  
        ret m.c;
1892  
  null;
1893  
}
1894  
1895  
svoid cleanKill {
1896  
  setOpt(javax(), cleanKill_verbose := true);
1897  
  cleanKillVM();
1898  
}
1899  
1900  
sS moduleIDAndName(Module m) {
1901  
  ret m == null ? "-" : m.id + " - " + rcall_pcall moduleName(m);
1902  
}
1903  
1904  
sbool hideFeature(S name) {
1905  
  ret contains(hideFeatures, name);
1906  
}
1907  
1908  
sS featureMenuItem(S name) {
1909  
  ret featureMenuItem(name, name);
1910  
}
1911  
1912  
sS featureMenuItem(S feature, S name) {
1913  
  ret hideFeature(feature) ? null : name;
1914  
}
1915  
1916  
sS osName() { ret or2(osName, "Stefan's OS " + version()); }
1917  
1918  
sS version() { ret ai_versionFromName(programName()); }
1919  
1920  
static IF0<Bool> standardOSExitConfirm() {
1921  
  ret () -> confirmOKCancel("Really exit " + osName() + "?");
1922  
}
1923  
1924  
svoid setLAF(S laf) {
1925  
  cset(uniq(LAF), +laf);
1926  
}
1927  
1928  
sS getLAF() {
1929  
  ret getString laf(conceptWhere(LAF));
1930  
}
1931  
1932  
static TopInput topInputConcept() {
1933  
  ret uniq(TopInput);
1934  
}
1935  
1936  
sbool quickSearchesEnabled() {
1937  
  ret topInputConcept().quickSearchesEnabled;
1938  
}
1939  
1940  
svoid useLastSessionBackup {
1941  
  restoreNextToLastConceptsBackup(dbProgramID());
1942  
  restart();
1943  
}
1944  
1945  
static Settings settings() { ret uniq(Settings); }
1946  
1947  
concept Settings {
1948  
  S backgroundMode = "fit";
1949  
  Color backgroundColor = Color.white;
1950  
}
1951  
1952  
svoid setBackgroundMode(S backgroundMode) { cset(settings(), +backgroundMode); }
1953  
svoid setBackgroundColor(Color backgroundColor) { cset(settings(), +backgroundColor); }
1954  
1955  
svoid subConnectorToChannel(S channel) {
1956  
  connector.sub(channel);
1957  
}

Author comment

Began life as a copy of #1016005

download  show line numbers  debug dex  old transpilations   

Travelled to 96 computer(s): abfyfbgggack, aexrvlgyxxhu, aijbjpqedjjc, aoiabmzegqzx, axwnutwaxmlh, ayivmpnvhhik, bhatertpkbcr, bngzkrcgfjus, btvdylkaqoum, cbybwowwnfue, cecjewutwwoy, cfunsshuasjs, cnewtswnjcpl, dbzfplsxganw, djztyncnmsck, dmudagwnpltw, eiwvkucnqnjw, ekrmjmnbrukm, elvireockksu, fpbaligaclcw, fwldxygvxlem, gfcwnmfwchyu, gwrvuhgaqvyk, hhusmcjygydo, hpgrupgrauku, ilgbwaciyqrp, inmhkjdpuplp, irmadwmeruwu, ishqpsrjomds, iveijnkanddl, ixlofvyxkrco, jatrsapfxtty, jchfcwwgaovw, jcllbfdqhrgy, jozkyjcghlvl, jsbwwwyklurv, jtubtzbbkimh, kanivhkedcyu, keakywteguii, ktbwgngfmivo, kwdqxmbuyord, lastaxpxduqo, lhhfttygyvev, lpdgvwnxivlt, lqnftawlhpir, mowyntqkapby, mplzucoataeu, mqqgnosmbjvj, nazvggbglmsf, nnlgzsuogrvb, nphwexcmpunv, nrkwhpbvqrop, odhhsrjjbcgr, ofpaelxlmzfo, omdjrrnzbjjv, onxytkatvevr, pcsjzfqafodr, poggnhebuplf, pyentgdyhuwx, pzhvpgtvlbxg, qebrsmobutff, qgvkllrfbgaw, qmtsvidgarql, qnjxhkjyztuv, qqauijjrzgml, qsqiayxyrbia, rjpzpeejafvs, skddmizpvtmy, snaazhdonpnp, svlzptffahhm, tosptxptpfyt, tslmcundralx, tvejysmllsmz, twycvekltchr, ubadkicnhrcp, uhjabitqdyqv, umsdtmbpyecw, unoaxrwscvea, uwohonbpqrts, vdksuejmluqn, veepotesqksf, voixwhikvanr, vouqrxazstgt, vtoaovihiybt, vtpnfdczhzww, vzdtmrzilvqm, wdffvflfhhdx, whxojlpjdney, wpzdwgqboxjy, xjedlqssgqex, xktzprzutyxr, xrpafgyirdlv, xvimeffiorjm, zkbeyrirjpvi, zmkyvqxnmjhp, zpmdaxwphzuy

No comments. add comment

Snippet ID: #1016478
Snippet name: Stefan's OS v6
Eternal ID of this version: #1016478/528
Text MD5: c57745a0ec98ffbd8dd3e5cc07e58aea
Transpilation MD5: 13b3c2fa147171618590e3bfd510f516
Author: stefan
Category: javax / stefan's os
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-03-11 01:24:01
Source code size: 59680 bytes / 1957 lines
Pitched / IR pitched: No / No
Views / Downloads: 2547 / 22241
Version history: 527 change(s)
Referenced in: [show references]