LiquidPlayer / LiquidCore

Node.js virtual machine for Android and iOS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Need a JSObject property to be bound to jsexported methods

sammy44nts opened this issue · comments

commented

Hello!

Using Kotlin, I'm having trouble with the 'proper' way to define the JSObject property because Property constructor is private so I can't declare them that way.

I used

        JSObjectPropertiesMap(instance, Any::class.java).apply {
            put("id", instance.getId())
        }

to define a property in the JSObject.

I need the property to use getId() as getter and setId(value) as setter. Do you see a way to redefine JS object property id to bind it to the jsexported getter & setter at the instance creation time in the constructor?

commented

Found a solution for two way communication:

  • getId() & setId(value) are not exported using jsexport anymore;
  • At instance creation time, I retrieve the Kotlin member id:
    var id: String
        get() = getId()
        set(value) = setId(value)
  • Set the constructor's properties:
    this::class.memberProperties.forEach {
      if (it.name == "id") {
        `this`.property(
          "\$\$_getid",
          object : JSFunction(context, "__NativeGetter__") {
            fun __NativeGetter__() = it.getter.call(this)
          })
        `this`.property(
          "\$\$_setid",
          object : JSFunction(context, "__NativeSetter__") {
            fun __NativeSetter__(v: JSValue) {
              if (it is KMutableProperty<*>) it.setter.call(this, "$v")
            }
          })
      }
    }
  • Use of the following to redefine JSObject prototype:
    context.evaluateScript(
      "function InitClass(Class, props) {\n" +
      "    props.forEach(prop => {\n" +
      "        Object.defineProperty(Class.prototype, prop, {\n" +
      "                    get: function () {return this[\"\$\$_get\"+prop]()},\n" +
      "                    set: function (v) {this[\"\$\$_set\"+prop](v)}\n" +
      "                });\n" +
      "    });\n" +
      "}"
    )
  • Call of context.evaluateScript("InitClass($className, ['id'])")