Download Jar. Uses 1177K of libraries. Click here for Pure Java version (27941L/221K).
1 | !759 |
2 | |
3 | set flag InOSCore. |
4 | set flag NotifyingPrintLog. |
5 | |
6 | sS defaultBackground = #1101488; //#1101303; //#1101465; //#1101438; //#1101355; // #1009931; |
7 | sS background = defaultBackground; |
8 | sS backgroundMode = 'fit; |
9 | sS mainIconID = #1101432, moduleDefaultIconID = #1101337; |
10 | sS laf; |
11 | static double minLoadScreenShowingTime = 2; |
12 | sbool loadBackgroundLater = true; |
13 | sbool showLoadingScreen = false; |
14 | static JDesktopPane desktop; |
15 | |
16 | static int autoSaveInterval = -10000; // 10 seconds plus slowdown logic |
17 | static int persistenceDelayPerModule = 10000; // 10 seconds |
18 | |
19 | static int systemErrorsToKeep = 10; |
20 | |
21 | static ReliableSingleThread rstUpdateModules = new(r { systemQ.add(r updateModules) }); |
22 | sS lastTopInput; |
23 | static ReliableSingleThread rstTopInputChanged = rstWithDelay(250, r { |
24 | S s = getText(tfTopInput); |
25 | if (neq(lastTopInput, s)) |
26 | vmBus_send('topInputChanged, lastTopInput = s); |
27 | }); |
28 | |
29 | static volatile long updateCycles; |
30 | static L systemErrors = synchroList(); |
31 | static int systemErrors_pointer; |
32 | static new Flag stopRequested; |
33 | static SimpleLiveValue<S> systemStatus = stringLiveValue("loading"); |
34 | static bool firstModuleShown; |
35 | static Map<O, GhostModule> ghostModules = weakHashMap(); // key is main class (if dynamic module) or instance (if static module) |
36 | static Q systemQ; |
37 | static AccessControlContext globalACC; |
38 | static volatile Module activeModule; |
39 | static JTextField tfTopInput; // the input field in the OS menu bar |
40 | static long tfTopInput_dontSelectAll; // sysNow timestamp |
41 | static StefansOS_ConnectToServer connector; |
42 | static Map generalMap = synchroMap(); |
43 | static L<Component> trayAreaComponents = synchroList(); |
44 | sbool printOnPersistContents, verboseCleanUp; |
45 | static JMenuBar menuBar; |
46 | sbool katze_send = true, katze_sendTyped; |
47 | sO makeReloadingComponent; // F1<Module, Component> |
48 | static long startTime; |
49 | |
50 | // if you want other initial modules |
51 | sO initialModules_override; // VF1<OS reference> |
52 | |
53 | static Runnable restarter_override; |
54 | |
55 | p { |
56 | startTime = sysNow(); |
57 | vm_generalMap_put(stefansOS := mc()); |
58 | |
59 | if (!headless()) showControls(jbutton("TROUBLESHOOTING", r { stopRequested.raise() })); |
60 | noRegularGC(); // not while we're loading |
61 | |
62 | if (onLocallyInferiorJavaX()) { |
63 | print("Restarting to use standard JavaX"); |
64 | restart(); |
65 | } |
66 | |
67 | checkMaxWindowBoundsBug(); |
68 | |
69 | if (!eq("0", trim(loadTextFile(javaxDataDir("compile-on-server"))))) |
70 | set hotwire_compileOnServer; |
71 | |
72 | /*if (isLinux() && isRoot()) |
73 | addToDefaultVMArgs("-XX:ThreadPriorityPolicy");*/ |
74 | |
75 | if (java10OrHigher()) { |
76 | addStandardAddOpensFlags(); |
77 | addPermitIllegalAccessesFlag(); |
78 | if (!hasPermitIllegalAccessesFlagInCurrentVM()) { |
79 | print("RESTARTING with proper JDK 11 arguments"); |
80 | restart(); |
81 | } |
82 | } |
83 | |
84 | if (java8OrHigher()) |
85 | addToDefaultVMArgs(smallHeapArgs()); |
86 | |
87 | //laf = 'webLAF; // Let's not generally use it, is sluggish on my machine |
88 | //laf = 'nimbus; |
89 | laf = 'platform; |
90 | |
91 | //if (isMac()) laf = 'platform; // because https://github.com/michael-hagen/JTattoo/issues/1 |
92 | if (isMac()) vmGeneralMap_set('iconifyBroken, true); |
93 | if (isLinux()) laf = 'jtattoo; |
94 | |
95 | /*if (vmArgs().contains("-XX:+PrintAssembly")) pcall { |
96 | teeSystemOutAndErrToFile(programFile("os.log")); |
97 | }*/ |
98 | |
99 | if (!hasClass("x30_pkg.x30_util")) { |
100 | if (!zipFileContains_falseOnError(pathToJavaxJar(), "x30_pkg/x30_util.class")) |
101 | upgradeJavaXAndRestart(); |
102 | else |
103 | restart(); |
104 | } |
105 | |
106 | _handleException_addHandler(voidfunc(Throwable e) { |
107 | try { |
108 | synchronized(systemErrors) { |
109 | listSet(systemErrors, systemErrors_pointer, e); |
110 | systemErrors_pointer = (systemErrors_pointer+1) % systemErrorsToKeep; |
111 | } |
112 | } catch e2 { |
113 | printStackTrace(e2); |
114 | } |
115 | infoBox("Error: " + exceptionToStringShort(e)); |
116 | LastErrors lastErrors = first(staticModulesOfType(LastErrors)); |
117 | if (lastErrors != null) lastErrors.addError(e); |
118 | }); |
119 | |
120 | timeJumpDetector(); |
121 | |
122 | vm_generalMap_put('consoleInUse, true); // bots made by modules should not handle console |
123 | |
124 | monitorThreadAllocatedMemory(); |
125 | |
126 | // Solve deadlocks every 10 to be sure |
127 | doEvery(10000, r printDeadlocksAndSolve); |
128 | |
129 | print("Data dir: " + javaxDataDir()); |
130 | vm_setGlobalACC(globalACC = acc_current()); |
131 | |
132 | if (swic(activateFramesOf(programIDPlusHome()), "OK")) { |
133 | print("OS already running!"); |
134 | cleanKill(); |
135 | } |
136 | |
137 | framesBot(); |
138 | |
139 | makeBot("Stefan's OS."); |
140 | |
141 | S printLogSize = trim(loadTextFile(javaxDataDir("os-print-log-size.txt"))); |
142 | if (isInteger(printLogSize)) printLogMaxChars(parseInt(printLogSize)); |
143 | |
144 | vm_generalMap_put('newSwingComponentRegistry, voidfunc(Component c) { |
145 | allAWTComponents_extraList.add(c) |
146 | }); |
147 | |
148 | connector = new StefansOS_ConnectToServer; |
149 | connector.start(); |
150 | |
151 | //substance(); |
152 | final SimpleLiveValue<S> lvDetails = stringLiveValue(); |
153 | lvDetails.onChange(r { print(lvDetails!) }); |
154 | stefansOS_loadingAnimation_fullScreen = startInFullScreen() && !isWindows() /* bug */; |
155 | final Component loadingAnim = showLoadingScreen ? stefansOS_loadingAnimation(r { |
156 | stopRequested.raise() |
157 | }, lvDetails) : null; |
158 | |
159 | try { |
160 | long start = sysNow(); |
161 | systemQ = startQ("System Q"); |
162 | useDBOf(#1015871); |
163 | lvDetails.set("Loading database"); |
164 | db(autoSaveInterval); |
165 | if (!headless()) { |
166 | // if you use Processing |
167 | JPopupMenu.setDefaultLightWeightPopupEnabled(false); |
168 | |
169 | lvDetails.set("Loading background"); |
170 | background = or2(trim(loadTextFile(javaxDataDir("os-background.txt"))), background); |
171 | if (!isSnippetID(background)) |
172 | background = fileToURI(new File(background)); |
173 | try { |
174 | if (eq(backgroundMode, 'fit)) |
175 | desktop = loadBackgroundLater |
176 | ? jDesktopPaneWithFitPicture_smooth_cacheScaled_loadLater(background) |
177 | : jDesktopPaneWithFitPicture_smooth_cacheScaled(background); |
178 | else |
179 | desktop = jDesktopPaneWithSkyPicture/*_autoUnload*/(background, Color.black); |
180 | } catch print e { |
181 | desktop = jDesktopPaneWithFitPicture_smooth(defaultBackground); |
182 | } |
183 | setMainDesktopPane(desktop); |
184 | autoFixDesktopPane(desktop); |
185 | |
186 | // Allow frame switching from AI bar & similar components |
187 | installInternalFrameSwitcher_v3(desktop).shouldSwitch = |
188 | func -> bool { sameComponentOrDeepChildOf(getFocusOwner(), menuBar) }; |
189 | } |
190 | |
191 | long ms = toMS(minLoadScreenShowingTime); |
192 | long remaining = start+ms-sysNow(); |
193 | if (remaining <= 0) |
194 | lvDetails.set("Done loading"); |
195 | else { |
196 | S seconds = formatDouble(toSeconds(remaining), 1); |
197 | lvDetails.set("Done loading, but will wait if you hit the troubleshooting button for " + seconds + " more second" + (eq(seconds, "1") ? "" : "s")); |
198 | } |
199 | //if (loadingAnim != null) |
200 | waitUntilSysTimeOrFlag(start+ms, stopRequested); |
201 | } catch e { |
202 | _handleException(e); |
203 | stopRequested.raise(); |
204 | } |
205 | |
206 | try { |
207 | bool flag = stopRequested.isUp(); // get before closing animation |
208 | if (flag) |
209 | ret with showFrame("Stop screen", |
210 | centerAndSouthWithMargins( |
211 | jcenteredlabel("More troubleshooting options will go here."), |
212 | jcenteredbuttons( |
213 | "Start Stefan's OS normally", r restart, |
214 | "Switch to " + otherVersionName(), r startOtherVersion, |
215 | "Delete session", disableButtonWhileCalcing(func -> bool { |
216 | if (!fileExists(conceptsFile())) |
217 | ret false with infoBox("Session already empty."); |
218 | if (!confirmOKCancel("Really delete your current session?")) false; |
219 | cleanMeUp_concepts(); |
220 | renameFileToSomeBackupName(conceptsFile()); |
221 | infoBox("Session deleted. Starting again."); |
222 | disableAllButtonsInWindow(heldInstance(JButton)); |
223 | sleepSeconds(3); |
224 | restart(); |
225 | false; |
226 | })))); |
227 | |
228 | //autoRestart(); |
229 | thread { serverAutoRestartMD5(); } // just a short ping |
230 | |
231 | pcall { setLookAndFeel(); } |
232 | |
233 | showDesktop(); |
234 | } finally { |
235 | disposeWindow(loadingAnim); |
236 | } |
237 | |
238 | initAfterDBLoad(); |
239 | setOpt(javax(), regularGC_firstDelay := 60000); |
240 | call(javax(), 'regularGC); |
241 | if (!headless()) { |
242 | final NotTooOften hourlyGC = onlyEveryHour(); |
243 | setOpt(javax(), regularGC_condition := func -> bool { |
244 | if (hourlyGC! || isInForeground(desktop)) |
245 | ret true with print("GC"); |
246 | else |
247 | ret false with print("Skipping GC (not in foreground)"); |
248 | }); |
249 | } |
250 | hideConsole(); |
251 | manualConsole(); |
252 | //clearConsole(); |
253 | if (headless()) sleep(); |
254 | } |
255 | |
256 | sbool startInFullScreen() { |
257 | ret eq("1", trim(loadTextFile(javaxDataDir("start-os-in-full-screen.txt")))); |
258 | } |
259 | |
260 | svoid setStartInFullScreen(bool b) { |
261 | saveTextFile(javaxDataDir("start-os-in-full-screen.txt"), b ? "1" : "0"); |
262 | } |
263 | sbool showDesktop_first = true; |
264 | |
265 | svoid showDesktop { |
266 | if (headless()) ret; |
267 | bool done = false; |
268 | |
269 | S title = programName(); |
270 | S subDir = javaxVirtualSpaceName(); |
271 | if (subDir != null) title = "[" + subDir + "] " + title; |
272 | |
273 | if (showDesktop_first && startInFullScreen()) pcall { |
274 | showFullScreen(title, desktop); |
275 | done = true; |
276 | } |
277 | |
278 | if (!done) { |
279 | showMaximizedFrame(title, desktop); |
280 | titlePopupMenu_top(desktop, voidfunc(JPopupMenu menu) { |
281 | addMenuItems(menu, |
282 | "New Session", rThreadPcallMessageBox(r deleteAllModules), |
283 | "Restore Initial Modules", r initialModules, |
284 | ); |
285 | }); |
286 | } |
287 | |
288 | registerFunctionKey(getFrame(desktop), 1, r { requestFocus(tfTopInput) }); |
289 | |
290 | fillMenuBar(); |
291 | doNothingOnClose(getFrame(desktop)); |
292 | frameIcon(mainIconID, desktop); |
293 | showDesktop_first = false; |
294 | cleanExitOnFrameClose_ifStillInSameFrame(desktop); |
295 | } |
296 | |
297 | sbool inFullScreen() { |
298 | ret isFullScreen(desktop); |
299 | } |
300 | |
301 | svoid fullScreenOff() { |
302 | if (inFullScreen()) fullScreenOnOff(); |
303 | } |
304 | |
305 | svoid fullScreenOnOff { |
306 | // Don't screw up window positions while adjusting from/to fullscreen |
307 | autoFixDesktopPane_exclude.add(desktop); |
308 | temp tempAfterwards(r { autoFixDesktopPane_exclude.remove(desktop) }); |
309 | |
310 | Window w = getWindow(desktop); |
311 | if (!inFullScreen()) { |
312 | showFullScreen(frameTitle(desktop), desktop); |
313 | pcall { frameIcon(mainIconID, desktop); } |
314 | cleanExitOnFrameClose_ifStillInSameFrame(desktop); |
315 | fillMenuBar(); |
316 | setStartInFullScreen(true); |
317 | } else { |
318 | removeFromParent(desktop); |
319 | showDesktop(); |
320 | setStartInFullScreen(false); |
321 | } |
322 | |
323 | // Allow closing empty "zombie" windows (why do we have these?) |
324 | final JFrame f = getFrame(desktop); |
325 | onFrameClosing(f, r { if (isEmptyFrame(f)) { |
326 | removeListener(); |
327 | disposeWindow(f); |
328 | }}); |
329 | |
330 | disposeWindow(w); |
331 | fixDesktopPane(desktop); |
332 | } |
333 | |
334 | svoid updateMenuBar() swing { |
335 | //temp tempRememberFocusedComponent(); |
336 | JMenuBar mb = getMenuBar(desktop); |
337 | if (mb == null) { |
338 | mb = addMenuBar(desktop); |
339 | mb.setLayout(new javax.swing.plaf.basic.DefaultMenuLayout(menuBar, BoxLayout.X_AXIS)); |
340 | } |
341 | keepComponentsByPred(mb, func(Component c) -> bool { |
342 | c instanceof JMenu || c == tfTopInput |
343 | }); |
344 | //clearMenuBar(); |
345 | fillMenuBar(); |
346 | } |
347 | |
348 | svoid fillMenuBar() swing { |
349 | menuBar = addMenuBar(desktop); |
350 | set jmenuItem_newThreads; |
351 | S version = ai_versionFromName(programName()); |
352 | final bool dev = isDevVersion(); |
353 | S name = "Stefan's OS " + version; |
354 | //S subDir = userHomeSubDirName(); |
355 | //if (subDir != null) name += " [" + subDir + "]"; |
356 | addMenu(desktop, trim(name), |
357 | "Screenshot", r stefansOS_screenshot, |
358 | "Full screen on/off", r fullScreenOnOff, |
359 | "Switch to " + otherVersionName(), r { |
360 | innerCleanUp(); |
361 | startOtherVersion(); |
362 | cleanKill(); |
363 | }, |
364 | "System Version", r { makeOrShowModule("#1016442/SystemVersion") }, |
365 | "---", |
366 | "Restart Stefan's OS", r { showConsole(); restart(); }, |
367 | "Exit", r cleanKill |
368 | ); |
369 | |
370 | addMenu(desktop, "Current Module", |
371 | "Show Menu", r showCurrentModuleMenu); |
372 | |
373 | addMenu(desktop, "Modules", |
374 | "Other Module...", r stefansOS_addDynamicModuleDialog, |
375 | "---", |
376 | jDynamicScrollingMenu("All Modules", voidfunc(JPopupMenu menu) { |
377 | for (final Module m : sortedByMethodIC('moduleName, onModules())) |
378 | addMenuItem(menu, m.moduleName(), rThread { showModule(m) }); |
379 | }), |
380 | "Welcome Screen", r { makeOrShowModule("#1016067/WelcomeScreen") }, |
381 | "Quick Module Search", r addQuickModuleSearch, |
382 | //"Hello (input field for everything)", r { makeOrShowModule("Hello") }, |
383 | "Task Bar", r { makeOrShowModule("#1019712/TaskBar_dev") }, |
384 | "System Print Log", r { makeOrShowModule("#1016189/SystemPrintLog") }, |
385 | jmenu("Internal Types", map(myNonAbstractClassesImplementing(Module), func(final Class c) -> JMenuItem { |
386 | jMenuItem(shortClassName(c), rThread { makeOrShowStaticModuleOfType(c) }) |
387 | })), |
388 | "Module Classes", r { makeOrShowStaticModuleOfType(ModuleClasses) }, |
389 | ); |
390 | |
391 | // TODO - need to generate menu items differently in enhanceFrame |
392 | //addFullyDynamicMenu(desktop, "Current module", |
393 | |
394 | addMenu(desktop, "More", |
395 | "Start External JavaX Program...", r stefansOS_startExternalJavaXProgram, |
396 | "---", |
397 | "Find memory leaks (PID: " + getPID() + ")", r stefansOS_findMemoryLeaks, |
398 | "Computer ID: " + computerID(), r { copyTextToClipboard_infoBox(computerID()) }, |
399 | "Show console", rThread showConsole, |
400 | "Remove moduleless frames", rThread dm_closeModuleLessFrames); |
401 | |
402 | // Add the fancy stuff |
403 | |
404 | JMenuBar menuBar = cast call(getFrame(desktop), 'getJMenuBar); |
405 | |
406 | if (tfTopInput == null) { |
407 | tfTopInput = jcenteredtextfield(uniq(TopInput).text); |
408 | setFontSize(tfTopInput, 16); |
409 | selectAllOnFocusIf(tfTopInput, func -> bool { |
410 | elapsedTime(tfTopInput_dontSelectAll) >= 2000 |
411 | }); |
412 | onChange(tfTopInput, r { |
413 | cset(uniq(TopInput), text := getText(tfTopInput)); |
414 | rstTopInputChanged.trigger(); |
415 | }); |
416 | onEnter(tfTopInput, r { |
417 | S info = cast generalMap.get('topInputInfo); |
418 | temp dm_generalMap_tempPut(topInputInfo := or2(info, "typed")); |
419 | S text = getText(tfTopInput); |
420 | vmBus_send('topInput, text); |
421 | if (katze_send) |
422 | if (nempty(info)) |
423 | katze_userSaid(info, text); |
424 | else if (katze_sendTyped) |
425 | katze_userTyped(text); |
426 | }); |
427 | } |
428 | |
429 | if (getParent(tfTopInput) == null) { |
430 | menuBar.add(Box.createHorizontalStrut(20)); |
431 | menuBar.add(tfTopInput); |
432 | } |
433 | |
434 | if (!containsChildOfType(menuBar, JLabel.class)) { |
435 | //menuBar.add(Box.createHorizontalGlue()); |
436 | menuBar.add(Box.createHorizontalStrut(5)); |
437 | menuBar.add(onClick(setToolTip([[Simulate pressing Enter key in input field to the left ("AI bar")]], jimage(#1101426)), r { simulateEnter(tfTopInput) })); |
438 | //menuBar.add(jhgrid(null, tfTopInput)); |
439 | //menuBar.add(jhgrid(tfTopInput, null)); |
440 | menuBar.add(Box.createHorizontalStrut(20)); |
441 | for i over trayAreaComponents: { |
442 | Component c = trayAreaComponents.get(i); |
443 | continue if c == null; |
444 | menuBar.add(c); |
445 | menuBar.add(Box.createHorizontalStrut(i == l(trayAreaComponents)-1 ? 20 : 6)); |
446 | } |
447 | menuBar.add(jLiveValueLabel(clockTimeLiveValue())); |
448 | menuBar.add(Box.createHorizontalStrut(6)); |
449 | } |
450 | } |
451 | |
452 | svoid addQuickModuleSearch { |
453 | makeOrShowModule("#1016702/LoadedModuleSearch"); |
454 | makeOrShowModule("#1016932/ServerModuleSearch"); |
455 | } |
456 | |
457 | static tempDisposeInternalFrame_obj<JLabel> tempBusyAnimation(fS text) { |
458 | ret vmExiting() ? null : tempBusyAnimation(stringLiveValue(text)); |
459 | } |
460 | |
461 | static tempDisposeInternalFrame_obj<JLabel> tempBusyAnimation(LiveValue<S> text) { |
462 | if (headless()) null; |
463 | final JLabel anim = jBackground(Color.white, jAnimation_liveValueText(#1101316, text)); |
464 | swing { |
465 | addInternalFrame_dontSelect.set(true); |
466 | addInternalFrame_layer.set(JLayeredPane.POPUP_LAYER); |
467 | addInternalFrame(desktop, "", null, anim); |
468 | packInternalFrameInTopRightCorner(anim); |
469 | JInternalFrame f = getInternalFrame(anim); |
470 | //print("Have busy animation: " + f + " in " + getParent(f)); |
471 | } |
472 | ret tempDisposeInternalFrame(anim); |
473 | } |
474 | |
475 | svoid allRegularFixes { |
476 | applyStandardSwingFixes(); |
477 | cleanDefunctACCsInAllThreads(); |
478 | cleanDefunctACCsInAllSwingComponents(); |
479 | } |
480 | |
481 | svoid gcWithFixes { |
482 | allRegularFixes(); |
483 | gc(); |
484 | allRegularFixes(); |
485 | } |
486 | |
487 | svoid initAfterDBLoad { |
488 | doEvery(30000, r allRegularFixes); |
489 | doEvery(600000, r clearSnippetTitleCacheIfOnline); |
490 | set cleanUp_interruptThreads; |
491 | |
492 | // for Java Chrome |
493 | classForNameOpt("java.util.prefs.FileSystemPreferences"); |
494 | |
495 | SimpleLiveValue<S> lvText = stringLiveValue(jlabel_textAsHTML_center("Restoring Session")); |
496 | temp final tempDisposeInternalFrame_obj<JLabel> anim = tempBusyAnimation(lvText); |
497 | if (anim != null) { |
498 | onResizeAndNow(anim.component, r { |
499 | setVerticalAlignment( |
500 | anim.component.getHeight() >= 150 ? JLabel.CENTER : JLabel.TOP, |
501 | anim.component) |
502 | }); |
503 | growInternalFrameLeft(anim.component, 50); |
504 | growInternalFrameSouth(anim.component, 50); |
505 | } |
506 | |
507 | initialModules(); |
508 | |
509 | UpdateCycles uc = conceptWhere(UpdateCycles); |
510 | if (uc != null) updateCycles = uc.value; |
511 | |
512 | stefansOS_installQuickSearchHelper(); |
513 | |
514 | L<Module> modules = startOrder(onModules()); |
515 | int i = 0; |
516 | for (Module m : modules) { |
517 | if (isShuttingDown()) ret; |
518 | ++i; |
519 | lvText.set(jlabel_textAsHTML_center( |
520 | "Starting module " + i + "/" + l(modules) + ":\n" |
521 | + m.moduleName())); |
522 | startModule(m); |
523 | } |
524 | |
525 | /*addConceptIndex(simpleConceptIndex(rstUpdateModules)); |
526 | rstUpdateModules.trigger();*/ |
527 | |
528 | if (isShuttingDown()) ret; |
529 | systemStatus.set("running"); |
530 | print("== OS BOOTED IN " + iceil(elapsedSeconds(/*vmStartTime_sys()*/startTime)) + " SECONDS =="); |
531 | } |
532 | |
533 | static L<Module> startOrder(L<Module> modules) { |
534 | ret sortedByComparator( |
535 | combineComparators( |
536 | main.<Module> descFieldComparator('visible), |
537 | main.<Module> fieldComparator('zOrder)), |
538 | modules); |
539 | } |
540 | |
541 | svoid initialModules { |
542 | if (initialModules_override != null) |
543 | ret with pcallF(initialModules_override, mc()); |
544 | |
545 | if (headless()) { |
546 | makeOrShowModule("#1016576/ConnectToServer"); |
547 | ret; |
548 | } |
549 | |
550 | if (empty(onModules())) { |
551 | if (isDevVersion()) |
552 | showModule(new DynamicModule(#1016081, 'main$WelcomeScreen)); |
553 | else |
554 | showModule(new DynamicModule(#1016067, 'main$WelcomeScreen)); |
555 | showModule_noFocus(getModuleByID(makeModule("#1018866/SystemPrintLog"))); |
556 | showModule_noFocus(getModuleByID(makeModule("#1019954/TaskBar_dev"))); |
557 | //makeModule("#1016872/SnippetsDB"); |
558 | makeModule("#1016932/ServerModuleSearch"); |
559 | makeModule("#1016702/LoadedModuleSearch"); |
560 | //makeModule("#1018602/QuickAudioRecord"); |
561 | makeModule("#1019326/WitAILastRecording"); |
562 | makeModule("#1019400/SpeechRecogConfirmation"); |
563 | } |
564 | } |
565 | |
566 | svoid triggerUpdate { rstUpdateModules.trigger(); } |
567 | |
568 | // not done anymore |
569 | svoid updateModules { |
570 | /*++updateCycles; |
571 | for (Module m : onModules()) |
572 | updateModule(m);*/ |
573 | } |
574 | |
575 | svoid updateModule(Module m) { |
576 | if (m == null) ret; |
577 | temp m.enter(); |
578 | pcall { m.update(); } |
579 | } |
580 | |
581 | svoid updateModules(final Collection<Module> l) { |
582 | systemQ.add(r { |
583 | for (Module m : unnull(l)) updateModule(m); |
584 | }); |
585 | } |
586 | |
587 | svoid saveZOrder { |
588 | for (Module m) |
589 | cset(m, zOrder := getComponentZOrder(getInternalFrame(m.vis))); |
590 | } |
591 | |
592 | svoid cleanMeUp { |
593 | saveZOrder(); |
594 | autoConsole(); |
595 | showConsole(); |
596 | killProgram(#1019683); // stop watch dog |
597 | systemStatus.set("shutting down"); |
598 | temp tempBusyAnimation("Shutting Down"); |
599 | preCleanUp(list(Module)); |
600 | for (Module m) { |
601 | if (m.vis != null) pcall { |
602 | m.unvisualize(); |
603 | } |
604 | cleanUp(m); |
605 | } |
606 | cleanedUp = true; |
607 | } |
608 | |
609 | static L<Module> onModules() { ret conceptsWhere(Module, on := true); } |
610 | |
611 | sbool hasModuleWithFields(Class<? extends Module> c, O... params) { |
612 | ret hasConcept(c, concatArrays(new O[] {on := true}, params)); |
613 | } |
614 | |
615 | svoid startModule(Module m) { ping(); pcall { |
616 | //addIfNotThere(modules, m); |
617 | temp m.enter(); |
618 | if (m.started) ret; |
619 | m.started = true; |
620 | print("Starting module " + m.moduleName()); |
621 | try { |
622 | m.start(); |
623 | } catch e { |
624 | m.setError(e); |
625 | _handleException(e); |
626 | } |
627 | vmBus_send('moduleStarted, m.moduleID()); |
628 | rstUpdateModules.trigger(); |
629 | if (m.visible) showModule(m); |
630 | }} |
631 | |
632 | static Module showModule(final Module m) { |
633 | ret showModule(m, true); |
634 | } |
635 | |
636 | static Module showModule_noFocus(final Module m) { |
637 | ret showModule(m, false); |
638 | } |
639 | |
640 | svoid runInSystemQAndWait(Runnable r) { |
641 | if (isAWTThread()) ret with callF(r); |
642 | runInQAndWait(systemQ, r); |
643 | } |
644 | |
645 | static Module showModule(final Module m, final bool focus) { |
646 | if (m == null) ret m; |
647 | runInSystemQAndWait(r { |
648 | startModule(m); |
649 | if (headless()) ret; |
650 | temp m.enter(); |
651 | if (m.vis != null) { |
652 | if (focus && !isLoading()) |
653 | activateInternalFrame(m.vis); |
654 | ret; |
655 | } |
656 | csetAndStatusChange(m, visible := true); |
657 | visualizeModule(m); |
658 | if (m.vis != null) swing { |
659 | Rect r = m.frameRect; |
660 | /*if (r == null) r = randomRect(desktop.getWidth(), desktop.getHeight(), 10, 150, 100); |
661 | if (r == null) r = Rect(10, 10, 200, 100); |
662 | print("Showing frame at " + r);*/ |
663 | S frameTitle = m.moduleName(); |
664 | final JInternalFrame f; |
665 | bool toBack = isLoading() && firstModuleShown; |
666 | bool activate = focus && !toBack; |
667 | { |
668 | temp tempSetThreadLocal(addInternalFrame_toBack, toBack); |
669 | temp tempSetThreadLocal(addInternalFrame_dontSelect, !activate); |
670 | f = showInternalFrame(desktop, frameTitle, r, m.vis); |
671 | set firstModuleShown; |
672 | } |
673 | if (r == null) centerPackInternalFrame(f); |
674 | f.setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE); |
675 | |
676 | onInternalFrameIconified(f, r { hideModule(m) }); |
677 | onInternalFrameClosing(f, r { deleteModule(m) }); |
678 | onInternalFrameActivated(f, r { setActiveModule(m) }); |
679 | onInternalFrameDeactivated(f, r { if (activeModule == m) setActiveModule(null) }); |
680 | internalFrameIcon(f, or2(m.iconID, moduleDefaultIconID)); |
681 | m.enhanceFrame(f); |
682 | if (activate) setActiveModule(m); |
683 | } |
684 | }); |
685 | ret m; |
686 | } |
687 | |
688 | svoid showModules(L<? extends Module> l) { |
689 | for (Module m : unnull(l)) showModule(m); |
690 | } |
691 | |
692 | sbool deleteModule(final Module m) { |
693 | pcall { |
694 | bool warn = isTrue(callOpt(resolveModule(m), 'warnOnDelete)); |
695 | if (warn && !confirmOKCancel("Really delete module " + m + "?")) |
696 | false; |
697 | } |
698 | runInSystemQAndWait(r { |
699 | O m2 = unwrapDynamicModule(m); |
700 | vmBus_send('deletingModule, m2); |
701 | ghostModules.put(m == m2 ? m : m2.getClass(), nu(GhostModule, |
702 | name := m.moduleName(), |
703 | created := m.created, |
704 | deleted := now(), |
705 | instance := new WeakReference(m2))); |
706 | pcall { m.unvisualize(); } |
707 | removeConcept(m); // generates oStruct |
708 | vmBus_send('moduleDeleted, m); |
709 | pcall { |
710 | S snippetID = m instanceof DynamicModule ? m/DynamicModule.moduleID : "internal_" + shortClassName(m); |
711 | logStructure(deletedModulesLogFile(snippetID), litmap( |
712 | globalID := aGlobalID(), |
713 | deleted := now(), |
714 | module := m)); |
715 | } |
716 | //triggerUpdate(); |
717 | }); |
718 | true; |
719 | } |
720 | |
721 | svoid visualizeModule(Module m) { |
722 | pcall { |
723 | if (m.vis == null) m.vis = m.visualize(); |
724 | } |
725 | pcall { |
726 | if (m.vis == null) m.vis = defaultVisualize(m); |
727 | } |
728 | vmBus_send('moduleVisualized, m); |
729 | } |
730 | |
731 | svoid hideModule(final Module m) { |
732 | if (m == null) ret; |
733 | runInSystemQAndWait(r { |
734 | temp m.enter(); |
735 | csetAndStatusChange(m, visible := false); |
736 | pcall { m.unvisualize(); } |
737 | }); |
738 | } |
739 | |
740 | svoid csetAndStatusChange(Module m, O... params) { |
741 | if (cset(m, params) > 0) |
742 | vmBus_send('moduleStatusChange, m, params); |
743 | } |
744 | |
745 | svoid revisualizeModule(Module m) { |
746 | pcall { |
747 | if (m == null) ret; |
748 | temp m.enter(); |
749 | JInternalFrame frame = getInternalFrame(m.vis); |
750 | if (frame == null) ret; |
751 | m.unvisualize1b(); |
752 | m.unvisualize2(); |
753 | visualizeModule(m); |
754 | setInternalFrameContents(frame, m.vis); |
755 | } |
756 | } |
757 | |
758 | abstract concept Module { |
759 | transient JComponent vis; |
760 | transient bool started; |
761 | transient Lock lock = lock(); |
762 | |
763 | bool on = true, visible; |
764 | Rect frameRect; |
765 | int zOrder; |
766 | S iconID; |
767 | PersistableThrowable error; |
768 | |
769 | //transient Set timers; |
770 | |
771 | JComponent visualize() { null; } |
772 | void unvisualize() { |
773 | pcall { unvisualize1(); } |
774 | pcall { unvisualize2(); } |
775 | vmBus_send('moduleUnvisualized, this); |
776 | } |
777 | void enhanceFrame(JInternalFrame frame) {} |
778 | void start() {} |
779 | void unvisualize1() { |
780 | disposeInternalFrame(getInternalFrame(vis)); |
781 | unvisualize1b(); |
782 | } |
783 | |
784 | void unvisualize1b() { |
785 | grabFrameRect(); |
786 | vis = null; |
787 | } |
788 | void unvisualize2() {} |
789 | void update() {} |
790 | |
791 | void grabFrameRect() { |
792 | JInternalFrame f = getInternalFrame(vis); |
793 | if (f != null) |
794 | cset(this, frameRect := toRect(getBounds(f))); |
795 | } |
796 | |
797 | Rect getFrameRect() { |
798 | grabFrameRect(); |
799 | ret frameRect; |
800 | } |
801 | |
802 | void cleanMeUp_started() { started = false; } |
803 | |
804 | void delete() { |
805 | unvisualize(); |
806 | cleanUp(this); |
807 | super.delete(); |
808 | } |
809 | |
810 | S sourceCode() { |
811 | ret javaxSourceOfMyClass1(shortClassName(this)); |
812 | } |
813 | |
814 | // for all modules |
815 | void triggerUpdate { rstUpdateModules.trigger(); } |
816 | |
817 | void setModuleIcon(S iconID) { |
818 | if (eq(iconID, this.iconID)) ret; |
819 | this.iconID = iconID; |
820 | internalFrameIcon(vis, iconID); |
821 | } |
822 | |
823 | O resolve() { ret this; } |
824 | O getError() { ret error; } |
825 | S moduleID() { ret str(id); } |
826 | |
827 | void setError(Throwable e) { |
828 | cset(this, error := persistableThrowable(e)); |
829 | } |
830 | |
831 | AutoCloseable enter() { null; } |
832 | |
833 | JComponent vis() { ret vis; } |
834 | |
835 | static bool needsParameters() { false; } |
836 | |
837 | S moduleName() { |
838 | ret humanizeFormLabel(shortClassName(this)); |
839 | } |
840 | } // END CONCEPT MODULE |
841 | |
842 | static JComponent defaultVisualize(Module m) { |
843 | ret jCenteredMultiLineLabel(renderConcept(m)); |
844 | } |
845 | |
846 | static <A extends Module> A findModule(Class<A> c) { |
847 | ret findConcept(c, on := true); |
848 | } |
849 | |
850 | // returns module ID |
851 | static S findDynModuleOfType(S type) { |
852 | DynamicModule m = findConcept(DynamicModule, on := true, _className := "main$" + type); |
853 | ret m == null ? null : m.moduleID(); |
854 | } |
855 | |
856 | sbool moduleTypeIs(Module m, S type) { |
857 | if (m == null) false; |
858 | ret eq(moduleResolvedClassName(m), "main$" + type); |
859 | } |
860 | |
861 | sS moduleResolvedClassName(Module m) { |
862 | if (m == null) null; |
863 | if (m instanceof DynamicModule) |
864 | ret m/DynamicModule._className; |
865 | ret className(m); |
866 | } |
867 | |
868 | // returns module ID |
869 | sS findClosestModuleTo(O searcher, S type) { |
870 | JInternalFrame f = getInternalFrame(dm_getVisualization(searcher)); |
871 | if (f == null) null; |
872 | Pt p = centerOfRect(toRect(getBounds(f))); |
873 | new Lowest<S> best; |
874 | for (Module m : onModules()) { |
875 | JInternalFrame f2 = getInternalFrame(m.vis); |
876 | if (f2 == null || f2 == f) continue; |
877 | if (type != null && !moduleTypeIs(m, type)) continue; |
878 | Rect r2 = toRect(getBounds(f2)); |
879 | best.put(m.moduleID(), rectPointDistance(r2, p)); |
880 | } |
881 | ret best!; |
882 | } |
883 | |
884 | static <A extends Module> L<A> staticModulesOfType(Class<A> type) { |
885 | ret conceptsWhere(type, on := true); |
886 | } |
887 | |
888 | static <A extends Module> L<A> staticModulesOfExactType(Class<A> type) { |
889 | ret filterByExactType(type, staticModulesOfType(type)); |
890 | } |
891 | |
892 | static L listModules() { |
893 | ret map unwrapDynamicModule(onModules()); |
894 | } |
895 | |
896 | static int moduleCount() { |
897 | ret l(onModules()); |
898 | } |
899 | |
900 | static L visibleModules() { |
901 | ret map unwrapDynamicModule(objectsWhere(onModules(), visible := true)); |
902 | } |
903 | |
904 | static O unwrapDynamicModule(Module m) { |
905 | ret m instanceof DynamicModule ? or(m/DynamicModule.o, m) : m; |
906 | } |
907 | |
908 | sbool moduleStillThere(O o) { |
909 | Module m = o instanceof Module ? o/Module : (Module) get(o, '_host); |
910 | ret isConceptRegistered(mainConcepts, m); |
911 | } |
912 | |
913 | static O getDynModuleByID(S moduleID) { |
914 | if (moduleID == null) null; |
915 | ret resolveModule(getConcept(Module, parseLong(moduleID))); |
916 | } |
917 | |
918 | static Module getModuleByID(S moduleID) { |
919 | if (moduleID == null) null; |
920 | ret getConcept(Module, parseLong(moduleID)); |
921 | } |
922 | |
923 | sS getInterestingString { |
924 | InterestingString m = findModule(InterestingString); |
925 | ret m == null ? getText(tfTopInput) : m.theString; |
926 | } |
927 | |
928 | sS modulesSessionGrab() { |
929 | grabFrameRects(); |
930 | ret struct(ll(programID(), localDateWithMilliseconds())) + "\n" |
931 | + mainConcepts.xfullgrab(); |
932 | } |
933 | |
934 | svoid autoSaveModulesSession() { |
935 | infoBox("Auto-saving session."); |
936 | S grab; |
937 | logQuoted(javaxBackupDir(fsI(programID()) + "/auto-saved-sessions.txt"), grab = modulesSessionGrab()); |
938 | infoBox("Auto-save done (" + l(grab) + " chars)"); |
939 | } |
940 | |
941 | svoid deleteAllModules() { |
942 | autoSaveModulesSession(); |
943 | deleteConcepts(Module); |
944 | initialModules(); |
945 | } |
946 | |
947 | svoid restoreModulesSession(S text) { |
948 | autoSaveModulesSession(); |
949 | systemStatus.set("shutting down"); |
950 | infoBox("Releasing session"); |
951 | cleanMeUp(); |
952 | cleanUp(mainConcepts); |
953 | mainConcepts = null; |
954 | //sleepSeconds(1); |
955 | infoBox("Loading session"); |
956 | systemStatus.set("loading"); |
957 | mainConcepts = new Concepts().load(dropFirstLine(text)); |
958 | initAfterDBLoad(); |
959 | infoBox("Session restore done"); |
960 | } |
961 | |
962 | svoid grabFrameRects { |
963 | for (Module m : onModules()) m.grabFrameRect(); |
964 | } |
965 | |
966 | sclass DynamicModule extends Module { |
967 | // moduleID is the snippet ID |
968 | // "className" is taken by DynamicObject; _className == null for old-style dyn module |
969 | S moduleID, _className; |
970 | S oStruct; // serialized dynamic object |
971 | sbool reload_replaceFrame = true; |
972 | |
973 | transient Class c; |
974 | transient O o; |
975 | transient bool contentsDirty = true; |
976 | transient ReliableSingleThread rstPersist = rstWithDelay(persistenceDelayPerModule, r persistContents); |
977 | transient O reloadData; // data held for module during reload |
978 | |
979 | *() {} |
980 | *(S *moduleID, S *_className) {} |
981 | *(S *moduleID, S *_className, Class *c) {} |
982 | |
983 | static bool needsParameters() { true; } |
984 | |
985 | AutoCloseable enter() { |
986 | ret castForTemp(callOpt(o, 'enter)); |
987 | } |
988 | |
989 | JComponent visualize() { |
990 | temp enter(); |
991 | ret (JComponent) callOpt(o, 'visualize); |
992 | } |
993 | |
994 | void enhanceFrame(final JInternalFrame f) { |
995 | final WeakReference<JInternalFrame> fRef = new(f); |
996 | final WeakReference<DynamicModule> mRef = new(this); |
997 | S idText = str(id); |
998 | |
999 | if (isTrue(vmGeneralMap_get('iconifyBroken))) |
1000 | internalFrameTitlePopupMenuItem(f, "Hide/Minimize", r { hideModule(mRef!) }); |
1001 | |
1002 | idText += "/" + moduleLibID(); |
1003 | internalFrameTitlePopupMenuItem(f, "Source code [Module ID: " + idText + "]", r-thread { pcall { |
1004 | if (empty(mRef->moduleID)) ret with infoBox("No source code found"); |
1005 | dm_openSnippetInEditor(mRef->moduleID); |
1006 | }}); |
1007 | |
1008 | internalFrameTitlePopupMenuItem(f, "Reload", r reload); |
1009 | internalFrameTitlePopupMenuItem(f, "Duplicate", rThread { duplicateModule(DynamicModule.this) }); |
1010 | if (isDevVersion()) |
1011 | internalFrameTitlePopupMenuItem(f, "Medium Retranspile", rThread { transpileOnServerWithErrorWindow(moduleID, true, r reload) }); |
1012 | internalFrameTitlePopupMenuItem(f, "Pop Out", r { stefansOS_popOutModule(DynamicModule.this) }); |
1013 | |
1014 | { |
1015 | temp enter(); |
1016 | pcallOpt(o, 'enhanceFrame, f); |
1017 | } |
1018 | internalFrameTitle(f, moduleName()); |
1019 | } |
1020 | |
1021 | S moduleLibID() { |
1022 | ret moduleID + "/" + dropPrefix("main$", _className); |
1023 | } |
1024 | |
1025 | S moduleName() { |
1026 | S name = (S) callOpt(o, 'moduleName); |
1027 | if (nempty(name)) ret name; |
1028 | ret originalModuleName(); |
1029 | } |
1030 | |
1031 | S originalModuleName() { |
1032 | S title = snippetTitle_cached(moduleID); |
1033 | //ret dropSuffixICTrimOneOf(title, "[Dyn Module]", "[Dyn Module, OK]", "[Dyn Module, shortened]"); |
1034 | ret stefansOS_cleanModuleName(title); |
1035 | } |
1036 | |
1037 | void start() { |
1038 | try { |
1039 | start_impl(); |
1040 | } catch e { |
1041 | setError(e); |
1042 | _handleException(e); |
1043 | } |
1044 | } |
1045 | |
1046 | void start_impl { |
1047 | if (moduleID == null) ret; |
1048 | if (c == null) c = hotwireModule(moduleID); |
1049 | replaceACCInClassLoader(c, globalACC); |
1050 | if (oStruct != null) pcall { |
1051 | Map<S, O> renames = cast getOpt(c, '_renameClasses); |
1052 | //print("Class renames: " + sfu(renames)); |
1053 | S renamed = migrateClassesInStructureText(oStruct, renames); |
1054 | //print("Renamed: " + renamed); |
1055 | o = unstructureInRealm(renamed, c); |
1056 | } |
1057 | if (o == null) |
1058 | if (_className == null) |
1059 | o = c; |
1060 | else |
1061 | o = nu(_getClass(c, _className)); |
1062 | setOptAll(o, _host := this, lock := lock); |
1063 | temp enter(); |
1064 | if (o instanceof Class) |
1065 | callMain(o); |
1066 | else |
1067 | callOpt(o, 'start); |
1068 | } |
1069 | |
1070 | void unvisualize2() { callOpt(o, 'unvisualize); } |
1071 | |
1072 | void update() { callOpt(o, 'update); } |
1073 | |
1074 | // XXX - only when called from DynModule |
1075 | // (works for now, but should be renamed) |
1076 | void _change() { |
1077 | super._change(); |
1078 | contentsDirty = true; |
1079 | if (rstPersist != null) |
1080 | rstPersist.trigger(); |
1081 | } |
1082 | |
1083 | void persistContents() { |
1084 | temp enter(); |
1085 | if (_concepts != null && contentsDirty) { |
1086 | contentsDirty = false; |
1087 | //oStruct = null; |
1088 | pcall { |
1089 | if (o != null && !o instanceof Class) { |
1090 | cset(this, oStruct := struct(o)); |
1091 | if (printOnPersistContents) |
1092 | print("Persisted contents: " + moduleID + " - " + l(oStruct) + " chars"); |
1093 | callOpt(o, 'onPersisted); |
1094 | } |
1095 | } |
1096 | } |
1097 | } |
1098 | |
1099 | void cleanMeUp() { |
1100 | persistContents(); |
1101 | if (verboseCleanUp) |
1102 | print("o: " + className(o) + ". Cleaning up main class: " + mainClass(o)); |
1103 | cleanUpObjectAndItsMainClass(o); |
1104 | o = null; |
1105 | c = null; |
1106 | } |
1107 | |
1108 | void reload() { |
1109 | reloadModuleInBackground(this); |
1110 | } |
1111 | |
1112 | // don't call directly |
1113 | void reload_impl() { |
1114 | if (reloadData == null) |
1115 | reloadData = callOpt(o, '_getReloadData); |
1116 | |
1117 | JInternalFrame frame = getInternalFrame(vis); |
1118 | unvisualize1b(); |
1119 | unvisualize2(); |
1120 | |
1121 | if (o != null) |
1122 | ghostModules.put(o.getClass(), nu(GhostModule, |
1123 | name := moduleName(), |
1124 | created := created, |
1125 | deleted := now(), |
1126 | instance := new WeakReference(o))); |
1127 | |
1128 | cleanUp(this); // also sets started to false |
1129 | |
1130 | if (frame != null) |
1131 | setInternalFrameContents(frame, makeReloadingComponent != null ? callF(makeReloadingComponent, this) : makeStandardReloadingComponent(this) ); |
1132 | visible = false; |
1133 | startModule(this); |
1134 | |
1135 | if (reloadData != null) { |
1136 | callOpt(o, '_setReloadData, reloadData); |
1137 | reloadData = null; |
1138 | } |
1139 | |
1140 | if (frame != null) { |
1141 | if (reload_replaceFrame) { // avoids some bugs |
1142 | cset(this, frameRect := toRect(getBounds(frame))); |
1143 | disposeInternalFrame(frame); |
1144 | showModule(this); |
1145 | } else { |
1146 | csetAndStatusChange(this, visible := true); |
1147 | visualizeModule(this); |
1148 | //print("New content: " + vis); |
1149 | setInternalFrameContents(frame, vis); |
1150 | } |
1151 | } |
1152 | rstUpdateModules.trigger(); |
1153 | } |
1154 | |
1155 | S sourceCode() { |
1156 | ret loadSnippet(moduleID); |
1157 | } |
1158 | |
1159 | O resolve() { ret o; } |
1160 | O getError() { |
1161 | if (o != null) { |
1162 | O error = callOpt(o, 'getError); |
1163 | if (error != null) ret error; |
1164 | } |
1165 | ret super.getError(); |
1166 | } |
1167 | |
1168 | toString { |
1169 | ret "DynModule " + moduleID + "/" + shortenClassName(_className); |
1170 | } |
1171 | |
1172 | void setError(Throwable e) { |
1173 | if (o != null && isTrue(callOpt(o, 'setError, e))) ret; |
1174 | super.setError(e); |
1175 | } |
1176 | |
1177 | } |
1178 | |
1179 | /*static L resolvedModules() { |
1180 | new L l; |
1181 | for (Module m : onModules()) |
1182 | l.add(m.resolve()); |
1183 | ret l; |
1184 | }*/ |
1185 | |
1186 | static S moduleID(Module m) { |
1187 | ret m == null ? null : m.moduleID(); |
1188 | } |
1189 | |
1190 | static O resolveModule(O m) { |
1191 | ret m instanceof Module ? m/Module.resolve() : m; |
1192 | } |
1193 | |
1194 | static S makeModule(Class<? extends Module> moduleClass) { |
1195 | ret makeModule(shortClassName(moduleClass)); |
1196 | } |
1197 | |
1198 | static S makeModule(S moduleLibID) { |
1199 | ret makeOrShowModule(moduleLibID, false); |
1200 | } |
1201 | |
1202 | static S makeOrShowModule(S moduleLibID) { |
1203 | ret makeOrShowModule(moduleLibID, true); |
1204 | } |
1205 | |
1206 | sS makeOrShowModule(fS moduleLibID, final bool orShow) { |
1207 | ret //evalInQ(systemQ, func -> S { |
1208 | makeOrShowModule_impl(moduleLibID, orShow) |
1209 | /*})*/; |
1210 | } |
1211 | |
1212 | sS makeOrShowModule_impl(fS moduleLibID, final bool orShow) { |
1213 | // makes dynamic & static modules |
1214 | |
1215 | if (isIdentifier(moduleLibID)) |
1216 | ret moduleID(makeOrShowStaticModuleOfType(moduleLibID, orShow)); |
1217 | |
1218 | L<S> l = splitAtSlash(moduleLibID); |
1219 | if (!isSnippetID(first(l))) |
1220 | fail("Unknown module lib ID: " + moduleLibID); |
1221 | |
1222 | S snippetID = first(l), className = second(l); |
1223 | className = className == null ? null : "main$" + className; |
1224 | DynamicModule m = findConcept(DynamicModule, on := true, moduleID := snippetID, _className := className); |
1225 | if (m == null) { |
1226 | Class c = hotwireModule(snippetID); |
1227 | m = DynamicModule(snippetID, className, c); |
1228 | vmBus_send('moduleLoaded, m); |
1229 | } |
1230 | if (orShow) showModule(m); else startModule(m); |
1231 | ret moduleID(m); |
1232 | } |
1233 | |
1234 | static S makeNewModule(S moduleLibID, bool show) { |
1235 | print("Loading module " + moduleLibID); |
1236 | |
1237 | if (isIdentifier(moduleLibID)) |
1238 | ret moduleID(makeNewStaticModuleOfType(moduleLibID, show)); |
1239 | |
1240 | L<S> l = splitAtSlash(moduleLibID); |
1241 | if (!isSnippetID(first(l))) |
1242 | fail("Unknown module lib ID: " + moduleLibID); |
1243 | |
1244 | S snippetID = first(l), className = second(l); |
1245 | className = className == null ? null : "main$" + className; |
1246 | Class c = hotwireModule(snippetID); |
1247 | Module m = DynamicModule(snippetID, className, c); |
1248 | startModule(m); |
1249 | if (show && !isTrue(getOpt(unwrapDynamicModule(m), '_startMinimized))) |
1250 | showModule(m); |
1251 | ret moduleID(m); |
1252 | } |
1253 | |
1254 | // dynamic only |
1255 | static S findModuleByLibID(S moduleLibID) { |
1256 | L<S> l = splitAtSlash(moduleLibID); |
1257 | if (!isSnippetID(first(l))) |
1258 | fail("Unknown module lib ID: " + moduleLibID); |
1259 | |
1260 | S snippetID = first(l), className = second(l); |
1261 | className = className == null ? null : "main$" + className; |
1262 | L<DynamicModule> list = findConcepts(DynamicModule, on := true, moduleID := snippetID); |
1263 | DynamicModule m = firstWhere(list, _className := className); |
1264 | if (m != null) ret moduleID(m); |
1265 | if (className != null) null; |
1266 | ret moduleID(first(list)); |
1267 | } |
1268 | |
1269 | static Module makeOrShowStaticModuleOfType(S s) { |
1270 | ret makeOrShowStaticModuleOfType(s, true); |
1271 | } |
1272 | |
1273 | static Module makeOrShowStaticModuleOfType(S s, bool orShow) { |
1274 | ret makeOrShowStaticModuleOfType(classForName("main$" + s), orShow); |
1275 | } |
1276 | |
1277 | static Module makeOrShowStaticModuleOfType(Class<? extends Module> c) { |
1278 | ret makeOrShowStaticModuleOfType(c, true); |
1279 | } |
1280 | |
1281 | static Module makeOrShowStaticModuleOfType(Class<? extends Module> c, bool orShow) { |
1282 | final L<? extends Module> l = staticModulesOfExactType(c); |
1283 | Module m = empty(l) ? nu(c) : first(l); |
1284 | if (orShow) showModule(m); else startModule(m); |
1285 | ret m; |
1286 | } |
1287 | |
1288 | static Module makeNewStaticModuleOfType(S type, bool show) { |
1289 | Class c = classForName("main$" + type); |
1290 | Module m = cast nu(c); |
1291 | if (show) showModule(m); else startModule(m); |
1292 | ret m; |
1293 | } |
1294 | |
1295 | //!include once #1016217 // Sticky Libs |
1296 | !include once #1020744 // Sticky Libs & Src Libs |
1297 | |
1298 | static Class hotwireModule(S snippetID) { |
1299 | hotwire_autoStickyLibs(); |
1300 | ret hotwire(snippetID); // give each their own local_log |
1301 | } |
1302 | |
1303 | // Make modules print with their module ID |
1304 | |
1305 | set flag hotwire_copyOver_extend. |
1306 | svoid hotwire_copyOver_extend(Class c) { |
1307 | S progID = getProgramID(c); |
1308 | if (nempty(progID) && fieldType(c, 'print_log) == Appendable.class) |
1309 | setOpt(c, 'print_log, _SubModulePrint("[" + progID + "] ")); |
1310 | } |
1311 | |
1312 | sbool isLoading() { |
1313 | ret eq(systemStatus!, "loading"); |
1314 | } |
1315 | |
1316 | sbool isShuttingDown() { |
1317 | ret eq(systemStatus!, "shutting down"); |
1318 | } |
1319 | |
1320 | svoid doInGlobalContext(final Runnable r) { |
1321 | final new Flag flag; |
1322 | systemQ.add(r { |
1323 | callF(r); |
1324 | flag.raise(); |
1325 | }); |
1326 | flag.waitUntilUp(); |
1327 | } |
1328 | |
1329 | !include once #1015842 // SavedSessions |
1330 | !include once #1015885 // Standard Modules |
1331 | !include once #1015959 // More Standard Modules |
1332 | |
1333 | please include function renderConcept. |
1334 | please include function restart. |
1335 | |
1336 | svoid setLookAndFeel() { |
1337 | if (eq(laf, 'webLAF)) |
1338 | installWebLAF(); |
1339 | else if (eq(laf, 'nimbus)) |
1340 | nimbus(); |
1341 | else if (eq(laf, 'jtattoo)) |
1342 | jtattoo_mcWin(); |
1343 | else if (eq(laf, 'platform)) |
1344 | systemLAF(); |
1345 | |
1346 | pcall { |
1347 | S scale = trim(loadTextFile(javaxDataDir("os-font-scale.txt"))); |
1348 | if (nempty(scale)) |
1349 | swingFontScale(parseDouble(scale)); |
1350 | } |
1351 | } |
1352 | |
1353 | please include function myTranspilationDate. |
1354 | |
1355 | // should happen in swing thread |
1356 | svoid setActiveModule(Module m) { |
1357 | if (activeModule != m) { |
1358 | activeModule = m; |
1359 | vmBus_send('newActiveModule, m); |
1360 | } |
1361 | } |
1362 | |
1363 | static O unwrappedActiveModule() { |
1364 | ret unwrapDynamicModule(activeModule); |
1365 | } |
1366 | |
1367 | concept TopInput { |
1368 | S text; |
1369 | } |
1370 | |
1371 | svoid nohupJavax(S javaxArgs) { |
1372 | nohupJavax(javaxArgs, javaxDefaultVMArgs()); |
1373 | } |
1374 | |
1375 | sbool cleanedUp; |
1376 | |
1377 | svoid nohupJavax(S javaxArgs, S vmArgs) { |
1378 | if (desktop != null && !cleanedUp) pcall { fullScreenOff(); } |
1379 | directNohupJavax(javaxArgs, vmArgs); |
1380 | } |
1381 | |
1382 | sbool isDevVersion() { |
1383 | ret neq(programID(), #1016005); |
1384 | } |
1385 | |
1386 | svoid startOtherVersion { |
1387 | nohupJavax(isDevVersion() ? #1016005 : #1016478); |
1388 | } |
1389 | |
1390 | sS otherVersionName() { |
1391 | ret isDevVersion() ? "v5" : "v6"; |
1392 | } |
1393 | |
1394 | sS restoreModule(S structure) { |
1395 | O mod = safeUnstructure(structure); |
1396 | if (mod instanceof Map) |
1397 | mod = get((Map) mod, 'module); |
1398 | |
1399 | S shortName = dynShortName(mod); |
1400 | if (!eq(shortName, "DynamicModule")) |
1401 | fail("Can't restore static modules yet [" + shortName + "]"); |
1402 | |
1403 | S snippetID = getString(mod, "moduleID"); |
1404 | S className = getString(mod, "_className"); |
1405 | |
1406 | Class c = hotwireModule(snippetID); |
1407 | DynamicModule m = new(snippetID, className, c); |
1408 | copyFields(mod, m, 'iconID); |
1409 | m.frameRect = (Rect) restruct(getOpt(m, 'frameRect)); |
1410 | m.oStruct = getString(mod, "oStruct"); |
1411 | showModule(m); |
1412 | ret moduleID(m); |
1413 | } |
1414 | |
1415 | sS duplicateModule(DynamicModule m) { |
1416 | if (m == null) null; |
1417 | m.persistContents(); |
1418 | S struct = struct(m); |
1419 | fO resolved = resolveModule(m); |
1420 | |
1421 | if (hasMethod(resolved, '_modifyStructForDuplication, struct)) |
1422 | struct = jreplace_first_dyn(struct, "oStruct=*", func(LS tok, int i) -> S { |
1423 | S s = unquote(tok.get(i+4)); |
1424 | s = callOpt(resolved, '_modifyStructForDuplication, s); |
1425 | if (s == null) fail("Module does not want to be duplicated"); |
1426 | ret "oStruct=" + quote(s); |
1427 | }); |
1428 | |
1429 | ret restoreModule(struct); |
1430 | } |
1431 | |
1432 | static O dm_current_mandatory() { fail(); } |
1433 | |
1434 | // for modules |
1435 | please include function mechList_opt_raw. |
1436 | please include function mechList_clearCache. |
1437 | please include function mechLists_clearCache. |
1438 | |
1439 | // This is only answered from localhost |
1440 | answer { |
1441 | if "swing latency" { ret str(swingLatency()); } |
1442 | |
1443 | if "activate frames" { |
1444 | awt { activateMyFrames(); } |
1445 | ret "OK"; |
1446 | } |
1447 | |
1448 | if "program id" ret programID(); |
1449 | |
1450 | if "enable remote control from *" { |
1451 | O mod = getDynModuleByID(makeOrShowModule("#1017127/RemoteControlled")); |
1452 | call(mod, 'setFields, new O[] {new O[] {controllingComputers := $1, enabled := true}}); |
1453 | ret "OK"; |
1454 | } |
1455 | |
1456 | if "stack traces" |
1457 | ret renderAllThreadsWithStackTraces(); |
1458 | } |
1459 | |
1460 | srecord Service(O module, O worker) {} |
1461 | |
1462 | static new MultiMap<S, Service> registeredServices; |
1463 | |
1464 | static bool callService(S name, O... args) { |
1465 | for (Service service : cloneList(registeredServices.get(name))) |
1466 | if (isTrue(pcallF(service.worker, name, args))) true; |
1467 | false; |
1468 | } |
1469 | |
1470 | static void registerService(O module, S name, O service) { |
1471 | registeredServices.put(name, Service(module, service)); |
1472 | } |
1473 | |
1474 | static void unregisterService(O module, S name, O service) { |
1475 | registeredServices.remove(name, Service(module, service)); |
1476 | } |
1477 | |
1478 | static O dm_os() { ret main.class; } |
1479 | |
1480 | please include function robot_keyPress. |
1481 | please include function robot_keyRelease. |
1482 | please include function robot_safetyKeyReleaser. |
1483 | |
1484 | svoid showCurrentModuleMenu { |
1485 | swing { |
1486 | showInternalFramePopupMenu(desktop.getSelectedFrame()); |
1487 | } |
1488 | } |
1489 | |
1490 | svoid inSystemQ(Runnable r) { |
1491 | systemQ.add(r); |
1492 | } |
1493 | |
1494 | svoid reloadModuleInBackground(final DynamicModule m) { |
1495 | if (m == null) ret; |
1496 | inSystemQ(r { m.reload_impl() }); |
1497 | } |
1498 | |
1499 | svoid deleteModuleInBackground(final DynamicModule m) { |
1500 | if (m == null) ret; |
1501 | inSystemQ(r { deleteModule(m) }); |
1502 | } |
1503 | |
1504 | svoid restart { |
1505 | if (restarter_override != null) |
1506 | ret with callF(restarter_override); |
1507 | restartWithDefaultVMArgs(); |
1508 | sleep(); |
1509 | } |
1510 | |
1511 | static Component makeStandardReloadingComponent(Module m) { |
1512 | ret jcenteredlabel("Reloading..."); |
1513 | } |
Began life as a copy of #1016478
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, cfunsshuasjs, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1022729 |
Snippet name: | Stefan's OS v6 - copy for transpiler test |
Eternal ID of this version: | #1022729/3 |
Text MD5: | 200d747d28dda646d8b23e1bd3fe1b4c |
Transpilation MD5: | f8e626052561cc21d29d629bf7a6fd39 |
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: | 2019-04-03 15:44:45 |
Source code size: | 44699 bytes / 1513 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 309 / 902 |
Version history: | 2 change(s) |
Referenced in: | [show references] |