6

Every function and variable that I create in KotlinJs project gets into a module. But I need to define some functions in global scope.

I use p5js library (pure js). It allows user to define event handling functions in global scope. I'm trying to use KotlinJS in this project. But I don't know how to create global functions to handle p5js's events. All my Kotlin functions are inside of the module. And to call my Kotlin code I need to specif the full name mymodule.draw()

Currently I have to make an additional layer of pure JS code with global funcs that translate execution to kotlin functions which looks like this:

function setup() {
    mymodule.setup();
}

function draw() {
    mymodule.draw();
}

The problem with this approach is a lot of boilerplate and repetitive code.

  • 1
    Looks like this is unconventional use case when library calls your code that has to be shaped as functions in global scope. IMO, Kotlin should stick with generating idiomatic JS modules and simple layer of JS glue is the best way to go. Making JS fit your Kotlin is easier than making Kotlin fit your JS. – kzm Feb 19 '19 at 11:44
  • 1
    Looks like there is a [instance mode](https://github.com/processing/p5.js/wiki/Global-and-instance-mode) where you don't need to have global functions – kzm Feb 19 '19 at 11:46

3 Answers3

5

In case this will be useful for somebody I will leave another workaround here:

import kotlin.browser.window

fun main() {
    window.asDynamic()["setup"] = ::setup
    window.asDynamic()["draw"] = ::draw
}

fun setup() {}
fun draw() {}

What it actually does, it creates functions in kotlin module as usual and then assigns them to window object, which makes it global.

This solution is still not ideal, cause it needs a manual assignment for every function. At least it does it right in Kotlin project, no need to maintain a separate pure js file. Maybe it is possible to create an annotation and leverage kotlin reflection(no idea how it's supported in KotlinJS).

Although this solution works for me, I would like to have some out of the box solution like they do for @JsNonModule external functions.

2

Unfortunately there is no way to define global function in Kotlin/JS. It is possible to use Plain module type where you have global symbols in module object which is defined in global scope.

// module M
fun foo() {}

which is accessible via M.foo

Roman Art
  • 126
  • 2
1

Adding on top of @Sergey's Answer, one can also use this work around when dealing with libs like p5.js

fun main() {
    window.asDynamic().setup = {
        // your setup code here
    }

    window.asDynamic().draw = {
        // your draw code here
    }
}

This approach minimizes the definition and the declaration of the two functions (looking at you C Language). Thanks

andylamax
  • 1,305
  • 9
  • 28