Add support for presets
This commit is contained in:
@@ -9,7 +9,25 @@ dependencies {
|
|||||||
compile "com.xenomachina:kotlin-argparser:2.0.7"
|
compile "com.xenomachina:kotlin-argparser:2.0.7"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ext.generatedResourcesDir = file("$buildDir/generated-resources")
|
||||||
|
task generateResources {
|
||||||
|
doLast {
|
||||||
|
generatedResourcesDir.mkdir()
|
||||||
|
generatePresetsIndex()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceSets.main.output.dir generatedResourcesDir, builtBy: generateResources
|
||||||
|
|
||||||
|
private void generatePresetsIndex() {
|
||||||
|
def presets = new File(sourceSets.main.resources.srcDirs[0], "presets")
|
||||||
|
def index = new PrintWriter(new FileWriter(new File(generatedResourcesDir, "presets.index")))
|
||||||
|
presets.listFiles().each { index.println(it.name) }
|
||||||
|
index.close()
|
||||||
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
dependsOn generateResources
|
||||||
|
|
||||||
zip64 true
|
zip64 true
|
||||||
manifest {
|
manifest {
|
||||||
attributes 'Main-Class': 'io.smnp.SMNPKt'
|
attributes 'Main-Class': 'io.smnp.SMNPKt'
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import io.smnp.cli.model.enumeration.ModulesPrintMode
|
|||||||
import io.smnp.environment.DefaultEnvironment
|
import io.smnp.environment.DefaultEnvironment
|
||||||
import io.smnp.ext.DefaultModuleRegistry
|
import io.smnp.ext.DefaultModuleRegistry
|
||||||
import io.smnp.interpreter.DefaultInterpreter
|
import io.smnp.interpreter.DefaultInterpreter
|
||||||
|
import io.smnp.preset.PresetProvider.providePresetCode
|
||||||
import io.smnp.type.model.Value
|
import io.smnp.type.model.Value
|
||||||
|
|
||||||
fun main(args: Array<String>): Unit = mainBody {
|
fun main(args: Array<String>): Unit = mainBody {
|
||||||
@@ -19,6 +20,7 @@ fun main(args: Array<String>): Unit = mainBody {
|
|||||||
when {
|
when {
|
||||||
file != null -> interpreter.run(file!!, environment, printTokens, printAst, dryRun)
|
file != null -> interpreter.run(file!!, environment, printTokens, printAst, dryRun)
|
||||||
code != null -> interpreter.run(code!!, environment, printTokens, printAst, dryRun)
|
code != null -> interpreter.run(code!!, environment, printTokens, printAst, dryRun)
|
||||||
|
preset != null -> interpreter.run(providePresetCode(preset!!), environment, printTokens, printAst, dryRun)
|
||||||
else -> null
|
else -> null
|
||||||
}?.let { it as DefaultEnvironment }?.let { disposedEnvironment ->
|
}?.let { it as DefaultEnvironment }?.let { disposedEnvironment ->
|
||||||
if(loadedModules != null) {
|
if(loadedModules != null) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io.smnp.cli.model.entity
|
|||||||
import com.xenomachina.argparser.ArgParser
|
import com.xenomachina.argparser.ArgParser
|
||||||
import com.xenomachina.argparser.default
|
import com.xenomachina.argparser.default
|
||||||
import io.smnp.cli.model.enumeration.ModulesPrintMode
|
import io.smnp.cli.model.enumeration.ModulesPrintMode
|
||||||
|
import io.smnp.preset.PresetProvider
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class Arguments(parser: ArgParser) {
|
class Arguments(parser: ArgParser) {
|
||||||
@@ -30,6 +31,14 @@ class Arguments(parser: ArgParser) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val preset by parser.storing(
|
||||||
|
"-p",
|
||||||
|
"--preset",
|
||||||
|
argName = "NAME",
|
||||||
|
help = "load preset by name and execute it. Preset is a predefined snippet of SMNP code that allows user to " +
|
||||||
|
"perform some useful action without having to script it himself. Presets are located in SMNP executable JAR " +
|
||||||
|
"file. Available presets: ${PresetProvider.presets.joinToString()}"
|
||||||
|
).default<String?>(null)
|
||||||
|
|
||||||
val code by parser.storing("-c", "--code", help = "inline code to be executed").default<String?>(null)
|
val code by parser.storing("-c", "--code", help = "inline code to be executed").default<String?>(null)
|
||||||
val file by parser.positional(
|
val file by parser.positional(
|
||||||
|
|||||||
3
app/src/main/kotlin/io/smnp/error/PresetException.kt
Normal file
3
app/src/main/kotlin/io/smnp/error/PresetException.kt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
package io.smnp.error
|
||||||
|
|
||||||
|
class PresetException(message: String?) : SmnpException("Preset error", message)
|
||||||
24
app/src/main/kotlin/io/smnp/preset/PresetProvider.kt
Normal file
24
app/src/main/kotlin/io/smnp/preset/PresetProvider.kt
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package io.smnp.preset
|
||||||
|
|
||||||
|
import io.smnp.error.PresetException
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.Paths
|
||||||
|
|
||||||
|
object PresetProvider {
|
||||||
|
private const val PRESETS_DIR = "presets"
|
||||||
|
private val classLoader = javaClass.classLoader
|
||||||
|
|
||||||
|
val presets: List<String>
|
||||||
|
get() = classLoader
|
||||||
|
.getResource("presets.index")
|
||||||
|
?.readText()
|
||||||
|
?.trim()
|
||||||
|
?.split("\n")
|
||||||
|
?.map { File(it).nameWithoutExtension }
|
||||||
|
?: throw RuntimeException("Presets index not found")
|
||||||
|
|
||||||
|
fun providePresetCode(name: String) = classLoader
|
||||||
|
.getResource(Paths.get(PRESETS_DIR, "$name.mus").toString())
|
||||||
|
?.readText()
|
||||||
|
?: throw PresetException("Preset with name '$name' does not exist")
|
||||||
|
}
|
||||||
16
app/src/main/resources/presets/alert.mus
Normal file
16
app/src/main/resources/presets/alert.mus
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import smnp.music.tools;
|
||||||
|
import smnp.text;
|
||||||
|
|
||||||
|
infinite = __param__.containsKey("cycles");
|
||||||
|
melody = __param__.getOrDefault("melody", "beep");
|
||||||
|
|
||||||
|
if(infinite) {
|
||||||
|
cycles = __param__.get("cycles").toInt();
|
||||||
|
if(typeOf(cycles) != "int") {
|
||||||
|
throw "Expected 'cycles' to be of int type";
|
||||||
|
}
|
||||||
|
|
||||||
|
alert(cycles, melody);
|
||||||
|
} else {
|
||||||
|
alert(melody);
|
||||||
|
}
|
||||||
15
app/src/main/resources/presets/metronome.mus
Normal file
15
app/src/main/resources/presets/metronome.mus
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import smnp.music.tools;
|
||||||
|
import smnp.text;
|
||||||
|
|
||||||
|
bpm = __param__.getOrDefault("bpm", "120").toInt();
|
||||||
|
if(typeOf(bpm) != "int") {
|
||||||
|
throw "Expected 'bpm' to be of int type";
|
||||||
|
}
|
||||||
|
|
||||||
|
beats = __param__.getOrDefault("beats", "4").toInt();
|
||||||
|
if(typeOf(beats) != "int") {
|
||||||
|
throw "Expected 'beats' to be of int type";
|
||||||
|
}
|
||||||
|
|
||||||
|
metronome(bpm, beats);
|
||||||
|
|
||||||
@@ -18,4 +18,12 @@ extend map as this {
|
|||||||
function isNotEmpty() {
|
function isNotEmpty() {
|
||||||
return not this.isEmpty();
|
return not this.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getOrDefault(key, default) {
|
||||||
|
if(this.containsKey(key)) {
|
||||||
|
return this.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ extend string as this {
|
|||||||
output = -output;
|
output = -output;
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return Int(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
function substring(startIndex: int, endIndex: int) {
|
function substring(startIndex: int, endIndex: int) {
|
||||||
|
|||||||
Reference in New Issue
Block a user