3

Jetbrain/Exposedを ORM ライブラリとして、TornadoFXを JavaFX の kotlin バージョン ラッパーとして UI フレームワークとしてプログラム ビルドを試みています。エンティティのクラス プロパティが Exposed によって委任されるという問題があります。

object Paintings: UUIDTable() {
    ...
    val description = text("description").default("")
    ...
}

class Painting(id: EntityID<UUID>) : UUIDEntity(id) {
    ...

    var description by Paintings.description

    ...
}

また、このようなJavaFXのプロパティに委任されたプロパティを作成したいです

class Painting(id: EntityID<UUID>) : UUIDEntity(id) {
    ...

    var description by property<String>()
    fun descriptionProperty() = getProperty(Painting::description)

    ...
}

ここで競合が発生するため、2 つのフレームワークのデリゲートをラッパーする独自のデリゲート クラスを作成しようとしています。

class Painting(id: EntityID<UUID>) : UUIDEntity(id) {
    ...

    var description by Paintings.description notify property<String>()
    fun descriptionProperty() = getProperty(Painting::description)

    ...
}

そして、ここにExposed からのデリゲートの演算子setValueとfor がクラスで宣言されているという問題がありますgetValueEntity

open class Entity<ID:Comparable<ID>>(val id: EntityID<ID>) {
    ...

    operator fun <T> Column<T>.getValue(o: Entity<ID>, desc: KProperty<*>): T = 
        lookup()

    operator fun <T> Column<T>.setValue(o: Entity<ID>, desc: KProperty<*>, value: T) {...}

ラッパー クラスを宣言すると、クラスColumnでスコープされているデリゲート オペレーターにアクセスできません。Entity

//Global Extension instead of scoped to `Entity`
infix fun <T> Column<T>.notify(fxProperty: PropertyDelegate<T>) {
    return DelegateWrapper(this,fxProperty)
}

class DelegateWrapper<T>(val column: Column<T>, val fxProperty: PropertyDelegate<T>) {

    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return column.getValue(...)  <-cannot resolve getValue
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) 
    {
        ...
    }
}

回避策として、UUIDEntityのサブクラスを構築し、それらの拡張機能をメンバー拡張機能として追加し、それを機能させるためにネストクラスを追加する必要があったと思います。

4

1 に答える 1

2

デリゲートを使用できる型を に制限することで、これを行うことができますEntity

これは、次のようにレシーバーを提供するブロック内の拡張機能を置き換えthisRef: Any?thisRef: Entity<ID>呼び出すことで実行できます。getValuethisRef.run { ... }Entitiy<ID>

class DelegateWrapper<T>(val column: Column<T>, val fxProperty: PropertyDelegate<T>) {

    operator fun <ID : Comparable<ID>> getValue(
        thisRef: Entity<ID>,  // <-- here
        property: KProperty<*>
    ): String =
        thisRef.run { column.getValue(thisRef, property) }  

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) = TODO()
}
于 2018-04-27T12:38:48.237 に答える