Minor fixes for samples
Added homebrew paths for videoplayer sample Fixed android sample chmod +x calculator/androidApp/gradlew Removed obsolete stubGenerator for html5canvas
This commit is contained in:
committed by
Sergey Bogolepov
parent
43cbea8a67
commit
0ce85df549
@@ -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'
|
||||
|
||||
@@ -1 +1 @@
|
||||
includeBuild '../../'
|
||||
//includeBuild '../../'
|
||||
|
||||
@@ -45,7 +45,7 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : CPointed> CPointer<*>?.dereferenceAs(): T = this!!.reinterpret<T>().pointed
|
||||
inline fun <reified T : CPointed> CPointer<*>?.dereferenceAs(): T = this!!.reinterpret<T>().pointed
|
||||
|
||||
class Engine(val arena: NativePlacement, val state: NativeActivityState) {
|
||||
private val renderer = Renderer(arena, state.activity!!.pointed, state.savedState)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -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<R${argName!!}>"
|
||||
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<R$name>($name), ArenaManager.currentArena"
|
||||
is InterfaceRef -> TODO("Implement me")
|
||||
else -> error("Unexpected type")
|
||||
}
|
||||
}
|
||||
|
||||
fun Interface.wasmReturnArg(): String = "ArenaManager.currentArena"
|
||||
|
||||
fun Arg.wasmArgNames(): List<String> {
|
||||
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<Arg>.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<Interface>) =
|
||||
kotlinHeader() +
|
||||
interfaces.map {
|
||||
it.generateKotlin()
|
||||
}.joinToString("\n") +
|
||||
"fun <R> setInterval(interval: Int, lambda: KtFunction<R>) = 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<Interface>): 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<String>) {
|
||||
generateKotlin(all).writeToFile("kotlin_stubs.kt")
|
||||
generateJs(all).writeToFile("js_stubs.js")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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', {
|
||||
|
||||
Reference in New Issue
Block a user