From 0ce85df549f8578e64a9e6757754a4b92c4ccf72 Mon Sep 17 00:00:00 2001 From: Sergey Bogolepov Date: Mon, 12 Feb 2018 16:06:44 +0300 Subject: [PATCH] Minor fixes for samples Added homebrew paths for videoplayer sample Fixed android sample chmod +x calculator/androidApp/gradlew Removed obsolete stubGenerator for html5canvas --- samples/androidNativeActivity/build.gradle | 4 +- samples/androidNativeActivity/settings.gradle | 2 +- .../src/main/kotlin/engine.kt | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- samples/calculator/androidApp/gradlew | 0 .../src/stubGenerator/kotlin/idl.kt | 52 --- .../src/stubGenerator/kotlin/stubGenerator.kt | 342 ------------------ samples/videoplayer/README.md | 1 + samples/videoplayer/build.gradle | 3 +- 9 files changed, 8 insertions(+), 400 deletions(-) mode change 100644 => 100755 samples/calculator/androidApp/gradlew delete mode 100644 samples/html5Canvas/src/stubGenerator/kotlin/idl.kt delete mode 100644 samples/html5Canvas/src/stubGenerator/kotlin/stubGenerator.kt diff --git a/samples/androidNativeActivity/build.gradle b/samples/androidNativeActivity/build.gradle index 75425d0a3f6..c9da5b50a4a 100644 --- a/samples/androidNativeActivity/build.gradle +++ b/samples/androidNativeActivity/build.gradle @@ -2,13 +2,14 @@ buildscript { repositories { jcenter() mavenCentral() + google() maven { url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies" } } dependencies { classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:+" - classpath "com.android.tools.build:gradle:2.3.3" + classpath "com.android.tools.build:gradle:3.0.1" } } @@ -57,7 +58,6 @@ tasks.matching { it.name == 'preBuild' }.all { android { compileSdkVersion 25 - buildToolsVersion '25.0.2' defaultConfig { applicationId 'com.jetbrains.konan_activity2' diff --git a/samples/androidNativeActivity/settings.gradle b/samples/androidNativeActivity/settings.gradle index af876428f84..5842b801908 100644 --- a/samples/androidNativeActivity/settings.gradle +++ b/samples/androidNativeActivity/settings.gradle @@ -1 +1 @@ -includeBuild '../../' +//includeBuild '../../' diff --git a/samples/androidNativeActivity/src/main/kotlin/engine.kt b/samples/androidNativeActivity/src/main/kotlin/engine.kt index ef04bef7bb7..599629e3cc1 100644 --- a/samples/androidNativeActivity/src/main/kotlin/engine.kt +++ b/samples/androidNativeActivity/src/main/kotlin/engine.kt @@ -45,7 +45,7 @@ fun main(args: Array) { } } -fun CPointer<*>?.dereferenceAs(): T = this!!.reinterpret().pointed +inline fun CPointer<*>?.dereferenceAs(): T = this!!.reinterpret().pointed class Engine(val arena: NativePlacement, val state: NativeActivityState) { private val renderer = Renderer(arena, state.activity!!.pointed, state.savedState) diff --git a/samples/calculator/androidApp/gradle/wrapper/gradle-wrapper.properties b/samples/calculator/androidApp/gradle/wrapper/gradle-wrapper.properties index 7c1bd6f3ea9..e2ce1431802 100644 --- a/samples/calculator/androidApp/gradle/wrapper/gradle-wrapper.properties +++ b/samples/calculator/androidApp/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-all.zip diff --git a/samples/calculator/androidApp/gradlew b/samples/calculator/androidApp/gradlew old mode 100644 new mode 100755 diff --git a/samples/html5Canvas/src/stubGenerator/kotlin/idl.kt b/samples/html5Canvas/src/stubGenerator/kotlin/idl.kt deleted file mode 100644 index 52fa6cfe7cb..00000000000 --- a/samples/html5Canvas/src/stubGenerator/kotlin/idl.kt +++ /dev/null @@ -1,52 +0,0 @@ -package org.jetbrains.kotlin.konan.jsinterop.tool - -import org.jetbrains.kotlin.konan.jsinterop.tool.Type.* - -// This shall be an output of Web IDL parser. -val all = listOf( - Interface("Context", - Attribute("lineWidth", Integer), - Attribute("fillStyle", idlString), - Attribute("strokeStyle", idlString), - - Operation("lineTo", Void, Arg("x", Integer), Arg("y", Integer)), - Operation("moveTo", Void, Arg("x", Integer), Arg("y", Integer)), - Operation("beginPath", Void), - Operation("stroke", Void), - Operation("fillRect", Void, Arg("x", Integer), Arg("y", Integer), Arg("width", Integer), Arg("height", Integer)), - Operation("fillText", Void, Arg("test", idlString), Arg("x", Integer), Arg("y", Integer), Arg("maxWidth", Integer)), - Operation("fill", Void), - Operation("closePath", Void) - ), - Interface("DOMRect", - Attribute("left", Integer), - Attribute("right", Integer), - Attribute("top", Integer), - Attribute("bottom", Integer) - ), - Interface("Canvas", - Operation("getContext", InterfaceRef("Context"), Arg("context", idlString)), - Operation("getBoundingClientRect", InterfaceRef("DOMRect")) - ), - Interface("Document", - Operation("getElementById", Object, Arg("id", idlString)) - ), - Interface("MouseEvent", - Attribute("clientX", Integer, readOnly = true), - Attribute("clientY", Integer, readOnly = true) - ), - Interface("Response", - Operation("json", Object) - ), - Interface("Promise", - Operation("then", InterfaceRef("Promise"), Arg("lambda", Function)) - ), - Interface("__Global", - Attribute("document", InterfaceRef("Document"), readOnly = true), - - Operation("fetch", InterfaceRef("Promise"), Arg("url", idlString)), - Operation("setInterval", Void, Arg("lambda", Function), Arg("interval", Integer)) - ) -) - - diff --git a/samples/html5Canvas/src/stubGenerator/kotlin/stubGenerator.kt b/samples/html5Canvas/src/stubGenerator/kotlin/stubGenerator.kt deleted file mode 100644 index 8aca2908981..00000000000 --- a/samples/html5Canvas/src/stubGenerator/kotlin/stubGenerator.kt +++ /dev/null @@ -1,342 +0,0 @@ -package org.jetbrains.kotlin.konan.jsinterop.tool - -import platform.posix.* - -// This is (as of now) a poor man's IDL representation. - -interface Type -interface Member - -object Void: Type -object Integer: Type -object Floating: Type -object idlString: Type -object Object: Type -object Function: Type - -data class Attribute(val name: String, val type: Type, - val readOnly: Boolean = false): Member - -data class Arg(val name: String, val type: Type) - -class Operation(val name: String, val returnType: Type, vararg val args: Arg): Member - -class InterfaceRef(val name: String): Type -class Interface(val name: String, vararg val members: Member) - -fun kotlinHeader(): String { - val packageName = "html5.minimal" - return "package $packageName\n" + - "import kotlinx.wasm.jsinterop.*\n" -} - -fun Type.toKotlinType(argName: String? = null): String { - return when (this) { - is Void -> "Unit" - is Integer -> "Int" - is Floating -> "Float" - is idlString -> "String" - is Object -> "JsValue" - is Function -> "KtFunction" - is InterfaceRef -> name - else -> error("Unexpected type") - } -} - -fun Arg.wasmMapping(): String { - return when (type) { - is Void -> error("An arg can not be Void") - is Integer -> name - is Floating -> name - is idlString -> "stringPointer($name), stringLengthBytes($name)" - is Object -> TODO("implement me") - is Function -> "wrapFunction($name), ArenaManager.currentArena" - is InterfaceRef -> TODO("Implement me") - else -> error("Unexpected type") - } -} - -fun Interface.wasmReturnArg(): String = "ArenaManager.currentArena" - -fun Arg.wasmArgNames(): List { - return when (type) { - is Void -> error("An arg can not be Void") - is Integer -> listOf(name) - is Floating -> listOf(name) - is idlString -> listOf("${name}Ptr", "${name}Len") - is Object -> TODO("implement me (Object)") - is Function -> listOf("${name}Index", "${name}ResultArena") - is InterfaceRef -> TODO("Implement me (InterfaceRef)") - else -> error("Unexpected type") - } -} - -fun Type.wasmReturnMapping(value: String): String { - return when (this) { - is Void -> "" - is Integer -> value - is Floating -> value - is idlString -> "TODO(\"Implement me\")" - is Object -> "JsValue(ArenaManager.currentArena, $value)" - is Function -> "TODO(\"Implement me\")" - is InterfaceRef -> "$name(ArenaManager.currentArena, $value)" - else -> error("Unexpected type") - } -} - -fun wasmFunctionName(functionName: String, interfaceName: String) - = "knjs__${interfaceName}_$functionName" - -fun wasmSetterName(propertyName: String, interfaceName: String) - = "knjs_set__${interfaceName}_$propertyName" - -fun wasmGetterName(propertyName: String, interfaceName: String) - = "knjs_get__${interfaceName}_$propertyName" - -val Operation.kotlinTypeParameters: String get() { - val lambdaRetTypes = args.filter { it.type is Function } - .map { "R${it.name}" }. joinToString(", ") - return if (lambdaRetTypes == "") "" else "<$lambdaRetTypes>" -} - -val Interface.wasmReceiverArgs get() = - if (this.name != "__Global") - listOf("this.arena", "this.index") - else emptyList() - -fun Operation.generateKotlin(parent: Interface): String { - val argList = args.map { - "${it.name}: ${it.type.toKotlinType(it.name)}" - }.joinToString(",") - - val wasmArgList = (parent.wasmReceiverArgs + args.map{it.wasmMapping()} + parent.wasmReturnArg()).joinToString(",") - - // TODO: there can be multiple Rs. - return " fun $kotlinTypeParameters $name(" + - argList + - "): ${returnType.toKotlinType()} {\n" + - - " ${if (returnType != Void) "val wasmRetVal = " else ""}${wasmFunctionName(name, parent.name)}($wasmArgList)\n" + - - " return ${returnType.wasmReturnMapping("wasmRetVal")}\n"+ - " }\n" -} - -fun Attribute.generateKotlinSetter(parent: Interface): String { - val kotlinType = type.toKotlinType(name) - return " set(value: $kotlinType) {\n" + - " ${wasmSetterName(name, parent.name)}(" + - (parent.wasmReceiverArgs + Arg("value", type).wasmMapping()).joinToString(", ") + - ")\n" + - " }\n" -} - -fun Attribute.generateKotlinGetter(parent: Interface): String { - return " get() {\n" + - " val wasmRetVal = ${wasmGetterName(name, parent.name)}(${(parent.wasmReceiverArgs + parent.wasmReturnArg()).joinToString(", ")})\n" + - " return ${type.wasmReturnMapping("wasmRetVal")}\n"+ - " }\n" + - " \n" -} - -fun Attribute.generateKotlin(parent: Interface): String { - val kotlinType = type.toKotlinType(name) - val varOrVal = if (readOnly) "val" else "var" - return " $varOrVal $name: $kotlinType\n" + - generateKotlinGetter(parent) + - if (!readOnly) generateKotlinSetter(parent) else "" -} - -val Interface.wasmTypedReceiverArgs get() = - if (this.name != "__Global") - listOf("arena: Int", "index: Int") - else emptyList() - -fun Operation.generateWasmStub(parent: Interface): String { - val wasmName = wasmFunctionName(this.name, parent.name) - val allArgs = (parent.wasmTypedReceiverArgs + args.toList().wasmTypedMapping() + parent.wasmTypedReturnMapping()).joinToString(", ") - return "@SymbolName(\"$wasmName\")\n" + - "external public fun $wasmName($allArgs): ${returnType.wasmReturnTypeMapping()}\n\n" -} -fun Attribute.generateWasmSetterStub(parent: Interface): String { - val wasmSetter = wasmSetterName(this.name, parent.name) - val allArgs = (parent.wasmTypedReceiverArgs + Arg("value", this.type).wasmTypedMapping()).joinToString(", ") - return "@SymbolName(\"$wasmSetter\")\n" + - "external public fun $wasmSetter($allArgs): Unit\n\n" -} -fun Attribute.generateWasmGetterStub(parent: Interface): String { - val wasmGetter = wasmGetterName(this.name, parent.name) - val allArgs = (parent.wasmTypedReceiverArgs + parent.wasmTypedReturnMapping()).joinToString(", ") - return "@SymbolName(\"$wasmGetter\")\n" + - "external public fun $wasmGetter($allArgs): Int\n\n" -} -fun Attribute.generateWasmStubs(parent: Interface) = - generateWasmGetterStub(parent) + - if (!readOnly) generateWasmSetterStub(parent) else "" - -// TODO: consider using virtual mathods -fun Member.generateKotlin(parent: Interface): String { - return when (this) { - is Operation -> this.generateKotlin(parent) - is Attribute -> this.generateKotlin(parent) - else -> error("Unexpected member") - } -} - -// TODO: consider using virtual mathods -fun Member.generateWasmStub(parent: Interface) = - when (this) { - is Operation -> this.generateWasmStub(parent) - is Attribute -> this.generateWasmStubs(parent) - else -> error("Unexpected member") - - } - -fun Arg.wasmTypedMapping() - = this.wasmArgNames().map { "$it: Int" } .joinToString(", ") - -fun Interface.wasmTypedReturnMapping() - = "resultArena: Int" - -fun List.wasmTypedMapping() - = this.map{ it.wasmTypedMapping() } - -// TODO: more complex return types, such as returning a pair of Ints -// will require a more complex approach. -fun Type.wasmReturnTypeMapping() - = if (this == Void) "Unit" else "Int" - -fun Interface.generateMemberWasmStubs() = - members.map { - it.generateWasmStub(this) - }.joinToString("") - -fun Interface.generateKotlinMembers() = - members.map { - it.generateKotlin(this) - }.joinToString("") - -fun Interface.generateKotlinClassHeader() = - "open class $name(arena: Int, index: Int): JsValue(arena, index) {\n" + - " constructor(jsValue: JsValue): this(jsValue.arena, jsValue.index)\n" - -fun Interface.generateKotlinClassFooter() = - "}\n" - -fun Interface.generateKotlinClassConverter() = - "val JsValue.as$name: $name\n" + - " get() {\n" + - " return $name(this.arena, this.index)\n"+ - " }\n" - -fun Interface.generateKotlin(): String { - - fun String.skipForGlobal() = - if (this@generateKotlin.name != "__Global") this - else "" - - return generateMemberWasmStubs() + - generateKotlinClassHeader().skipForGlobal() + - generateKotlinMembers() + - generateKotlinClassFooter().skipForGlobal() + - generateKotlinClassConverter().skipForGlobal() -} - -fun generateKotlin(interfaces: List) = - kotlinHeader() + - interfaces.map { - it.generateKotlin() - }.joinToString("\n") + - "fun setInterval(interval: Int, lambda: KtFunction) = setInterval(lambda, interval)\n" - -///////////////////////////////////////////////////////// - -fun Arg.composeWasmArgs(): String { - return when (type) { - is Void -> error("An arg can not be Void") - is Integer -> "" - is Floating -> "" - is idlString -> " $name = toUTF16String(${name}Ptr, ${name}Len);\n" - is Object -> TODO("implement me") - is Function -> " $name = konan_dependencies.env.Konan_js_wrapLambda(lambdaResultArena, ${name}Index);\n" - - is InterfaceRef -> TODO("Implement me") - else -> error("Unexpected type") - } -} - -val Interface.receiver get() = - if (this.name == "__Global") "" else "kotlinObject(arena, obj)." - -fun Operation.generateJs(parent: Interface): String { - val allArgs = parent.wasmReceiverArgName + args.map { it.wasmArgNames() }.flatten() + wasmReturnArgName - val wasmMapping = allArgs.joinToString(", ") - val argList = args.map { it.name }. joinToString(", ") - val composedArgsList = args.map { it.composeWasmArgs() }. joinToString("") - - return "\n ${wasmFunctionName(this.name, parent.name)}: function($wasmMapping) {\n" + - composedArgsList + - " var result = ${parent.receiver}$name($argList);\n" + - (if (returnType == Void) "" else " return toArena(resultArena, result);\n") + - " }" -} - -val Interface.wasmReceiverArgName get() = - if (this.name != "__Global") listOf("arena", "obj") else emptyList() - -val Operation.wasmReturnArgName get() = - if (this.returnType != Void) listOf("resultArena") else emptyList() - -val Attribute.wasmReturnArgName get() = - if (this.type != Void) listOf("resultArena") else emptyList() - -fun Attribute.generateJsSetter(parent: Interface): String { - val valueArg = Arg("value", type) - val allArgs = parent.wasmReceiverArgName + valueArg.wasmArgNames() - val wasmMapping = allArgs.joinToString(", ") - return "\n ${wasmSetterName(name, parent.name)}: function($wasmMapping) {\n" + - valueArg.composeWasmArgs() + - " ${parent.receiver}$name = value;\n" + - " }" -} - -fun Attribute.generateJsGetter(parent: Interface): String { - val allArgs = parent.wasmReceiverArgName + wasmReturnArgName - val wasmMapping = allArgs.joinToString(", ") - return "\n ${wasmGetterName(name, parent.name)}: function($wasmMapping) {\n" + - " var result = ${parent.receiver}$name;\n" + - " return toArena(resultArena, result);\n" + - " }" -} - -fun Attribute.generateJs(parent: Interface) = - generateJsGetter(parent) + - if (!readOnly) ",\n${generateJsSetter(parent)}" else "" - -fun Member.generateJs(parent: Interface): String { - return when (this) { - is Operation -> this.generateJs(parent) - is Attribute -> this.generateJs(parent) - else -> error("Unexpected member") - } -} - -fun generateJs(interfaces: List): String = - "konan.libraries.push ({\n" + - interfaces.map { interf -> - interf.members.map { member -> - member.generateJs(interf) - } - }.flatten() .joinToString(",\n") + - "\n})\n" - -fun String.writeToFile(name: String) { - val file = fopen(name, "wb")!! - fputs(this, file) - fclose(file) -} -fun main(args: Array) { - generateKotlin(all).writeToFile("kotlin_stubs.kt") - generateJs(all).writeToFile("js_stubs.js") -} - diff --git a/samples/videoplayer/README.md b/samples/videoplayer/README.md index c6731fbcfc4..b1d47528baa 100644 --- a/samples/videoplayer/README.md +++ b/samples/videoplayer/README.md @@ -5,6 +5,7 @@ Almost any video file supported by ffmpeg could be played with it. ffmpeg and SDL2 is needed for that to work, i.e. port install ffmpeg-devel + brew install ffmpeg sdl2 apt install libavcodec-dev libavformat-dev libavutil-dev libswscale-dev \ libavresample-dev apt install libsdl2-dev diff --git a/samples/videoplayer/build.gradle b/samples/videoplayer/build.gradle index b294d3d4901..f29ab9e5304 100644 --- a/samples/videoplayer/build.gradle +++ b/samples/videoplayer/build.gradle @@ -45,7 +45,8 @@ konanArtifacts { } target 'macbook', { - linkerOpts "-F ${System.getProperty("user.home")}/Library/Frameworks -F /Library/Frameworks -L/opt/local/lib" + linkerOpts "-F ${System.getProperty("user.home")}/Library/Frameworks", "-F /Library/Frameworks", + "-L/opt/local/lib", "-L/usr/local/lib" } target 'linux', {