Skip to content

Commit 578c287

Browse files
committed
Build on save
1 parent fdc43dc commit 578c287

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,5 @@ processing-examples
122122
/java/gradle/example/gradlew
123123
/java/gradle/example/gradlew.bat
124124
/java/gradle/example/.kotlin/errors
125+
/java/gradle/hotreload/build
126+
*.iml

app/src/processing/app/gradle/GradleJob.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class GradleJob(
7272
Create the necessary build files if they do not exist.
7373
*/
7474
private fun BuildLauncher.setupGradle(extraArguments: List<String> = listOf()) {
75+
7576
val copy = sketch.isReadOnly || sketch.isUntitled
7677

7778
val sketchFolder = if(copy) workingDir.resolve("sketch").toFile() else sketch.folder
@@ -218,6 +219,8 @@ class GradleJob(
218219
val arguments = mutableListOf("--init-script", initGradle.toAbsolutePath().toString())
219220
// Hide Gradle output from the console if not in debug mode
220221
if(!DEBUG) arguments += "--quiet"
222+
// TODO: Fix continuous mode for the hot reload
223+
arguments += "-t"
221224

222225
if(copy) arguments += listOf("--project-dir", sketchFolder.absolutePath)
223226

app/src/processing/app/gradle/GradleService.kt

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ package processing.app.gradle
22

33
import androidx.compose.runtime.mutableStateListOf
44
import androidx.compose.runtime.mutableStateOf
5+
import androidx.compose.runtime.neverEqualPolicy
56
import androidx.compose.ui.awt.ComposePanel
7+
import kotlinx.coroutines.CoroutineScope
8+
import kotlinx.coroutines.Dispatchers
9+
import kotlinx.coroutines.delay
10+
import kotlinx.coroutines.launch
611
import processing.app.Language.text
712
import processing.app.Mode
813
import processing.app.Preferences
@@ -30,7 +35,7 @@ class GradleService(
3035
val editor: Editor?,
3136
) {
3237
val active = mutableStateOf(Preferences.getBoolean("run.use_gradle"))
33-
var sketch = mutableStateOf<Sketch?>(null)
38+
var sketch = mutableStateOf<Sketch?>(null, neverEqualPolicy())
3439
val jobs = mutableStateListOf<GradleJob>()
3540
val workingDir = createTempDirectory()
3641

@@ -52,7 +57,7 @@ class GradleService(
5257

5358
val job = GradleJob(
5459
tasks = tasks,
55-
workingDir = workingDir,
60+
workingDir = workingDir,
5661
sketch = sketch.value ?: throw IllegalStateException("Sketch is not set"),
5762
editor = editor
5863
)
@@ -64,10 +69,47 @@ class GradleService(
6469
jobs.forEach(GradleJob::cancel)
6570
}
6671

72+
private val scope = CoroutineScope(Dispatchers.IO)
73+
74+
/*
75+
Watch the sketch folder for changes and start a build job when the sketch is modified
76+
This need to be done properly to use hooks in the future but right now this is the simplest way to do it
77+
*/
78+
init{
79+
scope.launch {
80+
var path = ""
81+
var modified = false
82+
var sketched: Sketch? = null
83+
while(true){
84+
sketch.value?.let { sketch ->
85+
if(sketch.folder.absolutePath != path){
86+
path = sketch.folder.absolutePath
87+
if(sketched == sketch){
88+
// The same sketch has its folder changed, trigger updates downstream from the service
89+
this@GradleService.sketch.value = sketch
90+
}else {
91+
sketched = sketch
92+
}
93+
startJob("build")
94+
}
95+
if(sketch.isModified != modified){
96+
modified = sketch.isModified
97+
if(!modified){
98+
// If the sketch is no longer modified, start the build job, aka build on save
99+
startJob("build")
100+
}
101+
}
102+
}
103+
104+
105+
delay(100)
106+
}
107+
}
108+
}
109+
67110
// Hooks for java to interact with the Gradle service since mutableStateOf is not accessible in java
68111
fun setSketch(sketch: Sketch){
69112
this.sketch.value = sketch
70-
startJob("build")
71113
}
72114
fun getEnabled(): Boolean {
73115
return active.value

java/gradle/hotreload/src/main/kotlin/org/processing/java/gradle/ProcessingHotReloadPlugin.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ package org.processing.java.gradle
22

33
import org.gradle.api.Plugin
44
import org.gradle.api.Project
5-
import org.gradle.api.tasks.GradleBuild
5+
import org.gradle.api.plugins.JavaPlugin
6+
import org.gradle.api.plugins.JavaPluginExtension
7+
import org.gradle.jvm.toolchain.JavaLanguageVersion
8+
import org.gradle.jvm.toolchain.JvmVendorSpec
69
import org.jetbrains.compose.reload.gradle.ComposeHotReloadPlugin
710
import org.jetbrains.compose.reload.gradle.ComposeHotRun
811

@@ -11,10 +14,14 @@ class ProcessingHotReloadPlugin: Plugin<Project> {
1114
project.plugins.apply(ComposeHotReloadPlugin::class.java)
1215

1316
project.repositories.google()
17+
project.extensions.getByType(JavaPluginExtension::class.java).toolchain {
18+
it.languageVersion.set(JavaLanguageVersion.of(21))
19+
it.vendor.set(JvmVendorSpec.JETBRAINS)
20+
}
1421

1522
project.afterEvaluate {
16-
project.tasks.named("hotRun", ComposeHotRun::class.java){ task ->
17-
task.isAutoReloadEnabled.set(true)
23+
project.tasks.named("build").configure { task ->
24+
task.finalizedBy("reload")
1825
}
1926
project.tasks.named("run").configure { task ->
2027
task.dependsOn("hotRun")

0 commit comments

Comments
 (0)