|
| 1 | +package org.processing.gradle |
| 2 | + |
| 3 | +import org.gradle.api.Plugin |
| 4 | +import org.gradle.api.Project |
| 5 | +import org.gradle.api.file.SourceDirectorySet |
| 6 | +import org.gradle.api.internal.file.DefaultSourceDirectorySet |
| 7 | +import org.gradle.api.internal.tasks.TaskDependencyFactory |
| 8 | +import org.gradle.api.model.ObjectFactory |
| 9 | +import org.gradle.api.plugins.JavaPlugin |
| 10 | +import org.gradle.api.plugins.JavaPluginExtension |
| 11 | +import org.jetbrains.compose.ComposeExtension |
| 12 | +import org.jetbrains.compose.desktop.DesktopExtension |
| 13 | +import java.io.File |
| 14 | +import java.util.* |
| 15 | +import javax.inject.Inject |
| 16 | + |
| 17 | +class ProcessingPlugin @Inject constructor(private val objectFactory: ObjectFactory) : Plugin<Project> { |
| 18 | + override fun apply(project: Project) { |
| 19 | + project.plugins.apply(JavaPlugin::class.java) |
| 20 | + |
| 21 | + // TODO: Only set the build directory when run from the Processing plugin |
| 22 | + project.layout.buildDirectory.set(project.layout.projectDirectory.dir(".processing")) |
| 23 | + |
| 24 | + project.plugins.apply("org.jetbrains.compose") |
| 25 | + project.plugins.apply("org.jetbrains.kotlin.jvm") |
| 26 | + |
| 27 | + project.dependencies.add("implementation", "org.processing:core:4.3.1") |
| 28 | + project.dependencies.add("implementation", project.fileTree("src").apply { include("**/code/*.jar") }) |
| 29 | + |
| 30 | + // Base JOGL and Gluegen dependencies |
| 31 | + project.dependencies.add("runtimeOnly", "org.jogamp.jogl:jogl-all-main:2.5.0") |
| 32 | + project.dependencies.add("runtimeOnly", "org.jogamp.gluegen:gluegen-rt-main:2.5.0") |
| 33 | + |
| 34 | + // TODO: Only add the native dependencies for the platform the user is building for |
| 35 | + |
| 36 | + // MacOS specific native dependencies |
| 37 | + project.dependencies.add("runtimeOnly", "org.jogamp.jogl:jogl-all:2.5.0:natives-macosx-universal") |
| 38 | + project.dependencies.add("runtimeOnly", "org.jogamp.gluegen:gluegen-rt:2.5.0:natives-macosx-universal") |
| 39 | + |
| 40 | + // Windows specific native dependencies |
| 41 | + project.dependencies.add("runtimeOnly", "org.jogamp.jogl:jogl-all:2.5.0:natives-windows-amd64") |
| 42 | + project.dependencies.add("runtimeOnly", "org.jogamp.gluegen:gluegen-rt:2.5.0:natives-windows-amd64") |
| 43 | + |
| 44 | + // Linux specific native dependencies |
| 45 | + project.dependencies.add("runtimeOnly", "org.jogamp.jogl:jogl-all:2.5.0:natives-linux-amd64") |
| 46 | + project.dependencies.add("runtimeOnly", "org.jogamp.gluegen:gluegen-rt:2.5.0:natives-linux-amd64") |
| 47 | + |
| 48 | + // NativeWindow dependencies for all platforms |
| 49 | + project.dependencies.add("implementation", "org.jogamp.jogl:nativewindow:2.5.0") |
| 50 | + project.dependencies.add("runtimeOnly", "org.jogamp.jogl:nativewindow:2.5.0:natives-macosx-universal") |
| 51 | + project.dependencies.add("runtimeOnly", "org.jogamp.jogl:nativewindow:2.5.0:natives-windows-amd64") |
| 52 | + project.dependencies.add("runtimeOnly", "org.jogamp.jogl:nativewindow:2.5.0:natives-linux-amd64") |
| 53 | + |
| 54 | + project.repositories.add(project.repositories.maven { it.setUrl("https://jogamp.org/deployment/maven") }) |
| 55 | + project.repositories.add(project.repositories.mavenCentral()) |
| 56 | + |
| 57 | + project.extensions.configure(ComposeExtension::class.java) { extension -> |
| 58 | + extension.extensions.getByType(DesktopExtension::class.java).application { application -> |
| 59 | + application.mainClass = project.layout.projectDirectory.asFile.name.replace(Regex("[^a-zA-Z0-9_]"), "_") |
| 60 | + application.nativeDistributions.modules("java.management") |
| 61 | + } |
| 62 | + } |
| 63 | + |
| 64 | + // TODO: Also only do within Processing |
| 65 | + project.tasks.named("wrapper").configure { |
| 66 | + it.enabled = false |
| 67 | + } |
| 68 | + |
| 69 | + project.tasks.create("sketch").apply { |
| 70 | + group = "processing" |
| 71 | + description = "Runs the Processing sketch" |
| 72 | + dependsOn("run") |
| 73 | + } |
| 74 | + project.tasks.create("present").apply { |
| 75 | + // TODO: Implement dynamic fullscreen by setting the properties and recompiling the sketch every run |
| 76 | + group = "processing" |
| 77 | + description = "Presents the Processing sketch" |
| 78 | + dependsOn("run") |
| 79 | + } |
| 80 | + project.tasks.create("export").apply { |
| 81 | + group = "processing" |
| 82 | + description = "Creates a distributable version of the Processing sketch" |
| 83 | + dependsOn("createDistributable") |
| 84 | + } |
| 85 | + |
| 86 | + project.extensions.getByType(JavaPluginExtension::class.java).sourceSets.all { sourceSet -> |
| 87 | + // TODO: also supporting normal gradle setup |
| 88 | + val pdeSourceSet = objectFactory.newInstance( |
| 89 | + DefaultPDESourceDirectorySet::class.java, |
| 90 | + objectFactory.sourceDirectorySet("${sourceSet.name}.pde", "${sourceSet.name} Processing Source") |
| 91 | + ).apply { |
| 92 | + filter.include("**/*.pde") |
| 93 | + filter.exclude("${project.layout.buildDirectory.asFile.get().name}/**") |
| 94 | + |
| 95 | + srcDir("./") |
| 96 | + } |
| 97 | + sourceSet.allSource.source(pdeSourceSet) |
| 98 | + |
| 99 | + val outputDirectory = project.layout.buildDirectory.file( "generated/pde/" + sourceSet.name).get().asFile |
| 100 | + sourceSet.java.srcDir(outputDirectory) |
| 101 | + |
| 102 | + // TODO: Support multiple sketches? |
| 103 | + // TODO: Preprocess PDE files in this step so we can add the library dependencies |
| 104 | + |
| 105 | + val taskName = sourceSet.getTaskName("preprocess", "PDE") |
| 106 | + project.tasks.register(taskName, ProcessingTask::class.java) { task -> |
| 107 | + task.description = "Processes the ${sourceSet.name} PDE" |
| 108 | + task.source = pdeSourceSet |
| 109 | + task.outputDirectory = outputDirectory |
| 110 | + } |
| 111 | + |
| 112 | + project.tasks.named( |
| 113 | + sourceSet.compileJavaTaskName |
| 114 | + ) { task -> task.dependsOn(taskName) } |
| 115 | + } |
| 116 | + |
| 117 | + var settingsFolder = File(System.getProperty("user.home"),".processing") |
| 118 | + val osName = System.getProperty("os.name").lowercase() |
| 119 | + if (osName.contains("win")) { |
| 120 | + settingsFolder = File(System.getenv("APPDATA"), "Processing") |
| 121 | + } else if (osName.contains("mac")) { |
| 122 | + settingsFolder = File(System.getProperty("user.home"), "Library/Processing") |
| 123 | + }else if (osName.contains("nix") || osName.contains("nux")) { |
| 124 | + settingsFolder = File(System.getProperty("user.home"), ".processing") |
| 125 | + } |
| 126 | + |
| 127 | + val preferences = File(settingsFolder, "preferences.txt") |
| 128 | + val prefs = Properties() |
| 129 | + prefs.load(preferences.inputStream()) |
| 130 | + |
| 131 | + val sketchbook = prefs.getProperty("sketchbook.path.four") |
| 132 | + |
| 133 | + File(sketchbook, "libraries").listFiles { file -> file.isDirectory |
| 134 | + }?.forEach{ |
| 135 | + project.dependencies.add("implementation", project.fileTree(it).apply { include("**/*.jar") }) |
| 136 | + } |
| 137 | + } |
| 138 | + abstract class DefaultPDESourceDirectorySet @Inject constructor( |
| 139 | + sourceDirectorySet: SourceDirectorySet, |
| 140 | + taskDependencyFactory: TaskDependencyFactory |
| 141 | + ) : DefaultSourceDirectorySet(sourceDirectorySet, taskDependencyFactory), SourceDirectorySet |
| 142 | +} |
| 143 | + |
0 commit comments