Garbage collection capable wrappers for skia interop
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
|
||||
Skia interop support
|
||||
====================
|
||||
|
||||
@@ -15,6 +16,33 @@ plugin = org.jetbrains.kotlin.native.cinterop.plugin.skia
|
||||
language = C++
|
||||
```
|
||||
|
||||
Interop
|
||||
-------
|
||||
|
||||
There are two kinds of C++ classes used in Skia.
|
||||
The ones with ref()/unref() reference counting are abstracted with SkiaRefCnt interface.
|
||||
The ones without are abstracted with CPlusPlusClass interface.
|
||||
|
||||
So, for example, for SkPaint one has
|
||||
|
||||
class SkPaint(rawPtr) : CStructVar(rawPtr), CPlusPlusClass {
|
||||
// A C interop-like function having methods,
|
||||
// as well as low level __init__ and __destroy__
|
||||
}
|
||||
|
||||
class Paint(cpp: SkPaint, managed: Boolean) : ManagedType(cpp) {
|
||||
// A wrapper capable of garbage collection delegating all calls and fields to SkPaint
|
||||
}
|
||||
|
||||
|
||||
* pointer returned from C++ -> Wrapper(cpp, managed = false)
|
||||
* sk_sp returned from C++ -> calls .release() ; Wrapper(cpp, managed = true)
|
||||
* pointer passed to C++ -> kotlin.cpp.ptr
|
||||
* sk_sp passed to C++ -> sk_ref_sp(kotlin.cpp.ptr)
|
||||
* constructor call -> allocate Cpp; Wrapper(cpp, managed = true)
|
||||
* garbage collection -> if (managed==true): calls __destroy__() for CPluaPlusClass or unref() for SkiaRefCnt
|
||||
|
||||
|
||||
Implementation details
|
||||
======================
|
||||
|
||||
|
||||
+18
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.native.interop.gen.Classifier
|
||||
import org.jetbrains.kotlin.native.interop.gen.StubIrContext
|
||||
import org.jetbrains.kotlin.native.interop.gen.StubsBuildingContextImpl
|
||||
import org.jetbrains.kotlin.native.interop.indexer.StructDecl
|
||||
import org.jetbrains.kotlin.native.interop.indexer.StructDef
|
||||
|
||||
class SkiaStubsBuildingContextImpl(stubIrContext: StubIrContext) : StubsBuildingContextImpl(stubIrContext) {
|
||||
override val declarationMapper = SkiaDeclarationMapperImpl()
|
||||
@@ -23,4 +24,21 @@ class SkiaStubsBuildingContextImpl(stubIrContext: StubIrContext) : StubsBuilding
|
||||
return getKotlinClassForPointed(structArgument)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isCppClass(spelling: String): Boolean {
|
||||
val decl = nativeIndex.structs.firstOrNull { it.spelling == spelling } ?: return false
|
||||
return decl.def?.kind == StructDef.Kind.CLASS
|
||||
}
|
||||
|
||||
override fun managedWrapperClassifier(cppClassifier: Classifier): Classifier? {
|
||||
if (cppClassifier.pkg != "org.jetbrains.skiko.skia.native") return null
|
||||
// TODO: it'd be nice to check inheritance from SkiaRefCnt or CPlusPlusClass,
|
||||
// but unable to do that at StubType level.
|
||||
if (!(cppClassifier.topLevelName.startsWith("Sk") || cppClassifier.topLevelName.startsWith("Gr"))) return null
|
||||
if (cppClassifier.topLevelName == "SkString") return null
|
||||
// TODO: We only managed C++ classes, not structs for now.
|
||||
if (!isCppClass(cppClassifier.topLevelName)) return null
|
||||
|
||||
return Classifier.topLevel(cppClassifier.pkg, cppClassifier.topLevelName.drop(2))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user