Unverified Commit c20bf0c5 authored by Aleksandr Veselov's avatar Aleksandr Veselov Committed by GitHub

Implement `skottie::Logger` for native (#376)

parent 23a7d626
......@@ -150,6 +150,16 @@ inline fun withStringReferenceResult(block: () -> NativePointer): String {
return string.toString()
}
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
inline fun withStringReferenceNullableResult(block: () -> NativePointer): String? {
val ptr = block()
if (ptr == Native.NullPointer) return null
val string = ManagedString(ptr, false)
return string.toString()
}
interface ArrayInteropDecoder<T> {
fun getArrayElement(array: InteropPointer, index: Int): T
fun getArraySize(array: InteropPointer): Int
......
@file:Suppress("NESTED_EXTERNAL_DECLARATION")
package org.jetbrains.skia.skottie
import org.jetbrains.skia.ExternalSymbolName
import org.jetbrains.skia.impl.InteropPointer
import org.jetbrains.skia.impl.Library.Companion.staticLoad
import org.jetbrains.skia.impl.NativePointer
import org.jetbrains.skia.impl.RefCnt
import org.jetbrains.skia.impl.Stats
import org.jetbrains.skia.ExternalSymbolName
import org.jetbrains.skia.impl.NativePointer
/**
*
......@@ -19,17 +20,30 @@ abstract class Logger : RefCnt(_nMake()) {
}
}
abstract fun log(level: LogLevel?, message: String?, json: String?)
abstract fun log(level: LogLevel, message: String, json: String?)
init {
Stats.onNativeCall()
Stats.onNativeCall()
_nInit(_ptr)
doInit(_ptr)
}
}
internal expect fun Logger.doInit(ptr: NativePointer)
@ExternalSymbolName("org_jetbrains_skia_skottie_Logger__1nMake")
private external fun _nMake(): NativePointer
// Native/JS only
@ExternalSymbolName("org_jetbrains_skia_skottie_Logger__1nInit")
external fun _nInit(ptr: NativePointer)
internal external fun Logger_nInit(ptr: NativePointer, onLog: InteropPointer)
@ExternalSymbolName("org_jetbrains_skia_skottie_Logger__1nGetLogMessage")
internal external fun Logger_nGetLogMessage(ptr: NativePointer): NativePointer
@ExternalSymbolName("org_jetbrains_skia_skottie_Logger__1nGetLogJson")
internal external fun Logger_nGetLogJson(ptr: NativePointer): NativePointer
@ExternalSymbolName("org_jetbrains_skia_skottie_Logger__1nGetLogLevel")
internal external fun Logger_nGetLogLevel(ptr: NativePointer): Int
package org.jetbrains.skia.skottie
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
class LoggerTest {
@Test
fun canLog() {
var actualLevel: LogLevel? = null
var actualMessage: String? = null
var actualJson: String? = null
val logger = object: Logger() {
override fun log(level: LogLevel, message: String, json: String?) {
actualLevel = level
actualMessage = message
actualJson = json
}
}
try {
AnimationBuilder().setLogger(logger).buildFromString(
"""{"nm": "Test","v": "1.42.0","ip": <ERROR HERE>,"op": 180,"fr": 60,"w": 32,"h": 32,"layers": []}"""
)
} catch (e: IllegalArgumentException) {
// Must fail
}
assertEquals("Failed to parse JSON input.\n", actualMessage)
assertEquals(LogLevel.ERROR, actualLevel)
assertNull(actualJson)
}
}
\ No newline at end of file
......@@ -4,18 +4,18 @@
using namespace skottie;
class SkijaLoggerImpl: public Logger {
class SkikoLogger: public Logger {
public:
SkijaLoggerImpl() {
SkikoLogger() {
}
~SkijaLoggerImpl() {
fEnv->DeleteWeakGlobalRef(fObject);
~SkikoLogger() {
fEnv->DeleteGlobalRef(fObject);
}
void init(JNIEnv* e, jobject o) {
fEnv = e;
fObject = fEnv->NewWeakGlobalRef(o);
fObject = fEnv->NewGlobalRef(o);
}
public:
......@@ -39,12 +39,12 @@ private:
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_skottie_LoggerKt__1nMake
(JNIEnv* env, jclass jclass) {
SkijaLoggerImpl* instance = new SkijaLoggerImpl();
SkikoLogger* instance = new SkikoLogger();
return reinterpret_cast<jlong>(instance);
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_skottie_LoggerKt__1nInit
(JNIEnv* env, jobject jthis, jlong ptr) {
SkijaLoggerImpl* instance = reinterpret_cast<SkijaLoggerImpl*>(static_cast<uintptr_t>(ptr));
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_skottie_Logger_1jvmKt__1nInit
(JNIEnv* env, jclass jclass, jobject jthis, jlong ptr) {
SkikoLogger* instance = reinterpret_cast<SkikoLogger*>(static_cast<uintptr_t>(ptr));
instance->init(env, jthis);
}
package org.jetbrains.skia.skottie
import org.jetbrains.skia.impl.NativePointer
internal actual fun Logger.doInit(ptr: NativePointer) {
_nInit(this, ptr)
}
private external fun _nInit(thisPtr: Logger, ptr: NativePointer)
\ No newline at end of file
......@@ -5,32 +5,72 @@
using namespace skottie;
#include "common.h"
class SkikoLogger: public Logger {
public:
SkikoLogger() : _log(nullptr) {}
SKIKO_EXPORT KNativePointer org_jetbrains_skia_skottie_Logger__1nMake
() {
TODO("implement org_jetbrains_skia_skottie_Logger__1nMake");
}
void init(KInteropPointer onLog) {
_log = KVoidCallback(onLog);
}
SkString* logMessage() {
return &_logMessage;
}
SkString* logJson() {
return _hasLogJson ? &_logJson : nullptr;
}
Level logLevel() const {
return _logLevel;
}
void log(Level level, const char message[], const char* json = nullptr) override {
_logLevel = level;
_logMessage = message;
_hasLogJson = json != nullptr;
_logJson = json;
_log();
_logLevel = Level::kError;
_logMessage = nullptr;
_logJson = nullptr;
_hasLogJson = false;
}
private:
SkString _logMessage;
SkString _logJson;
KVoidCallback _log;
Level _logLevel;
bool _hasLogJson;
};
#if 0
SKIKO_EXPORT KNativePointer org_jetbrains_skia_skottie_Logger__1nMake
() {
SkijaLoggerImpl* instance = new SkijaLoggerImpl();
SkikoLogger* instance = sk_sp<SkikoLogger>(new SkikoLogger()).release();
return reinterpret_cast<KNativePointer>(instance);
}
#endif
SKIKO_EXPORT void org_jetbrains_skia_skottie_Logger__1nInit
(KNativePointer ptr, KInteropPointer onLog) {
SkikoLogger* instance = reinterpret_cast<SkikoLogger*>((ptr));
instance->init(onLog);
}
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_skottie_Logger__1nGetLogMessage
(KNativePointer ptr) {
TODO("implement org_jetbrains_skia_skottie_Logger__1nInit");
SkikoLogger* instance = reinterpret_cast<SkikoLogger*>((ptr));
return reinterpret_cast<KInteropPointer>(instance->logMessage());
}
#if 0
SKIKO_EXPORT void org_jetbrains_skia_skottie_Logger__1nInit
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_skottie_Logger__1nGetLogJson
(KNativePointer ptr) {
SkijaLoggerImpl* instance = reinterpret_cast<SkijaLoggerImpl*>((ptr));
instance->init(env, jthis);
SkikoLogger* instance = reinterpret_cast<SkikoLogger*>((ptr));
return reinterpret_cast<KInteropPointer>(instance->logJson());
}
#endif
SKIKO_EXPORT KInt org_jetbrains_skia_skottie_Logger__1nGetLogLevel
(KNativePointer ptr) {
SkikoLogger* instance = reinterpret_cast<SkikoLogger*>((ptr));
return static_cast<KInt>(instance->logLevel());
}
package org.jetbrains.skia.skottie
import org.jetbrains.skia.impl.NativePointer
import org.jetbrains.skia.impl.interopScope
import org.jetbrains.skia.impl.withStringReferenceNullableResult
import org.jetbrains.skia.impl.withStringReferenceResult
internal actual fun Logger.doInit(ptr: NativePointer) {
interopScope {
val onLog = virtual {
val level = LogLevel.values()[Logger_nGetLogLevel(ptr)]
val message = withStringReferenceResult { Logger_nGetLogMessage(ptr) }
val json = withStringReferenceNullableResult { Logger_nGetLogJson(ptr) }
log(level, message, json)
}
Logger_nInit(ptr, onLog)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment