diff --git a/orx-glslify/src/main/kotlin/FileSystemUtils.kt b/orx-glslify/src/main/kotlin/FileSystemUtils.kt index 2639f869..20b28cdd 100644 --- a/orx-glslify/src/main/kotlin/FileSystemUtils.kt +++ b/orx-glslify/src/main/kotlin/FileSystemUtils.kt @@ -5,6 +5,7 @@ import org.rauschig.jarchivelib.ArchiverFactory import java.io.File import java.io.InputStream import java.nio.file.Files +import java.nio.file.Path import java.nio.file.Paths internal fun extractGzipStream(tarStream: InputStream, dest: File) { @@ -13,8 +14,7 @@ internal fun extractGzipStream(tarStream: InputStream, dest: File) { archiver.extract(tarStream, dest) } -internal fun moveFilesUp(moduleDir: File) { - val modulePath = Paths.get(moduleDir.path) +internal fun moveFilesUp(modulePath: Path) { val packageFolder = modulePath.resolve("package") val packageFiles = Files.list(packageFolder).filter { @@ -28,14 +28,14 @@ internal fun moveFilesUp(moduleDir: File) { } } -internal fun parseModule(module: String): Pair { +internal fun parseModule(module: String): Pair { val path = Paths.get(module) val pathLen = path.nameCount val moduleName = path.subpath(0, 1).toString() - var shaderPath = "index" + var shaderPath = Paths.get("index") if (pathLen > 1) { - shaderPath = path.subpath(1, pathLen).toString() + shaderPath = path.subpath(1, pathLen) } return Pair(moduleName, shaderPath) diff --git a/orx-glslify/src/main/kotlin/Glslify.kt b/orx-glslify/src/main/kotlin/Glslify.kt index 8bf2f909..e472688d 100644 --- a/orx-glslify/src/main/kotlin/Glslify.kt +++ b/orx-glslify/src/main/kotlin/Glslify.kt @@ -5,16 +5,20 @@ import java.io.ByteArrayInputStream import java.io.File import java.io.InputStream import java.net.URL +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths import javax.net.ssl.HttpsURLConnection +import kotlin.streams.toList -const val BASE_URL = "https://registry.npmjs.org" -const val GLSLIFY_PATH = "src/main/resources/glslify" -const val IMPORT_PATT = """#pragma\sglslify:\s*(.*)\s=\s*require\('([\w\-]+)'\)""" -const val EXPORT_PATT = """#pragma\sglslify:\s*export\(([\w\-]+)\)""" +internal const val BASE_URL = "https://registry.npmjs.org" +internal const val GLSLIFY_PATH = "src/main/resources/glslify" +internal const val IMPORT_PATT = """#pragma\sglslify:\s*(.*)\s=\s*require\('?([\w\-\\/]+).*'?\)$""" +internal const val EXPORT_PATT = """#pragma\sglslify:\s*export\(([\w\-]+)\)""" internal val shaderExtensions = arrayOf("glsl", "frag") -data class GlslifyImport( +private data class GlslifyImport( val functionName: String, val pkgName: String, var exists: Boolean @@ -23,64 +27,42 @@ data class GlslifyImport( private val logger = KotlinLogging.logger {} fun glslify(module: String, renameFunctionTo: String? = null): String { - val (moduleName: String, shaderPath: String) = parseModule(module) - val moduleDir = File("$GLSLIFY_PATH/$moduleName") + val (moduleName: String, shaderPath: Path) = parseModule(module) + val moduleDir = Paths.get("$GLSLIFY_PATH/$moduleName") - val packageUrl = getPackageUrl(moduleName) + return glslifyImport(moduleName, moduleDir, shaderPath, renameFunctionTo) +} - if (packageUrl.isNullOrEmpty()) { - throw error("[glslify] $moduleName not found") - } - - if (!moduleDir.exists()) { - try { - moduleDir.mkdirs() - - val url = URL(packageUrl) - val con = url.openConnection() - val tarStream: InputStream = ByteArrayInputStream(con.getInputStream().readBytes()) - - extractGzipStream(tarStream, moduleDir) - - moveFilesUp(moduleDir) - - File("$moduleDir/package").deleteRecursively() - - logger.trace("[glslify] $moduleName downloaded") - (con as HttpsURLConnection).disconnect() - } catch (ex: Exception) { - logger.error(ex) { "[glslify]: There was an error getting $moduleName" } - - return "" - } +private fun glslifyImport(moduleName: String, moduleDir: Path, shaderPath: Path, renameFunctionTo: String? = null): String { + if (!Files.exists(moduleDir)) { + fetchModule(moduleName, moduleDir) } else { logger.trace("[glslify] $moduleName already exists.. Skipping download") } - val shaderFile: File + val shaderFile: Path try { shaderFile = shaderExtensions.map { - File("$GLSLIFY_PATH/$moduleName/$shaderPath.$it") - }.first { it.exists() } + moduleDir.resolve("$shaderPath.$it") + }.first { Files.exists(it) } } catch (ex: NoSuchElementException) { logger.trace("[glslify] $moduleName: $shaderPath doesn't lead to any shader file") return "" } - val shader = mutableListOf() val imports = mutableListOf() var exportName: String? = null - shaderFile.useLines { sequence -> - for (line in sequence.iterator()) { - if (line.contains("#pragma")) { + var shader = Files.lines(shaderFile).filter { line -> + line.contains("#pragma").let { isPragma -> + if (isPragma) { Regex(IMPORT_PATT).find(line)?.let { if (it.groupValues.size > 1) { - val importExists = File("$GLSLIFY_PATH/${it.groupValues[2]}").exists() + val importPath = Paths.get(GLSLIFY_PATH).resolve(it.groupValues[2]) - imports.add(GlslifyImport(it.groupValues[1], it.groupValues[2], importExists)) + imports.add(GlslifyImport(it.groupValues[1], it.groupValues[2], Files.exists(importPath))) } } @@ -89,11 +71,11 @@ fun glslify(module: String, renameFunctionTo: String? = null): String { exportName = it.groupValues[1] } } - } else { - shader.add(line) } + + !isPragma // we want to exclude any #pragma statements } - } + }.toList().joinToString("\n") val missingImports = imports.filter { !it.exists } @@ -105,11 +87,36 @@ fun glslify(module: String, renameFunctionTo: String? = null): String { throw error("[glslify] Please declare the missing imports") } - var shaderString = shader.joinToString("\n") - if (renameFunctionTo != null && exportName != null) { - shaderString = shaderString.replace( exportName!!, renameFunctionTo) + shader = shader.replace( exportName!!, renameFunctionTo) } - return shaderString + return shader +} + +internal fun fetchModule(moduleName: String, moduleDir: Path) { + val packageUrl = getPackageUrl(moduleName) + + if (packageUrl.isNullOrEmpty()) { + throw error("[glslify] $moduleName not found") + } + + try { + Files.createDirectories(moduleDir) + + val url = URL(packageUrl) + val con = url.openConnection() + val tarStream: InputStream = ByteArrayInputStream(con.getInputStream().readBytes()) + + extractGzipStream(tarStream, moduleDir.toFile()) + + moveFilesUp(moduleDir) + + moduleDir.resolve("package").toFile().deleteRecursively() + + logger.trace("[glslify] $moduleName downloaded") + (con as HttpsURLConnection).disconnect() + } catch (ex: Exception) { + logger.error(ex) { "[glslify]: There was an error getting $moduleName" } + } }