Wire up event handler bindings

Reviewed By: mdvacca

Differential Revision: D8048409

fbshipit-source-id: 5706130607302b4be2287cc303def7c2fb398bc8
This commit is contained in:
Sebastian Markbage 2018-05-22 00:05:17 -07:00 committed by Facebook Github Bot
parent f180300606
commit 5028d48382
4 changed files with 98 additions and 1 deletions

View File

@ -71,6 +71,10 @@ public class FabricUIManager implements UIManager {
mFabricReconciler = new FabricReconciler(mUIViewOperationQueue); mFabricReconciler = new FabricReconciler(mUIViewOperationQueue);
} }
public void registerEventHandler(long eventHandlerPointer) {
// TODO: Release this event handler at some point.
}
/** Creates a new {@link ReactShadowNode} */ /** Creates a new {@link ReactShadowNode} */
@Nullable @Nullable
public ReactShadowNode createNode( public ReactShadowNode createNode(

View File

@ -12,6 +12,7 @@ import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.JavaScriptContextHolder; import com.facebook.react.bridge.JavaScriptContextHolder;
import com.facebook.react.fabric.FabricBinding; import com.facebook.react.fabric.FabricBinding;
import com.facebook.react.fabric.FabricUIManager; import com.facebook.react.fabric.FabricUIManager;
import com.facebook.react.bridge.NativeMap;
import com.facebook.soloader.SoLoader; import com.facebook.soloader.SoLoader;
@DoNotStrip @DoNotStrip
@ -31,6 +32,16 @@ public class FabricJSCBinding implements FabricBinding {
private native void releaseEventTarget(long jsContextNativePointer, long eventTargetPointer); private native void releaseEventTarget(long jsContextNativePointer, long eventTargetPointer);
private native void releaseEventHandler(long jsContextNativePointer, long eventHandlerPointer);
private native void dispatchEventToTarget(
long jsContextNativePointer,
long eventHandlerPointer,
long eventTargetPointer,
String type,
NativeMap payload
);
private native void installFabric(long jsContextNativePointer, Object fabricModule); private native void installFabric(long jsContextNativePointer, Object fabricModule);
public FabricJSCBinding() { public FabricJSCBinding() {

View File

@ -7,7 +7,6 @@
#include "FabricJSCBinding.h" #include "FabricJSCBinding.h"
#include <fb/fbjni.h> #include <fb/fbjni.h>
#include <react/jni/ReadableNativeMap.h>
#include <jschelpers/JavaScriptCore.h> #include <jschelpers/JavaScriptCore.h>
#include <jschelpers/Unicode.h> #include <jschelpers/Unicode.h>
@ -81,6 +80,15 @@ local_ref<ReadableNativeMap::jhybridobject> JSValueToReadableMapViaJSON(JSContex
return ReadableNativeMap::newObjectCxxArgs(std::move(dynamicValue)); return ReadableNativeMap::newObjectCxxArgs(std::move(dynamicValue));
} }
JSValueRef ReadableMapToJSValueViaJSON(JSContextRef ctx, NativeMap *map) {
folly::dynamic dynamicValue = map->consume();
auto json = folly::toJson(dynamicValue);
JSStringRef jsonRef = JSC_JSStringCreateWithUTF8CString(ctx, json.c_str());
auto value = JSC_JSValueMakeFromJSONString(ctx, jsonRef);
JSC_JSStringRelease(ctx, jsonRef);
return value;
}
JSValueRef createNode(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { JSValueRef createNode(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) {
FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function); FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function);
alias_ref<jobject> manager = managerWrapper->fabricUiManager; alias_ref<jobject> manager = managerWrapper->fabricUiManager;
@ -231,6 +239,21 @@ JSValueRef completeRoot(JSContextRef ctx, JSObjectRef function, JSObjectRef this
return JSC_JSValueMakeUndefined(ctx); return JSC_JSValueMakeUndefined(ctx);
} }
JSValueRef registerEventHandler(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) {
FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function);
alias_ref<jobject> manager = managerWrapper->fabricUiManager;
static auto registerEventHandler =
jni::findClassStatic("com/facebook/react/fabric/FabricUIManager")
->getMethod<void(jlong)>("registerEventHandler");
auto eventHandler = arguments[0];
JSC_JSValueProtect(ctx, eventHandler);
registerEventHandler(manager, (jlong)eventHandler);
return JSC_JSValueMakeUndefined(ctx);
}
void finalizeJNIObject(JSObjectRef object) { void finalizeJNIObject(JSObjectRef object) {
// Release whatever global ref object we're storing here. // Release whatever global ref object we're storing here.
jobject globalRef = (jobject)JSC_JSObjectGetPrivate(useCustomJSC, object); jobject globalRef = (jobject)JSC_JSObjectGetPrivate(useCustomJSC, object);
@ -291,6 +314,47 @@ void FabricJSCBinding::releaseEventTarget(
JSC_JSValueUnprotect(context, value); JSC_JSValueUnprotect(context, value);
} }
void FabricJSCBinding::releaseEventHandler(
jlong jsContextNativePointer,
jlong eventHandlerPointer
) {
JSContextRef context = (JSContextRef)jsContextNativePointer;
JSValueRef value = (JSValueRef)((void *)eventHandlerPointer);
// Release this function.
JSC_JSValueUnprotect(context, value);
}
void FabricJSCBinding::dispatchEventToTarget(
jlong jsContextNativePointer,
jlong eventHandlerPointer,
jlong eventTargetPointer,
std::string type,
NativeMap *payloadMap
) {
JSContextRef context = (JSContextRef)jsContextNativePointer;
JSObjectRef eventHandler = (JSObjectRef)((void *)eventHandlerPointer);
JSObjectRef eventTarget = (JSObjectRef)((void *)eventTargetPointer);
JSObjectRef thisArg = (JSObjectRef)JSC_JSValueMakeUndefined(context);
JSStringRef typeStr = JSC_JSStringCreateWithUTF8CString(context, type.c_str());
JSValueRef typeRef = JSC_JSValueMakeString(context, typeStr);
JSC_JSStringRelease(context, typeStr);
JSValueRef payloadRef = ReadableMapToJSValueViaJSON(context, payloadMap);
JSValueRef args[] = {eventTarget, typeRef, payloadRef};
JSValueRef exn;
JSValueRef result = JSC_JSObjectCallAsFunction(
context,
eventHandler,
thisArg,
3,
args,
&exn
);
if (!result) {
// TODO: Handle error in exn
}
}
void FabricJSCBinding::installFabric(jlong jsContextNativePointer, void FabricJSCBinding::installFabric(jlong jsContextNativePointer,
jni::alias_ref<jobject> fabricModule) { jni::alias_ref<jobject> fabricModule) {
JSContextRef context = (JSContextRef)jsContextNativePointer; JSContextRef context = (JSContextRef)jsContextNativePointer;
@ -308,11 +372,14 @@ void FabricJSCBinding::installFabric(jlong jsContextNativePointer,
addFabricMethod(context, fabricModule, classRef, module, "cloneNodeWithNewChildren", cloneNodeWithNewChildren); addFabricMethod(context, fabricModule, classRef, module, "cloneNodeWithNewChildren", cloneNodeWithNewChildren);
addFabricMethod(context, fabricModule, classRef, module, "cloneNodeWithNewProps", cloneNodeWithNewProps); addFabricMethod(context, fabricModule, classRef, module, "cloneNodeWithNewProps", cloneNodeWithNewProps);
addFabricMethod(context, fabricModule, classRef, module, "cloneNodeWithNewChildrenAndProps", cloneNodeWithNewChildrenAndProps); addFabricMethod(context, fabricModule, classRef, module, "cloneNodeWithNewChildrenAndProps", cloneNodeWithNewChildrenAndProps);
addFabricMethod(context, fabricModule, classRef, module, "appendChild", appendChild); addFabricMethod(context, fabricModule, classRef, module, "appendChild", appendChild);
addFabricMethod(context, fabricModule, classRef, module, "createChildSet", createChildSet); addFabricMethod(context, fabricModule, classRef, module, "createChildSet", createChildSet);
addFabricMethod(context, fabricModule, classRef, module, "appendChildToSet", appendChildToSet); addFabricMethod(context, fabricModule, classRef, module, "appendChildToSet", appendChildToSet);
addFabricMethod(context, fabricModule, classRef, module, "completeRoot", completeRoot); addFabricMethod(context, fabricModule, classRef, module, "completeRoot", completeRoot);
addFabricMethod(context, fabricModule, classRef, module, "registerEventHandler", registerEventHandler);
JSC_JSClassRelease(useCustomJSC, classRef); JSC_JSClassRelease(useCustomJSC, classRef);
JSObjectRef globalObject = JSC_JSContextGetGlobalObject(context); JSObjectRef globalObject = JSC_JSContextGetGlobalObject(context);
@ -325,6 +392,10 @@ void FabricJSCBinding::registerNatives() {
registerHybrid({ registerHybrid({
makeNativeMethod("initHybrid", FabricJSCBinding::initHybrid), makeNativeMethod("initHybrid", FabricJSCBinding::initHybrid),
makeNativeMethod("installFabric", FabricJSCBinding::installFabric), makeNativeMethod("installFabric", FabricJSCBinding::installFabric),
makeNativeMethod("createEventTarget", FabricJSCBinding::createEventTarget),
makeNativeMethod("releaseEventTarget", FabricJSCBinding::releaseEventTarget),
makeNativeMethod("releaseEventHandler", FabricJSCBinding::releaseEventHandler),
makeNativeMethod("dispatchEventToTarget", FabricJSCBinding::dispatchEventToTarget),
}); });
} }

View File

@ -9,6 +9,7 @@
#include <memory> #include <memory>
#include <fb/fbjni.h> #include <fb/fbjni.h>
#include <react/jni/ReadableNativeMap.h>
namespace facebook { namespace facebook {
namespace react { namespace react {
@ -30,6 +31,16 @@ private:
void releaseEventTarget(jlong jsContextNativePointer, jlong eventTargetPointer); void releaseEventTarget(jlong jsContextNativePointer, jlong eventTargetPointer);
void releaseEventHandler(jlong jsContextNativePointer, jlong eventHandlerPointer);
void dispatchEventToTarget(
jlong jsContextNativePointer,
jlong eventHandlerPointer,
jlong eventTargetPointer,
std::string type,
NativeMap *payload
);
void installFabric(jlong jsContextNativePointer, jni::alias_ref<jobject> fabricModule); void installFabric(jlong jsContextNativePointer, jni::alias_ref<jobject> fabricModule);
}; };