@@ -7,8 +7,94 @@ import processing.app.ui.Editor
77import processing.app.ui.EditorState
88import processing.app.ui.EditorToolbar
99import javax.swing.JMenu
10+ import kotlinx.coroutines.*
11+ import java.io.BufferedReader
12+ import java.io.File
13+ import java.io.InputStreamReader
1014
1115class p5jsEditor (base : Base , path : String? , state : EditorState ? , mode : Mode ? ): Editor(base, path, state, mode) {
16+
17+ val scope = CoroutineScope (Dispatchers .Default )
18+ init {
19+ scope.launch {
20+ val folder = sketch.folder
21+ val name = sketch.name
22+
23+ val packageJsonName = " package.json"
24+
25+ val packageJson = loadPackageJson(" $folder /$packageJsonName " )
26+ packageJson.devDependencies[" electron" ] = " ^33.2.1"
27+ packageJson.sketch = " $name .js"
28+ savePackageJson(" $folder /$packageJsonName " , packageJson)
29+
30+ runNpmActions(folder, TYPE .npm, listOf (" install" ))
31+
32+ val indexHtml = """
33+ <!DOCTYPE html>
34+ <html lang="en">
35+ <head>
36+ <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.1/p5.js"></script>
37+ <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.1/addons/p5.sound.min.js"></script>
38+ <meta charset="utf-8" />
39+ <style>
40+ html, body {
41+ margin: 0;
42+ padding: 0;
43+ }
44+ canvas {
45+ display: block;
46+ }
47+ </style>
48+ </head>
49+
50+ <body>
51+ <main>
52+ <script src="${packageJson.sketch} "></script>
53+ </main>
54+ </body>
55+ </html>
56+ """ .trimIndent()
57+ val indexJS = """
58+ const { app, BrowserWindow, globalShortcut } = require('electron')
59+
60+ const createWindow = () => {
61+ const win = new BrowserWindow({
62+ width: 400,
63+ height: 400,
64+ webPreferences: {
65+ nodeIntegration: true,
66+ contextIsolation: false
67+ },
68+ })
69+
70+ win.loadFile('index.html')
71+
72+ // Register the 'Escape' key shortcut
73+ globalShortcut.register('Escape', () => {
74+ win.close()
75+ })
76+
77+ // Unregister the shortcut when window is closed
78+ win.on('closed', () => {
79+ globalShortcut.unregister('Escape')
80+ })
81+ }
82+
83+ app.on('window-all-closed', () => {
84+ // Unregister all shortcuts when app is closing
85+ globalShortcut.unregisterAll()
86+ app.quit()
87+ })
88+
89+ app.whenReady().then(() => {
90+ createWindow()
91+ })
92+ """ .trimIndent()
93+
94+ File (" $folder /index.html" ).writeText(indexHtml)
95+ File (" $folder /index.js" ).writeText(indexJS)
96+ }
97+ }
1298 override fun createToolbar (): EditorToolbar {
1399 return p5jsEditorToolbar(this )
14100 }
@@ -42,10 +128,53 @@ class p5jsEditor(base: Base, path: String?, state: EditorState?, mode: Mode?): E
42128 }
43129
44130 override fun internalCloseRunner () {
45- // TODO("Not yet implemented")
131+ processes.forEach { it.destroy() }
46132 }
47133
134+
48135 override fun deactivateRun () {
49- // TODO("Not yet implemented")
136+ processes.forEach { it.destroy() }
137+ }
138+
139+ enum class TYPE {
140+ npm, npx
141+ }
142+
143+ val processes = mutableListOf<Process >()
144+ fun runNpmActions (directory : File , type : TYPE , actions : List <String >, onFinished : () -> Unit = {}) {
145+ val processBuilder = ProcessBuilder ()
146+
147+ // Set the command based on the operating system
148+ val command = if (System .getProperty(" os.name" ).lowercase().contains(" windows" )) {
149+ listOf (" cmd" , " /c" , type.name , * actions.toTypedArray())
150+ } else {
151+ listOf (type.name, * actions.toTypedArray())
152+ }
153+
154+ processBuilder.command(command)
155+ processBuilder.directory(directory)
156+
157+ try {
158+ val process = processBuilder.start()
159+ processes.add(process)
160+
161+ // Handle output stream
162+ val reader = BufferedReader (InputStreamReader (process.inputStream))
163+ var line: String?
164+ while (reader.readLine().also { line = it } != null ) {
165+ println (line)
166+ }
167+
168+
169+ // Wait for the process to complete
170+ val exitCode = process.waitFor()
171+ processes.remove(process)
172+ onFinished()
173+ if (exitCode != 0 ) {
174+ throw RuntimeException (" npm install failed with exit code $exitCode " )
175+ }
176+ } catch (e: Exception ) {
177+ throw RuntimeException (" Failed to run npm install" , e)
178+ }
50179 }
51180}
0 commit comments