IDE perf tests for K/N: Produce duplicated *.kt files on demand
This commit is contained in:
+40
@@ -61,6 +61,7 @@ class PerformanceNativeProjectsTest : AbstractPerformanceProjectsTest() {
|
|||||||
|
|
||||||
private enum class TestProject(
|
private enum class TestProject(
|
||||||
val templateName: String,
|
val templateName: String,
|
||||||
|
val duplicatesAmount: Int = 2,
|
||||||
val filesToHighlight: List<String>
|
val filesToHighlight: List<String>
|
||||||
) {
|
) {
|
||||||
HELLO_WORLD(
|
HELLO_WORLD(
|
||||||
@@ -85,6 +86,7 @@ class PerformanceNativeProjectsTest : AbstractPerformanceProjectsTest() {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
assertTrue(filesToHighlight.isNotEmpty())
|
assertTrue(filesToHighlight.isNotEmpty())
|
||||||
|
assertTrue(duplicatesAmount in 0..100)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,6 +232,44 @@ class PerformanceNativeProjectsTest : AbstractPerformanceProjectsTest() {
|
|||||||
fail("Some files have not been merged in project root directory: $projectRoot: ${unmergedFiles.joinToString()}")
|
fail("Some files have not been merged in project root directory: $projectRoot: ${unmergedFiles.joinToString()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// produce N duplicates of *.kt files inside the project root
|
||||||
|
if (testProject.duplicatesAmount > 0) {
|
||||||
|
val originalKtFiles = projectRoot.walkTopDown()
|
||||||
|
.filter { it.isFile && it.name.endsWith(".kt") }
|
||||||
|
.toList()
|
||||||
|
|
||||||
|
for (originalKtFile in originalKtFiles) {
|
||||||
|
val originalKtFileContents = originalKtFile.readLines()
|
||||||
|
|
||||||
|
assertTrue(
|
||||||
|
"$originalKtFile must have @file:Suppress(\"PackageDirectoryMismatch\") annotation",
|
||||||
|
originalKtFileContents.any { it.startsWith("@file:Suppress") && it.contains("\"PackageDirectoryMismatch\"") }
|
||||||
|
)
|
||||||
|
|
||||||
|
val packageLineIndex = originalKtFileContents.indexOfFirst { it.startsWith("package perfTestPackage1") }
|
||||||
|
assertTrue(
|
||||||
|
"$originalKtFile must have package declaration: package perfTestPackage1",
|
||||||
|
packageLineIndex != -1
|
||||||
|
)
|
||||||
|
|
||||||
|
for (i in 1..testProject.duplicatesAmount) {
|
||||||
|
val n = i + 1
|
||||||
|
val duplicateKtFile = originalKtFile.resolveSibling("${originalKtFile.nameWithoutExtension}$n.kt")
|
||||||
|
duplicateKtFile.writeText(
|
||||||
|
buildString {
|
||||||
|
originalKtFileContents.forEachIndexed { index, line ->
|
||||||
|
if (index == packageLineIndex) {
|
||||||
|
appendln(line.replace("perfTestPackage1", "perfTestPackage$n"))
|
||||||
|
} else {
|
||||||
|
appendln(line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check all necessary files are there
|
// check all necessary files are there
|
||||||
listOf("build.gradle.kts", "settings.gradle.kts", "gradle.properties")
|
listOf("build.gradle.kts", "settings.gradle.kts", "gradle.properties")
|
||||||
.filter { !projectRoot.resolve(it).exists() }
|
.filter { !projectRoot.resolve(it).exists() }
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("PackageDirectoryMismatch")
|
||||||
|
package perfTestPackage1 // this package is mandatory
|
||||||
|
|
||||||
import kotlinx.cinterop.ByteVar
|
import kotlinx.cinterop.ByteVar
|
||||||
import kotlinx.cinterop.allocArray
|
import kotlinx.cinterop.allocArray
|
||||||
import kotlinx.cinterop.memScoped
|
import kotlinx.cinterop.memScoped
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import kotlinx.cinterop.ByteVar
|
|
||||||
import kotlinx.cinterop.allocArray
|
|
||||||
import kotlinx.cinterop.memScoped
|
|
||||||
import kotlinx.cinterop.toKString
|
|
||||||
import kotlinx.cli.ArgParser
|
|
||||||
import kotlinx.cli.ArgType
|
|
||||||
import kotlinx.cli.required
|
|
||||||
import platform.posix.fclose
|
|
||||||
import platform.posix.fgets
|
|
||||||
import platform.posix.fopen
|
|
||||||
import platform.posix.perror
|
|
||||||
import kotlin.collections.set
|
|
||||||
|
|
||||||
private fun parseLine(line: String, separator: Char) : List<String> {
|
|
||||||
val result = mutableListOf<String>()
|
|
||||||
val builder = StringBuilder()
|
|
||||||
var quotes = 0
|
|
||||||
for (ch in line) {
|
|
||||||
when {
|
|
||||||
ch == '\"' -> {
|
|
||||||
quotes++
|
|
||||||
builder.append(ch)
|
|
||||||
}
|
|
||||||
(ch == '\n') || (ch == '\r') -> {}
|
|
||||||
(ch == separator) && (quotes % 2 == 0) -> {
|
|
||||||
result.add(builder.toString())
|
|
||||||
builder.setLength(0)
|
|
||||||
}
|
|
||||||
else -> builder.append(ch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
val argParser = ArgParser("csvparser")
|
|
||||||
val fileName by argParser.argument(ArgType.String, description = "CSV file")
|
|
||||||
val column by argParser.option(ArgType.Int, description = "Column to parse").required()
|
|
||||||
val count by argParser.option(ArgType.Int, description = "Count of lines to parse").required()
|
|
||||||
argParser.parse(args)
|
|
||||||
|
|
||||||
val file = fopen(fileName, "r")
|
|
||||||
if (file == null) {
|
|
||||||
perror("cannot open input file $fileName")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val keyValue = mutableMapOf<String, Int>()
|
|
||||||
|
|
||||||
try {
|
|
||||||
memScoped {
|
|
||||||
val bufferLength = 64 * 1024
|
|
||||||
val buffer = allocArray<ByteVar>(bufferLength)
|
|
||||||
|
|
||||||
for (i in 1..count) {
|
|
||||||
val nextLine = fgets(buffer, bufferLength, file)?.toKString()
|
|
||||||
if (nextLine == null || nextLine.isEmpty()) break
|
|
||||||
|
|
||||||
val records = parseLine(nextLine, ',')
|
|
||||||
val key = records[column]
|
|
||||||
val current = keyValue[key] ?: 0
|
|
||||||
keyValue[key] = current + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
fclose(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
keyValue.forEach {
|
|
||||||
println("${it.key} -> ${it.value}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import kotlinx.cinterop.ByteVar
|
|
||||||
import kotlinx.cinterop.allocArray
|
|
||||||
import kotlinx.cinterop.memScoped
|
|
||||||
import kotlinx.cinterop.toKString
|
|
||||||
import kotlinx.cli.ArgParser
|
|
||||||
import kotlinx.cli.ArgType
|
|
||||||
import kotlinx.cli.required
|
|
||||||
import platform.posix.fclose
|
|
||||||
import platform.posix.fgets
|
|
||||||
import platform.posix.fopen
|
|
||||||
import platform.posix.perror
|
|
||||||
import kotlin.collections.set
|
|
||||||
|
|
||||||
private fun parseLine(line: String, separator: Char) : List<String> {
|
|
||||||
val result = mutableListOf<String>()
|
|
||||||
val builder = StringBuilder()
|
|
||||||
var quotes = 0
|
|
||||||
for (ch in line) {
|
|
||||||
when {
|
|
||||||
ch == '\"' -> {
|
|
||||||
quotes++
|
|
||||||
builder.append(ch)
|
|
||||||
}
|
|
||||||
(ch == '\n') || (ch == '\r') -> {}
|
|
||||||
(ch == separator) && (quotes % 2 == 0) -> {
|
|
||||||
result.add(builder.toString())
|
|
||||||
builder.setLength(0)
|
|
||||||
}
|
|
||||||
else -> builder.append(ch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
val argParser = ArgParser("csvparser")
|
|
||||||
val fileName by argParser.argument(ArgType.String, description = "CSV file")
|
|
||||||
val column by argParser.option(ArgType.Int, description = "Column to parse").required()
|
|
||||||
val count by argParser.option(ArgType.Int, description = "Count of lines to parse").required()
|
|
||||||
argParser.parse(args)
|
|
||||||
|
|
||||||
val file = fopen(fileName, "r")
|
|
||||||
if (file == null) {
|
|
||||||
perror("cannot open input file $fileName")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val keyValue = mutableMapOf<String, Int>()
|
|
||||||
|
|
||||||
try {
|
|
||||||
memScoped {
|
|
||||||
val bufferLength = 64 * 1024
|
|
||||||
val buffer = allocArray<ByteVar>(bufferLength)
|
|
||||||
|
|
||||||
for (i in 1..count) {
|
|
||||||
val nextLine = fgets(buffer, bufferLength, file)?.toKString()
|
|
||||||
if (nextLine == null || nextLine.isEmpty()) break
|
|
||||||
|
|
||||||
val records = parseLine(nextLine, ',')
|
|
||||||
val key = records[column]
|
|
||||||
val current = keyValue[key] ?: 0
|
|
||||||
keyValue[key] = current + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
fclose(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
keyValue.forEach {
|
|
||||||
println("${it.key} -> ${it.value}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@file:Suppress("PackageDirectoryMismatch")
|
||||||
|
package perfTestPackage1 // this package is mandatory
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
println("Hello World!")
|
println("Hello World!")
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
println("Hello World!")
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
println("Hello World!")
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
@file:Suppress("PackageDirectoryMismatch")
|
||||||
|
package perfTestPackage1 // this package is mandatory
|
||||||
|
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import kotlin.test.Test
|
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
private const val GREETING = "Hello, Kotlin/Native!"
|
|
||||||
|
|
||||||
class HelloTest2 {
|
|
||||||
@Test
|
|
||||||
fun testHello() {
|
|
||||||
assertTrue("Kotlin/Native" in GREETING)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import kotlin.test.Test
|
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
private const val GREETING = "Hello, Kotlin/Native!"
|
|
||||||
|
|
||||||
class HelloTest3 {
|
|
||||||
@Test
|
|
||||||
fun testHello() {
|
|
||||||
assertTrue("Kotlin/Native" in GREETING)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+2
-1
@@ -3,7 +3,8 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:Suppress("RemoveRedundantCallsOfConversionMethods", "unused", "CanBeParameter")
|
@file:Suppress("PackageDirectoryMismatch", "RemoveRedundantCallsOfConversionMethods", "unused", "CanBeParameter")
|
||||||
|
package perfTestPackage1 // this package is mandatory
|
||||||
|
|
||||||
import kotlinx.cinterop.FloatVar
|
import kotlinx.cinterop.FloatVar
|
||||||
import kotlinx.cinterop.allocArray
|
import kotlinx.cinterop.allocArray
|
||||||
|
|||||||
@@ -1,234 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@file:Suppress("RemoveRedundantCallsOfConversionMethods", "unused", "CanBeParameter")
|
|
||||||
|
|
||||||
import kotlinx.cinterop.FloatVar
|
|
||||||
import kotlinx.cinterop.allocArray
|
|
||||||
import kotlinx.cinterop.cValuesOf
|
|
||||||
import kotlinx.cinterop.memScoped
|
|
||||||
import kotlinx.cinterop.set
|
|
||||||
import kotlinx.cinterop.toCValues
|
|
||||||
import platform.gles.GL_COLOR_BUFFER_BIT
|
|
||||||
import platform.gles.GL_CULL_FACE
|
|
||||||
import platform.gles.GL_CW
|
|
||||||
import platform.gles.GL_DEPTH_BUFFER_BIT
|
|
||||||
import platform.gles.GL_DEPTH_TEST
|
|
||||||
import platform.gles.GL_DIFFUSE
|
|
||||||
import platform.gles.GL_DITHER
|
|
||||||
import platform.gles.GL_FASTEST
|
|
||||||
import platform.gles.GL_FLOAT
|
|
||||||
import platform.gles.GL_FRONT_AND_BACK
|
|
||||||
import platform.gles.GL_LIGHT0
|
|
||||||
import platform.gles.GL_LIGHTING
|
|
||||||
import platform.gles.GL_MODELVIEW
|
|
||||||
import platform.gles.GL_NORMAL_ARRAY
|
|
||||||
import platform.gles.GL_PERSPECTIVE_CORRECTION_HINT
|
|
||||||
import platform.gles.GL_POSITION
|
|
||||||
import platform.gles.GL_PROJECTION
|
|
||||||
import platform.gles.GL_SHININESS
|
|
||||||
import platform.gles.GL_SMOOTH
|
|
||||||
import platform.gles.GL_SPECULAR
|
|
||||||
import platform.gles.GL_TEXTURE_2D
|
|
||||||
import platform.gles.GL_TEXTURE_COORD_ARRAY
|
|
||||||
import platform.gles.GL_TRIANGLES
|
|
||||||
import platform.gles.GL_UNSIGNED_BYTE
|
|
||||||
import platform.gles.GL_VERTEX_ARRAY
|
|
||||||
import platform.gles.glClear
|
|
||||||
import platform.gles.glClearColor
|
|
||||||
import platform.gles.glDisable
|
|
||||||
import platform.gles.glDrawElements
|
|
||||||
import platform.gles.glEnable
|
|
||||||
import platform.gles.glEnableClientState
|
|
||||||
import platform.gles.glFrontFace
|
|
||||||
import platform.gles.glFrustumf
|
|
||||||
import platform.gles.glHint
|
|
||||||
import platform.gles.glLightfv
|
|
||||||
import platform.gles.glLoadIdentity
|
|
||||||
import platform.gles.glMaterialf
|
|
||||||
import platform.gles.glMaterialfv
|
|
||||||
import platform.gles.glMatrixMode
|
|
||||||
import platform.gles.glMultMatrixf
|
|
||||||
import platform.gles.glNormalPointer
|
|
||||||
import platform.gles.glPopMatrix
|
|
||||||
import platform.gles.glPushMatrix
|
|
||||||
import platform.gles.glShadeModel
|
|
||||||
import platform.gles.glTexCoordPointer
|
|
||||||
import platform.gles.glTranslatef
|
|
||||||
import platform.gles.glVertexPointer
|
|
||||||
import platform.gles.glViewport
|
|
||||||
import platform.posix.sqrtf
|
|
||||||
|
|
||||||
private const val WIDTH = 600
|
|
||||||
private const val HEIGHT = 800
|
|
||||||
private const val SCALE = 1.25f
|
|
||||||
|
|
||||||
fun main() = memScoped {
|
|
||||||
glDisable(GL_DITHER)
|
|
||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)
|
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f)
|
|
||||||
glEnable(GL_CULL_FACE)
|
|
||||||
glShadeModel(GL_SMOOTH)
|
|
||||||
glEnable(GL_DEPTH_TEST)
|
|
||||||
|
|
||||||
glViewport(0, 0, WIDTH, HEIGHT)
|
|
||||||
|
|
||||||
val ratio = WIDTH.toFloat() / HEIGHT
|
|
||||||
glMatrixMode(GL_PROJECTION)
|
|
||||||
glLoadIdentity()
|
|
||||||
glFrustumf(-ratio, ratio, -1.0f, 1.0f, 1.0f, 10.0f)
|
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW)
|
|
||||||
glTranslatef(0.0f, 0.0f, -2.0f)
|
|
||||||
glLightfv(GL_LIGHT0, GL_POSITION, cValuesOf(1.25f, 1.25f, -2.0f, 0.0f))
|
|
||||||
glEnable(GL_LIGHTING)
|
|
||||||
glEnable(GL_LIGHT0)
|
|
||||||
glEnable(GL_TEXTURE_2D)
|
|
||||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, cValuesOf(0.0f, 1.0f, 1.0f, 1.0f))
|
|
||||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, cValuesOf(0.3f, 0.3f, 0.3f, 1.0f))
|
|
||||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 30.0f)
|
|
||||||
|
|
||||||
glPushMatrix()
|
|
||||||
glMatrixMode(GL_MODELVIEW)
|
|
||||||
|
|
||||||
|
|
||||||
val matrix = allocArray<FloatVar>(16)
|
|
||||||
for (i in 0..3)
|
|
||||||
for (j in 0..3)
|
|
||||||
matrix[i * 4 + j] = if (i == j) 1.0f else 0.0f
|
|
||||||
|
|
||||||
glMultMatrixf(matrix)
|
|
||||||
|
|
||||||
glClear((GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT).toUInt())
|
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY)
|
|
||||||
glEnableClientState(GL_NORMAL_ARRAY)
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
|
|
||||||
|
|
||||||
val polygon = RegularPolyhedra.Dodecahedron
|
|
||||||
val vertices = mutableListOf<Float>()
|
|
||||||
val texCoords = mutableListOf<Float>()
|
|
||||||
val triangles = mutableListOf<Byte>()
|
|
||||||
val normals = mutableListOf<Float>()
|
|
||||||
|
|
||||||
val texturePoints = arrayOf(Vector2(0.0f, 0.2f), Vector2(0.0f, 0.8f), Vector2(0.6f, 1.0f), Vector2(1.0f, 0.5f), Vector2(0.8f, 0.0f))
|
|
||||||
|
|
||||||
|
|
||||||
for (face in polygon.faces) {
|
|
||||||
val u = polygon.vertices[face[2].toInt()] - polygon.vertices[face[1].toInt()]
|
|
||||||
val v = polygon.vertices[face[0].toInt()] - polygon.vertices[face[1].toInt()]
|
|
||||||
val normal = u.crossProduct(v).normalized()
|
|
||||||
|
|
||||||
val copiedFace = ByteArray(face.size)
|
|
||||||
for (j in face.indices) {
|
|
||||||
copiedFace[j] = (vertices.size / 4).toByte()
|
|
||||||
polygon.vertices[face[j].toInt()].copyCoordinatesTo(vertices)
|
|
||||||
vertices.add(SCALE)
|
|
||||||
normal.copyCoordinatesTo(normals)
|
|
||||||
texturePoints[j].copyCoordinatesTo(texCoords)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j in 1..face.size - 2) {
|
|
||||||
triangles.add(copiedFace[0])
|
|
||||||
triangles.add(copiedFace[j])
|
|
||||||
triangles.add(copiedFace[j + 1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glFrontFace(GL_CW)
|
|
||||||
glVertexPointer(4, GL_FLOAT, 0, vertices.toFloatArray().toCValues().ptr)
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, texCoords.toFloatArray().toCValues().ptr)
|
|
||||||
glNormalPointer(GL_FLOAT, 0, normals.toFloatArray().toCValues().ptr)
|
|
||||||
glDrawElements(GL_TRIANGLES, triangles.size, GL_UNSIGNED_BYTE, triangles.toByteArray().toCValues().ptr)
|
|
||||||
|
|
||||||
glPopMatrix()
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Vector2(val x: Float, val y: Float) {
|
|
||||||
val length by lazy { sqrtf(x * x + y * y) }
|
|
||||||
|
|
||||||
fun normalized(): Vector2 {
|
|
||||||
val len = length
|
|
||||||
return Vector2(x / len, y / len)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun copyCoordinatesTo(arr: MutableList<Float>) {
|
|
||||||
arr.add(x)
|
|
||||||
arr.add(y)
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun minus(other: Vector2) = Vector2(x - other.x, y - other.y)
|
|
||||||
operator fun plus(other: Vector2) = Vector2(x + other.x, y + other.y)
|
|
||||||
operator fun times(other: Float) = Vector2(x * other, y * other)
|
|
||||||
operator fun div(other: Float) = Vector2(x / other, y / other)
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val Zero = Vector2(0.0f, 0.0f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Vector3(val x: Float, val y: Float, val z: Float) {
|
|
||||||
val length by lazy { sqrtf(x * x + y * y + z * z) }
|
|
||||||
|
|
||||||
fun crossProduct(other: Vector3): Vector3 =
|
|
||||||
Vector3(y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x)
|
|
||||||
|
|
||||||
fun normalized(): Vector3 {
|
|
||||||
val len = length
|
|
||||||
return Vector3(x / len, y / len, z / len)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun copyCoordinatesTo(arr: MutableList<Float>) {
|
|
||||||
arr.add(x)
|
|
||||||
arr.add(y)
|
|
||||||
arr.add(z)
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun minus(other: Vector3) = Vector3(x - other.x, y - other.y, z - other.z)
|
|
||||||
operator fun plus(other: Vector3) = Vector3(x + other.x, y + other.y, z + other.z)
|
|
||||||
}
|
|
||||||
|
|
||||||
private const val Zero = 0.0f
|
|
||||||
private const val DodeA = 0.93417235896f // (Sqrt(5) + 1) / (2 * Sqrt(3))
|
|
||||||
private const val DodeB = 0.35682208977f // (Sqrt(5) - 1) / (2 * Sqrt(3))
|
|
||||||
private const val DodeC = 0.57735026919f // 1 / Sqrt(3)
|
|
||||||
private const val IcosA = 0.52573111212f // Sqrt(5 - Sqrt(5)) / Sqrt(10)
|
|
||||||
private const val IcosB = 0.85065080835f // Sqrt(5 + Sqrt(5)) / Sqrt(10)
|
|
||||||
|
|
||||||
private enum class RegularPolyhedra(val vertices: Array<Vector3>, val faces: Array<ByteArray>) {
|
|
||||||
Dodecahedron(
|
|
||||||
arrayOf(
|
|
||||||
Vector3(-DodeA, Zero, DodeB), Vector3(-DodeA, Zero, -DodeB), Vector3(DodeA, Zero, -DodeB),
|
|
||||||
Vector3(DodeA, Zero, DodeB), Vector3(DodeB, -DodeA, Zero), Vector3(-DodeB, -DodeA, Zero),
|
|
||||||
Vector3(-DodeB, DodeA, Zero), Vector3(DodeB, DodeA, Zero), Vector3(Zero, DodeB, -DodeA),
|
|
||||||
Vector3(Zero, -DodeB, -DodeA), Vector3(Zero, -DodeB, DodeA), Vector3(Zero, DodeB, DodeA),
|
|
||||||
Vector3(-DodeC, -DodeC, DodeC), Vector3(-DodeC, -DodeC, -DodeC), Vector3(DodeC, -DodeC, -DodeC),
|
|
||||||
Vector3(DodeC, -DodeC, DodeC), Vector3(-DodeC, DodeC, DodeC), Vector3(-DodeC, DodeC, -DodeC),
|
|
||||||
Vector3(DodeC, DodeC, -DodeC), Vector3(DodeC, DodeC, DodeC)
|
|
||||||
),
|
|
||||||
arrayOf(
|
|
||||||
byteArrayOf(0, 12, 10, 11, 16), byteArrayOf(1, 17, 8, 9, 13), byteArrayOf(2, 14, 9, 8, 18),
|
|
||||||
byteArrayOf(3, 19, 11, 10, 15), byteArrayOf(4, 14, 2, 3, 15), byteArrayOf(5, 12, 0, 1, 13),
|
|
||||||
byteArrayOf(6, 17, 1, 0, 16), byteArrayOf(7, 19, 3, 2, 18), byteArrayOf(8, 17, 6, 7, 18),
|
|
||||||
byteArrayOf(9, 14, 4, 5, 13), byteArrayOf(10, 12, 5, 4, 15), byteArrayOf(11, 19, 7, 6, 16)
|
|
||||||
)),
|
|
||||||
Icosahedron(
|
|
||||||
arrayOf(
|
|
||||||
Vector3(-IcosA, Zero, IcosB), Vector3(IcosA, Zero, IcosB), Vector3(-IcosA, Zero, -IcosB),
|
|
||||||
Vector3(IcosA, Zero, -IcosB), Vector3(Zero, IcosB, IcosA), Vector3(Zero, IcosB, -IcosA),
|
|
||||||
Vector3(Zero, -IcosB, IcosA), Vector3(Zero, -IcosB, -IcosA), Vector3(IcosB, IcosA, Zero),
|
|
||||||
Vector3(-IcosB, IcosA, Zero), Vector3(IcosB, -IcosA, Zero), Vector3(-IcosB, -IcosA, Zero)
|
|
||||||
),
|
|
||||||
arrayOf(
|
|
||||||
byteArrayOf(1, 4, 0), byteArrayOf(4, 9, 0), byteArrayOf(4, 5, 9), byteArrayOf(8, 5, 4),
|
|
||||||
byteArrayOf(1, 8, 4), byteArrayOf(1, 10, 8), byteArrayOf(10, 3, 8), byteArrayOf(8, 3, 5),
|
|
||||||
byteArrayOf(3, 2, 5), byteArrayOf(3, 7, 2), byteArrayOf(3, 10, 7), byteArrayOf(10, 6, 7),
|
|
||||||
byteArrayOf(6, 11, 7), byteArrayOf(6, 0, 11), byteArrayOf(6, 1, 0), byteArrayOf(10, 1, 6),
|
|
||||||
byteArrayOf(11, 0, 9), byteArrayOf(2, 11, 9), byteArrayOf(5, 2, 9), byteArrayOf(11, 2, 7)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
val verticesPerFace get() = faces[0].size
|
|
||||||
}
|
|
||||||
@@ -1,234 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@file:Suppress("RemoveRedundantCallsOfConversionMethods", "unused", "CanBeParameter")
|
|
||||||
|
|
||||||
import kotlinx.cinterop.FloatVar
|
|
||||||
import kotlinx.cinterop.allocArray
|
|
||||||
import kotlinx.cinterop.cValuesOf
|
|
||||||
import kotlinx.cinterop.memScoped
|
|
||||||
import kotlinx.cinterop.set
|
|
||||||
import kotlinx.cinterop.toCValues
|
|
||||||
import platform.gles.GL_COLOR_BUFFER_BIT
|
|
||||||
import platform.gles.GL_CULL_FACE
|
|
||||||
import platform.gles.GL_CW
|
|
||||||
import platform.gles.GL_DEPTH_BUFFER_BIT
|
|
||||||
import platform.gles.GL_DEPTH_TEST
|
|
||||||
import platform.gles.GL_DIFFUSE
|
|
||||||
import platform.gles.GL_DITHER
|
|
||||||
import platform.gles.GL_FASTEST
|
|
||||||
import platform.gles.GL_FLOAT
|
|
||||||
import platform.gles.GL_FRONT_AND_BACK
|
|
||||||
import platform.gles.GL_LIGHT0
|
|
||||||
import platform.gles.GL_LIGHTING
|
|
||||||
import platform.gles.GL_MODELVIEW
|
|
||||||
import platform.gles.GL_NORMAL_ARRAY
|
|
||||||
import platform.gles.GL_PERSPECTIVE_CORRECTION_HINT
|
|
||||||
import platform.gles.GL_POSITION
|
|
||||||
import platform.gles.GL_PROJECTION
|
|
||||||
import platform.gles.GL_SHININESS
|
|
||||||
import platform.gles.GL_SMOOTH
|
|
||||||
import platform.gles.GL_SPECULAR
|
|
||||||
import platform.gles.GL_TEXTURE_2D
|
|
||||||
import platform.gles.GL_TEXTURE_COORD_ARRAY
|
|
||||||
import platform.gles.GL_TRIANGLES
|
|
||||||
import platform.gles.GL_UNSIGNED_BYTE
|
|
||||||
import platform.gles.GL_VERTEX_ARRAY
|
|
||||||
import platform.gles.glClear
|
|
||||||
import platform.gles.glClearColor
|
|
||||||
import platform.gles.glDisable
|
|
||||||
import platform.gles.glDrawElements
|
|
||||||
import platform.gles.glEnable
|
|
||||||
import platform.gles.glEnableClientState
|
|
||||||
import platform.gles.glFrontFace
|
|
||||||
import platform.gles.glFrustumf
|
|
||||||
import platform.gles.glHint
|
|
||||||
import platform.gles.glLightfv
|
|
||||||
import platform.gles.glLoadIdentity
|
|
||||||
import platform.gles.glMaterialf
|
|
||||||
import platform.gles.glMaterialfv
|
|
||||||
import platform.gles.glMatrixMode
|
|
||||||
import platform.gles.glMultMatrixf
|
|
||||||
import platform.gles.glNormalPointer
|
|
||||||
import platform.gles.glPopMatrix
|
|
||||||
import platform.gles.glPushMatrix
|
|
||||||
import platform.gles.glShadeModel
|
|
||||||
import platform.gles.glTexCoordPointer
|
|
||||||
import platform.gles.glTranslatef
|
|
||||||
import platform.gles.glVertexPointer
|
|
||||||
import platform.gles.glViewport
|
|
||||||
import platform.posix.sqrtf
|
|
||||||
|
|
||||||
private const val WIDTH = 600
|
|
||||||
private const val HEIGHT = 800
|
|
||||||
private const val SCALE = 1.25f
|
|
||||||
|
|
||||||
fun main() = memScoped {
|
|
||||||
glDisable(GL_DITHER)
|
|
||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)
|
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f)
|
|
||||||
glEnable(GL_CULL_FACE)
|
|
||||||
glShadeModel(GL_SMOOTH)
|
|
||||||
glEnable(GL_DEPTH_TEST)
|
|
||||||
|
|
||||||
glViewport(0, 0, WIDTH, HEIGHT)
|
|
||||||
|
|
||||||
val ratio = WIDTH.toFloat() / HEIGHT
|
|
||||||
glMatrixMode(GL_PROJECTION)
|
|
||||||
glLoadIdentity()
|
|
||||||
glFrustumf(-ratio, ratio, -1.0f, 1.0f, 1.0f, 10.0f)
|
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW)
|
|
||||||
glTranslatef(0.0f, 0.0f, -2.0f)
|
|
||||||
glLightfv(GL_LIGHT0, GL_POSITION, cValuesOf(1.25f, 1.25f, -2.0f, 0.0f))
|
|
||||||
glEnable(GL_LIGHTING)
|
|
||||||
glEnable(GL_LIGHT0)
|
|
||||||
glEnable(GL_TEXTURE_2D)
|
|
||||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, cValuesOf(0.0f, 1.0f, 1.0f, 1.0f))
|
|
||||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, cValuesOf(0.3f, 0.3f, 0.3f, 1.0f))
|
|
||||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 30.0f)
|
|
||||||
|
|
||||||
glPushMatrix()
|
|
||||||
glMatrixMode(GL_MODELVIEW)
|
|
||||||
|
|
||||||
|
|
||||||
val matrix = allocArray<FloatVar>(16)
|
|
||||||
for (i in 0..3)
|
|
||||||
for (j in 0..3)
|
|
||||||
matrix[i * 4 + j] = if (i == j) 1.0f else 0.0f
|
|
||||||
|
|
||||||
glMultMatrixf(matrix)
|
|
||||||
|
|
||||||
glClear((GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT).toUInt())
|
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY)
|
|
||||||
glEnableClientState(GL_NORMAL_ARRAY)
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
|
|
||||||
|
|
||||||
val polygon = RegularPolyhedra.Dodecahedron
|
|
||||||
val vertices = mutableListOf<Float>()
|
|
||||||
val texCoords = mutableListOf<Float>()
|
|
||||||
val triangles = mutableListOf<Byte>()
|
|
||||||
val normals = mutableListOf<Float>()
|
|
||||||
|
|
||||||
val texturePoints = arrayOf(Vector2(0.0f, 0.2f), Vector2(0.0f, 0.8f), Vector2(0.6f, 1.0f), Vector2(1.0f, 0.5f), Vector2(0.8f, 0.0f))
|
|
||||||
|
|
||||||
|
|
||||||
for (face in polygon.faces) {
|
|
||||||
val u = polygon.vertices[face[2].toInt()] - polygon.vertices[face[1].toInt()]
|
|
||||||
val v = polygon.vertices[face[0].toInt()] - polygon.vertices[face[1].toInt()]
|
|
||||||
val normal = u.crossProduct(v).normalized()
|
|
||||||
|
|
||||||
val copiedFace = ByteArray(face.size)
|
|
||||||
for (j in face.indices) {
|
|
||||||
copiedFace[j] = (vertices.size / 4).toByte()
|
|
||||||
polygon.vertices[face[j].toInt()].copyCoordinatesTo(vertices)
|
|
||||||
vertices.add(SCALE)
|
|
||||||
normal.copyCoordinatesTo(normals)
|
|
||||||
texturePoints[j].copyCoordinatesTo(texCoords)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j in 1..face.size - 2) {
|
|
||||||
triangles.add(copiedFace[0])
|
|
||||||
triangles.add(copiedFace[j])
|
|
||||||
triangles.add(copiedFace[j + 1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glFrontFace(GL_CW)
|
|
||||||
glVertexPointer(4, GL_FLOAT, 0, vertices.toFloatArray().toCValues().ptr)
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, texCoords.toFloatArray().toCValues().ptr)
|
|
||||||
glNormalPointer(GL_FLOAT, 0, normals.toFloatArray().toCValues().ptr)
|
|
||||||
glDrawElements(GL_TRIANGLES, triangles.size, GL_UNSIGNED_BYTE, triangles.toByteArray().toCValues().ptr)
|
|
||||||
|
|
||||||
glPopMatrix()
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Vector2(val x: Float, val y: Float) {
|
|
||||||
val length by lazy { sqrtf(x * x + y * y) }
|
|
||||||
|
|
||||||
fun normalized(): Vector2 {
|
|
||||||
val len = length
|
|
||||||
return Vector2(x / len, y / len)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun copyCoordinatesTo(arr: MutableList<Float>) {
|
|
||||||
arr.add(x)
|
|
||||||
arr.add(y)
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun minus(other: Vector2) = Vector2(x - other.x, y - other.y)
|
|
||||||
operator fun plus(other: Vector2) = Vector2(x + other.x, y + other.y)
|
|
||||||
operator fun times(other: Float) = Vector2(x * other, y * other)
|
|
||||||
operator fun div(other: Float) = Vector2(x / other, y / other)
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val Zero = Vector2(0.0f, 0.0f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Vector3(val x: Float, val y: Float, val z: Float) {
|
|
||||||
val length by lazy { sqrtf(x * x + y * y + z * z) }
|
|
||||||
|
|
||||||
fun crossProduct(other: Vector3): Vector3 =
|
|
||||||
Vector3(y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x)
|
|
||||||
|
|
||||||
fun normalized(): Vector3 {
|
|
||||||
val len = length
|
|
||||||
return Vector3(x / len, y / len, z / len)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun copyCoordinatesTo(arr: MutableList<Float>) {
|
|
||||||
arr.add(x)
|
|
||||||
arr.add(y)
|
|
||||||
arr.add(z)
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun minus(other: Vector3) = Vector3(x - other.x, y - other.y, z - other.z)
|
|
||||||
operator fun plus(other: Vector3) = Vector3(x + other.x, y + other.y, z + other.z)
|
|
||||||
}
|
|
||||||
|
|
||||||
private const val Zero = 0.0f
|
|
||||||
private const val DodeA = 0.93417235896f // (Sqrt(5) + 1) / (2 * Sqrt(3))
|
|
||||||
private const val DodeB = 0.35682208977f // (Sqrt(5) - 1) / (2 * Sqrt(3))
|
|
||||||
private const val DodeC = 0.57735026919f // 1 / Sqrt(3)
|
|
||||||
private const val IcosA = 0.52573111212f // Sqrt(5 - Sqrt(5)) / Sqrt(10)
|
|
||||||
private const val IcosB = 0.85065080835f // Sqrt(5 + Sqrt(5)) / Sqrt(10)
|
|
||||||
|
|
||||||
private enum class RegularPolyhedra(val vertices: Array<Vector3>, val faces: Array<ByteArray>) {
|
|
||||||
Dodecahedron(
|
|
||||||
arrayOf(
|
|
||||||
Vector3(-DodeA, Zero, DodeB), Vector3(-DodeA, Zero, -DodeB), Vector3(DodeA, Zero, -DodeB),
|
|
||||||
Vector3(DodeA, Zero, DodeB), Vector3(DodeB, -DodeA, Zero), Vector3(-DodeB, -DodeA, Zero),
|
|
||||||
Vector3(-DodeB, DodeA, Zero), Vector3(DodeB, DodeA, Zero), Vector3(Zero, DodeB, -DodeA),
|
|
||||||
Vector3(Zero, -DodeB, -DodeA), Vector3(Zero, -DodeB, DodeA), Vector3(Zero, DodeB, DodeA),
|
|
||||||
Vector3(-DodeC, -DodeC, DodeC), Vector3(-DodeC, -DodeC, -DodeC), Vector3(DodeC, -DodeC, -DodeC),
|
|
||||||
Vector3(DodeC, -DodeC, DodeC), Vector3(-DodeC, DodeC, DodeC), Vector3(-DodeC, DodeC, -DodeC),
|
|
||||||
Vector3(DodeC, DodeC, -DodeC), Vector3(DodeC, DodeC, DodeC)
|
|
||||||
),
|
|
||||||
arrayOf(
|
|
||||||
byteArrayOf(0, 12, 10, 11, 16), byteArrayOf(1, 17, 8, 9, 13), byteArrayOf(2, 14, 9, 8, 18),
|
|
||||||
byteArrayOf(3, 19, 11, 10, 15), byteArrayOf(4, 14, 2, 3, 15), byteArrayOf(5, 12, 0, 1, 13),
|
|
||||||
byteArrayOf(6, 17, 1, 0, 16), byteArrayOf(7, 19, 3, 2, 18), byteArrayOf(8, 17, 6, 7, 18),
|
|
||||||
byteArrayOf(9, 14, 4, 5, 13), byteArrayOf(10, 12, 5, 4, 15), byteArrayOf(11, 19, 7, 6, 16)
|
|
||||||
)),
|
|
||||||
Icosahedron(
|
|
||||||
arrayOf(
|
|
||||||
Vector3(-IcosA, Zero, IcosB), Vector3(IcosA, Zero, IcosB), Vector3(-IcosA, Zero, -IcosB),
|
|
||||||
Vector3(IcosA, Zero, -IcosB), Vector3(Zero, IcosB, IcosA), Vector3(Zero, IcosB, -IcosA),
|
|
||||||
Vector3(Zero, -IcosB, IcosA), Vector3(Zero, -IcosB, -IcosA), Vector3(IcosB, IcosA, Zero),
|
|
||||||
Vector3(-IcosB, IcosA, Zero), Vector3(IcosB, -IcosA, Zero), Vector3(-IcosB, -IcosA, Zero)
|
|
||||||
),
|
|
||||||
arrayOf(
|
|
||||||
byteArrayOf(1, 4, 0), byteArrayOf(4, 9, 0), byteArrayOf(4, 5, 9), byteArrayOf(8, 5, 4),
|
|
||||||
byteArrayOf(1, 8, 4), byteArrayOf(1, 10, 8), byteArrayOf(10, 3, 8), byteArrayOf(8, 3, 5),
|
|
||||||
byteArrayOf(3, 2, 5), byteArrayOf(3, 7, 2), byteArrayOf(3, 10, 7), byteArrayOf(10, 6, 7),
|
|
||||||
byteArrayOf(6, 11, 7), byteArrayOf(6, 0, 11), byteArrayOf(6, 1, 0), byteArrayOf(10, 1, 6),
|
|
||||||
byteArrayOf(11, 0, 9), byteArrayOf(2, 11, 9), byteArrayOf(5, 2, 9), byteArrayOf(11, 2, 7)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
val verticesPerFace get() = faces[0].size
|
|
||||||
}
|
|
||||||
@@ -3,6 +3,9 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("PackageDirectoryMismatch")
|
||||||
|
package perfTestPackage1 // this package is mandatory
|
||||||
|
|
||||||
import kotlinx.cinterop.ExportObjCClass
|
import kotlinx.cinterop.ExportObjCClass
|
||||||
import kotlinx.cinterop.ObjCAction
|
import kotlinx.cinterop.ObjCAction
|
||||||
import kotlinx.cinterop.ObjCOutlet
|
import kotlinx.cinterop.ObjCOutlet
|
||||||
|
|||||||
@@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import kotlinx.cinterop.ExportObjCClass
|
|
||||||
import kotlinx.cinterop.ObjCAction
|
|
||||||
import kotlinx.cinterop.ObjCOutlet
|
|
||||||
import kotlinx.cinterop.autoreleasepool
|
|
||||||
import kotlinx.cinterop.cstr
|
|
||||||
import kotlinx.cinterop.memScoped
|
|
||||||
import kotlinx.cinterop.toCValues
|
|
||||||
import kotlinx.cinterop.useContents
|
|
||||||
import platform.CoreGraphics.CGPointMake
|
|
||||||
import platform.CoreGraphics.CGRectMake
|
|
||||||
import platform.Foundation.NSCoder
|
|
||||||
import platform.Foundation.NSSelectorFromString
|
|
||||||
import platform.Foundation.NSStringFromClass
|
|
||||||
import platform.UIKit.NSTextAlignmentCenter
|
|
||||||
import platform.UIKit.UIApplication
|
|
||||||
import platform.UIKit.UIApplicationDelegateProtocol
|
|
||||||
import platform.UIKit.UIApplicationDelegateProtocolMeta
|
|
||||||
import platform.UIKit.UIApplicationMain
|
|
||||||
import platform.UIKit.UIButton
|
|
||||||
import platform.UIKit.UIColor
|
|
||||||
import platform.UIKit.UIControlEventTouchUpInside
|
|
||||||
import platform.UIKit.UIControlStateNormal
|
|
||||||
import platform.UIKit.UIFont
|
|
||||||
import platform.UIKit.UILabel
|
|
||||||
import platform.UIKit.UIResponder
|
|
||||||
import platform.UIKit.UIResponderMeta
|
|
||||||
import platform.UIKit.UIScreen
|
|
||||||
import platform.UIKit.UIView
|
|
||||||
import platform.UIKit.UIViewController
|
|
||||||
import platform.UIKit.UIWindow
|
|
||||||
import platform.UIKit.addSubview
|
|
||||||
import platform.UIKit.backgroundColor
|
|
||||||
import platform.UIKit.font
|
|
||||||
import platform.UIKit.heightAnchor
|
|
||||||
import platform.UIKit.leadingAnchor
|
|
||||||
import platform.UIKit.setFrame
|
|
||||||
import platform.UIKit.topAnchor
|
|
||||||
import platform.UIKit.translatesAutoresizingMaskIntoConstraints
|
|
||||||
import platform.UIKit.widthAnchor
|
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
memScoped {
|
|
||||||
val argc = args.size + 1
|
|
||||||
val argv = (arrayOf("konan") + args).map { it.cstr.ptr }.toCValues()
|
|
||||||
|
|
||||||
autoreleasepool {
|
|
||||||
UIApplicationMain(argc, argv, null, NSStringFromClass(AppDelegate))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AppDelegate : UIResponder, UIApplicationDelegateProtocol {
|
|
||||||
companion object : UIResponderMeta(), UIApplicationDelegateProtocolMeta {}
|
|
||||||
|
|
||||||
@OverrideInit
|
|
||||||
constructor() : super()
|
|
||||||
|
|
||||||
private var _window: UIWindow? = null
|
|
||||||
override fun window() = _window
|
|
||||||
override fun setWindow(window: UIWindow?) {
|
|
||||||
_window = window
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun application(application: UIApplication, didFinishLaunchingWithOptions: Map<Any?, *>?): Boolean {
|
|
||||||
window = UIWindow(frame = UIScreen.mainScreen.bounds)
|
|
||||||
window!!.rootViewController = ViewController()
|
|
||||||
window!!.makeKeyAndVisible()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExportObjCClass
|
|
||||||
private class ViewController : UIViewController {
|
|
||||||
|
|
||||||
@OverrideInit
|
|
||||||
constructor() : super(nibName = null, bundle = null)
|
|
||||||
|
|
||||||
@OverrideInit
|
|
||||||
constructor(coder: NSCoder) : super(coder)
|
|
||||||
|
|
||||||
@ObjCOutlet
|
|
||||||
lateinit var label: UILabel
|
|
||||||
|
|
||||||
@ObjCOutlet
|
|
||||||
lateinit var button: UIButton
|
|
||||||
|
|
||||||
var pressed = 0
|
|
||||||
|
|
||||||
@ObjCAction
|
|
||||||
fun buttonPressed() {
|
|
||||||
label.text = "Hello #${pressed++} from Konan!"
|
|
||||||
println("Button pressed")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun viewDidLoad() {
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
val (width, height) = UIScreen.mainScreen.bounds.useContents {
|
|
||||||
this.size.width to this.size.height
|
|
||||||
}
|
|
||||||
|
|
||||||
val header = UIView().apply {
|
|
||||||
backgroundColor = UIColor.lightGrayColor
|
|
||||||
view.addSubview(this)
|
|
||||||
translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true
|
|
||||||
topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
|
|
||||||
widthAnchor.constraintEqualToAnchor(view.widthAnchor).active = true
|
|
||||||
heightAnchor.constraintEqualToAnchor(view.heightAnchor).active = true
|
|
||||||
}
|
|
||||||
|
|
||||||
label = UILabel().apply {
|
|
||||||
setFrame(CGRectMake(x = 10.0, y = 10.0, width = width - 100.0, height = 40.0))
|
|
||||||
center = CGPointMake(x = width / 2, y = 40.0 )
|
|
||||||
textAlignment = NSTextAlignmentCenter
|
|
||||||
text = "Press OK"
|
|
||||||
header.addSubview(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
button = UIButton().apply {
|
|
||||||
setFrame(CGRectMake(x = 10.0, y = height - 100.0, width = width - 100.0, height = 40.0))
|
|
||||||
center = CGPointMake(x = width / 2, y = height / 2)
|
|
||||||
backgroundColor = UIColor.blueColor
|
|
||||||
setTitle("OK", forState = UIControlStateNormal)
|
|
||||||
font = UIFont.fontWithName(fontName = font.fontName, size = 28.0)!!
|
|
||||||
layer.borderWidth = 1.0
|
|
||||||
layer.borderColor = UIColor.colorWithRed(0x47 / 255.0, 0x43 / 255.0, 0x70 / 255.0, 1.0).CGColor
|
|
||||||
layer.masksToBounds = true
|
|
||||||
addTarget(target = this@ViewController, action = NSSelectorFromString("buttonPressed"),
|
|
||||||
forControlEvents = UIControlEventTouchUpInside)
|
|
||||||
header.addSubview(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import kotlinx.cinterop.ExportObjCClass
|
|
||||||
import kotlinx.cinterop.ObjCAction
|
|
||||||
import kotlinx.cinterop.ObjCOutlet
|
|
||||||
import kotlinx.cinterop.autoreleasepool
|
|
||||||
import kotlinx.cinterop.cstr
|
|
||||||
import kotlinx.cinterop.memScoped
|
|
||||||
import kotlinx.cinterop.toCValues
|
|
||||||
import kotlinx.cinterop.useContents
|
|
||||||
import platform.CoreGraphics.CGPointMake
|
|
||||||
import platform.CoreGraphics.CGRectMake
|
|
||||||
import platform.Foundation.NSCoder
|
|
||||||
import platform.Foundation.NSSelectorFromString
|
|
||||||
import platform.Foundation.NSStringFromClass
|
|
||||||
import platform.UIKit.NSTextAlignmentCenter
|
|
||||||
import platform.UIKit.UIApplication
|
|
||||||
import platform.UIKit.UIApplicationDelegateProtocol
|
|
||||||
import platform.UIKit.UIApplicationDelegateProtocolMeta
|
|
||||||
import platform.UIKit.UIApplicationMain
|
|
||||||
import platform.UIKit.UIButton
|
|
||||||
import platform.UIKit.UIColor
|
|
||||||
import platform.UIKit.UIControlEventTouchUpInside
|
|
||||||
import platform.UIKit.UIControlStateNormal
|
|
||||||
import platform.UIKit.UIFont
|
|
||||||
import platform.UIKit.UILabel
|
|
||||||
import platform.UIKit.UIResponder
|
|
||||||
import platform.UIKit.UIResponderMeta
|
|
||||||
import platform.UIKit.UIScreen
|
|
||||||
import platform.UIKit.UIView
|
|
||||||
import platform.UIKit.UIViewController
|
|
||||||
import platform.UIKit.UIWindow
|
|
||||||
import platform.UIKit.addSubview
|
|
||||||
import platform.UIKit.backgroundColor
|
|
||||||
import platform.UIKit.font
|
|
||||||
import platform.UIKit.heightAnchor
|
|
||||||
import platform.UIKit.leadingAnchor
|
|
||||||
import platform.UIKit.setFrame
|
|
||||||
import platform.UIKit.topAnchor
|
|
||||||
import platform.UIKit.translatesAutoresizingMaskIntoConstraints
|
|
||||||
import platform.UIKit.widthAnchor
|
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
memScoped {
|
|
||||||
val argc = args.size + 1
|
|
||||||
val argv = (arrayOf("konan") + args).map { it.cstr.ptr }.toCValues()
|
|
||||||
|
|
||||||
autoreleasepool {
|
|
||||||
UIApplicationMain(argc, argv, null, NSStringFromClass(AppDelegate))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AppDelegate : UIResponder, UIApplicationDelegateProtocol {
|
|
||||||
companion object : UIResponderMeta(), UIApplicationDelegateProtocolMeta {}
|
|
||||||
|
|
||||||
@OverrideInit
|
|
||||||
constructor() : super()
|
|
||||||
|
|
||||||
private var _window: UIWindow? = null
|
|
||||||
override fun window() = _window
|
|
||||||
override fun setWindow(window: UIWindow?) {
|
|
||||||
_window = window
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun application(application: UIApplication, didFinishLaunchingWithOptions: Map<Any?, *>?): Boolean {
|
|
||||||
window = UIWindow(frame = UIScreen.mainScreen.bounds)
|
|
||||||
window!!.rootViewController = ViewController()
|
|
||||||
window!!.makeKeyAndVisible()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExportObjCClass
|
|
||||||
private class ViewController : UIViewController {
|
|
||||||
|
|
||||||
@OverrideInit
|
|
||||||
constructor() : super(nibName = null, bundle = null)
|
|
||||||
|
|
||||||
@OverrideInit
|
|
||||||
constructor(coder: NSCoder) : super(coder)
|
|
||||||
|
|
||||||
@ObjCOutlet
|
|
||||||
lateinit var label: UILabel
|
|
||||||
|
|
||||||
@ObjCOutlet
|
|
||||||
lateinit var button: UIButton
|
|
||||||
|
|
||||||
var pressed = 0
|
|
||||||
|
|
||||||
@ObjCAction
|
|
||||||
fun buttonPressed() {
|
|
||||||
label.text = "Hello #${pressed++} from Konan!"
|
|
||||||
println("Button pressed")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun viewDidLoad() {
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
val (width, height) = UIScreen.mainScreen.bounds.useContents {
|
|
||||||
this.size.width to this.size.height
|
|
||||||
}
|
|
||||||
|
|
||||||
val header = UIView().apply {
|
|
||||||
backgroundColor = UIColor.lightGrayColor
|
|
||||||
view.addSubview(this)
|
|
||||||
translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true
|
|
||||||
topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
|
|
||||||
widthAnchor.constraintEqualToAnchor(view.widthAnchor).active = true
|
|
||||||
heightAnchor.constraintEqualToAnchor(view.heightAnchor).active = true
|
|
||||||
}
|
|
||||||
|
|
||||||
label = UILabel().apply {
|
|
||||||
setFrame(CGRectMake(x = 10.0, y = 10.0, width = width - 100.0, height = 40.0))
|
|
||||||
center = CGPointMake(x = width / 2, y = 40.0 )
|
|
||||||
textAlignment = NSTextAlignmentCenter
|
|
||||||
text = "Press OK"
|
|
||||||
header.addSubview(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
button = UIButton().apply {
|
|
||||||
setFrame(CGRectMake(x = 10.0, y = height - 100.0, width = width - 100.0, height = 40.0))
|
|
||||||
center = CGPointMake(x = width / 2, y = height / 2)
|
|
||||||
backgroundColor = UIColor.blueColor
|
|
||||||
setTitle("OK", forState = UIControlStateNormal)
|
|
||||||
font = UIFont.fontWithName(fontName = font.fontName, size = 28.0)!!
|
|
||||||
layer.borderWidth = 1.0
|
|
||||||
layer.borderColor = UIColor.colorWithRed(0x47 / 255.0, 0x43 / 255.0, 0x70 / 255.0, 1.0).CGColor
|
|
||||||
layer.masksToBounds = true
|
|
||||||
addTarget(target = this@ViewController, action = NSSelectorFromString("buttonPressed"),
|
|
||||||
forControlEvents = UIControlEventTouchUpInside)
|
|
||||||
header.addSubview(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user