feat(core): refactor loadInstance

Co-authored-by: ozonelmy <ozonelmy@163.com>
Co-authored-by: zoomchan-cxj <zoom_chan@163.com>
Co-authored-by: maxli <maxli@tencent.com>
This commit is contained in:
churchill-zhang
2022-06-02 12:06:29 +08:00
committed by GitHub
co-authored by ozonelmy zoomchan-cxj maxli
parent e26ca23ede
commit d5058bbb10
23 changed files with 292 additions and 259 deletions
@@ -36,11 +36,11 @@ public interface HippyBridge {
void destroy(NativeCallback callback, boolean isReload);
void callFunction(String action, NativeCallback callback, ByteBuffer buffer);
void callFunction(int functionId, NativeCallback callback, ByteBuffer buffer);
void callFunction(String action, NativeCallback callback, byte[] buffer);
void callFunction(int functionId, NativeCallback callback, byte[] buffer);
void callFunction(String action, NativeCallback callback, byte[] buffer, int offset,
void callFunction(int functionId, NativeCallback callback, byte[] buffer, int offset,
int length);
long getV8RuntimeId();
@@ -58,7 +58,7 @@ import java.nio.ByteOrder;
@SuppressWarnings({"unused", "JavaJniMissingFunction"})
public class HippyBridgeImpl implements HippyBridge, DevRemoteDebugProxy.OnReceiveDataListener {
private static final String TAG = "HippyBridgeImpl";
private static final Object sBridgeSyncLock;
private static final String DEFAULT_LOCAL_HOST = "localhost:38989";
private static final String DEBUG_WEBSOCKET_URL = "ws://%s/debugger-proxy?role=android_client&clientId=%s";
@@ -200,16 +200,54 @@ public class HippyBridgeImpl implements HippyBridge, DevRemoteDebugProxy.OnRecei
}
}
private String getCallFunctionName(int functionId) {
String action = null;
switch (functionId) {
case HippyBridgeManagerImpl.FUNCTION_ACTION_LOAD_INSTANCE: {
action = "loadInstance";
break;
}
case HippyBridgeManagerImpl.FUNCTION_ACTION_RESUME_INSTANCE: {
action = "resumeInstance";
break;
}
case HippyBridgeManagerImpl.FUNCTION_ACTION_PAUSE_INSTANCE: {
action = "pauseInstance";
break;
}
case HippyBridgeManagerImpl.FUNCTION_ACTION_DESTROY_INSTANCE: {
action = "destroyInstance";
break;
}
case HippyBridgeManagerImpl.FUNCTION_ACTION_CALLBACK: {
action = "callBack";
break;
}
case HippyBridgeManagerImpl.FUNCTION_ACTION_CALL_JSMODULE: {
action = "callJsModule";
break;
}
case HippyBridgeManagerImpl.FUNCTION_ACTION_ON_WEBSOCKET_MESSAGE: {
action = "onWebsocketMsg";
break;
}
default:
LogUtils.w(TAG, "getCallFunctionName: Unknown function id=" + functionId);
}
return action;
}
@Override
public void callFunction(String action, NativeCallback callback, ByteBuffer buffer) {
if (!mInit || TextUtils.isEmpty(action) || buffer == null || buffer.limit() == 0) {
public void callFunction(int functionId, NativeCallback callback, ByteBuffer buffer) {
String functionName = getCallFunctionName(functionId);
if (!mInit || TextUtils.isEmpty(functionName) || buffer == null || buffer.limit() == 0) {
return;
}
int offset = buffer.position();
int length = buffer.limit() - buffer.position();
if (buffer.isDirect()) {
callFunction(action, mV8RuntimeId, callback, buffer, offset, length);
callFunction(functionName, mV8RuntimeId, callback, buffer, offset, length);
} else {
/*
* In Android's DirectByteBuffer implementation.
@@ -226,24 +264,28 @@ public class HippyBridgeImpl implements HippyBridge, DevRemoteDebugProxy.OnRecei
* {@link ByteBuffer#arrayOffset} will be ignored, treated as 0.
*/
offset += buffer.arrayOffset();
callFunction(action, mV8RuntimeId, callback, buffer.array(), offset, length);
callFunction(functionName, mV8RuntimeId, callback, buffer.array(), offset, length);
}
}
@Override
public void callFunction(String action, NativeCallback callback, byte[] buffer) {
callFunction(action, callback, buffer, 0, buffer.length);
public void callFunction(int functionId, NativeCallback callback, byte[] buffer) {
callFunction(functionId, callback, buffer, 0, buffer.length);
}
@Override
public void callFunction(String action, NativeCallback callback, byte[] buffer, int offset,
public void callFunction(int functionId, NativeCallback callback, byte[] buffer, int offset,
int length) {
if (!mInit || TextUtils.isEmpty(action) || buffer == null || offset < 0 || length < 0
String functionName = getCallFunctionName(functionId);
if (!mInit || TextUtils.isEmpty(functionName) || buffer == null || offset < 0 || length < 0
|| offset + length > buffer.length) {
return;
}
callFunction(action, mV8RuntimeId, callback, buffer, offset, length);
if (functionId == HippyBridgeManagerImpl.FUNCTION_ACTION_LOAD_INSTANCE) {
loadInstance(mV8RuntimeId, buffer, offset, length);
} else {
callFunction(functionName, mV8RuntimeId, callback, buffer, offset, length);
}
}
@Override
@@ -271,23 +313,27 @@ public class HippyBridgeImpl implements HippyBridge, DevRemoteDebugProxy.OnRecei
long groupId, V8InitParams v8InitParams, String dataDir, String wsUrl);
public native boolean runScriptFromUri(String uri, AssetManager assetManager,
boolean canUseCodeCache, String codeCacheDir, long V8RuntimId, NativeCallback callback);
boolean canUseCodeCache, String codeCacheDir, long V8RuntimeId,
NativeCallback callback);
public native void destroy(long runtimeId, boolean useLowMemoryMode, boolean isReload, NativeCallback callback);
public native void callFunction(String action, long V8RuntimId, NativeCallback callback,
public native void callFunction(String action, long V8RuntimeId, NativeCallback callback,
ByteBuffer buffer, int offset, int length);
public native void callFunction(String action, long V8RuntimId, NativeCallback callback,
public native void callFunction(String action, long V8RuntimeId, NativeCallback callback,
byte[] buffer, int offset, int length);
public native void loadInstance(long V8RuntimeId, byte[] buffer, int offset, int length);
public native void onResourceReady(ByteBuffer output, long runtimeId, long resId);
public void callNatives(String moduleName, String moduleFunc, String callId, byte[] buffer) {
callNatives(moduleName, moduleFunc, callId, ByteBuffer.wrap(buffer));
}
public void callNatives(String moduleName, String moduleFunc, String callId, ByteBuffer buffer) {
public void callNatives(String moduleName, String moduleFunc, String callId,
ByteBuffer buffer) {
if (mBridgeCallback != null) {
mBridgeCallback.callNatives(moduleName, moduleFunc, callId, buffer);
}
@@ -365,7 +411,8 @@ public class HippyBridgeImpl implements HippyBridge, DevRemoteDebugProxy.OnRecei
@Override
public void onReceiveData(String msg) {
if (this.mIsDevModule) {
callFunction("onWebsocketMsg", null, msg.getBytes(StandardCharsets.UTF_16LE));
callFunction(HippyBridgeManagerImpl.FUNCTION_ACTION_ON_WEBSOCKET_MESSAGE, null,
msg.getBytes(StandardCharsets.UTF_16LE));
}
}
}
@@ -68,6 +68,7 @@ public class HippyBridgeManagerImpl implements HippyBridgeManager, HippyBridge.B
static final int FUNCTION_ACTION_DESTROY_INSTANCE = 4;
static final int FUNCTION_ACTION_CALLBACK = 5;
static final int FUNCTION_ACTION_CALL_JSMODULE = 6;
static final int FUNCTION_ACTION_ON_WEBSOCKET_MESSAGE = 7;
public static final int BRIDGE_TYPE_SINGLE_THREAD = 2;
public static final int BRIDGE_TYPE_NORMAL = 1;
@@ -95,6 +96,7 @@ public class HippyBridgeManagerImpl implements HippyBridgeManager, HippyBridge.B
HippyEngine.ModuleListener mLoadModuleListener;
private TurboModuleManager mTurboModuleManager;
private HippyEngine.V8InitParams v8InitParams;
private NativeCallback mCallback;
public HippyBridgeManagerImpl(HippyEngineContext context, HippyBundleLoader coreBundleLoader,
int bridgeType, boolean enableV8Serialization, boolean isDevModule,
@@ -119,48 +121,20 @@ public class HippyBridgeManagerImpl implements HippyBridgeManager, HippyBridge.B
}
private void handleCallFunction(Message msg) {
String action = null;
int instanceId = 0;
switch (msg.arg2) {
case FUNCTION_ACTION_LOAD_INSTANCE: {
action = "loadInstance";
break;
}
case FUNCTION_ACTION_RESUME_INSTANCE: {
action = "resumeInstance";
break;
}
case FUNCTION_ACTION_PAUSE_INSTANCE: {
action = "pauseInstance";
break;
}
case FUNCTION_ACTION_DESTROY_INSTANCE: {
action = "destroyInstance";
break;
}
case FUNCTION_ACTION_CALLBACK: {
action = "callBack";
break;
}
case FUNCTION_ACTION_CALL_JSMODULE: {
action = "callJsModule";
break;
}
if (mCallback == null) {
mCallback = new NativeCallback(mHandler) {
@Override
public void Call(long result, Message message, String action, String reason) {
if (result != 0) {
String info = "CallFunction error: action=" + action
+ ", result=" + result + ", reason=" + reason;
reportException(new Throwable(info));
}
}
};
}
final int actinCode = msg.arg2;
final int rootViewId = instanceId;
NativeCallback callback = new NativeCallback(mHandler) {
@Override
public void Call(long result, Message message, String action, String reason) {
if (result != 0) {
String info = "CallFunction error: actinCode=" + actinCode
+ ", result=" + result + ", reason=" + reason;
reportException(new Throwable(info));
}
}
};
int functionId = msg.arg2;
PrimitiveValueSerializer serializer = (msg.obj instanceof JSValue) ?
recommendSerializer : compatibleSerializer;
@@ -185,7 +159,7 @@ public class HippyBridgeManagerImpl implements HippyBridgeManager, HippyBridge.B
buffer.put(bytes);
}
mHippyBridge.callFunction(action, callback, buffer);
mHippyBridge.callFunction(functionId, mCallback, buffer);
} else {
if (enableV8Serialization) {
if (safeHeapWriter == null) {
@@ -200,12 +174,12 @@ public class HippyBridgeManagerImpl implements HippyBridgeManager, HippyBridge.B
ByteBuffer buffer = safeHeapWriter.chunked();
int offset = buffer.arrayOffset() + buffer.position();
int length = buffer.limit() - buffer.position();
mHippyBridge.callFunction(action, callback, buffer.array(), offset, length);
mHippyBridge.callFunction(functionId, mCallback, buffer.array(), offset, length);
} else {
mStringBuilder.setLength(0);
byte[] bytes = ArgumentUtils.objectToJsonOpt(msg.obj, mStringBuilder).getBytes(
StandardCharsets.UTF_16LE);
mHippyBridge.callFunction(action, callback, bytes);
mHippyBridge.callFunction(functionId, mCallback, bytes);
}
}
}
@@ -80,5 +80,12 @@ void DestroyDomInstance(JNIEnv* j_env, __unused jobject j_obj, jint j_dom_id);
void DestroyAnimationManager(JNIEnv* j_env, __unused jobject j_obj, jint j_ani_id);
void LoadInstance(JNIEnv* j_env,
__unused jobject j_obj,
jlong j_runtime_id,
jbyteArray j_byte_array,
jint j_offset,
jint j_length);
} // namespace bridge
} // namespace hippy
@@ -110,6 +110,12 @@ REGISTER_JNI("com/tencent/link_supplier/Linker", // NOLINT(cert-err58-cpp)
"(I)V",
DestroyAnimationManager)
REGISTER_JNI( // NOLINT(cert-err58-cpp)
"com/tencent/mtt/hippy/bridge/HippyBridgeImpl",
"loadInstance",
"(J[BII)V",
LoadInstance)
using unicode_string_view = tdf::base::unicode_string_view;
using u8string = unicode_string_view::u8string;
using StringViewUtils = hippy::base::StringViewUtils;
@@ -342,17 +348,17 @@ void UpdateAnimationNode(JNIEnv* j_env,
node_style_map;
std::vector<std::pair<uint32_t, std::shared_ptr<tdf::base::DomValue>>>
ani_data;
for (size_t i = 0; i < array.size(); i++) {
TDF_BASE_DCHECK(array[i].IsObject());
for (auto & i : array) {
TDF_BASE_DCHECK(i.IsObject());
tdf::base::DomValue::DomValueObjectType node;
if (array[i].ToObject(node)) {
if (i.ToObject(node)) {
if (node[kAnimationId].IsInt32()) {
int32_t animation_id;
node[kAnimationId].ToInt32(animation_id);
tdf::base::DomValue animation_value = node[kAnimationValue];
ani_data.push_back(std::make_pair(
ani_data.emplace_back(
static_cast<uint32_t>(animation_id),
std::make_shared<tdf::base::DomValue>(animation_value)));
std::make_shared<tdf::base::DomValue>(animation_value));
}
}
}
@@ -438,6 +444,17 @@ void DestroyInstance(__unused JNIEnv* j_env,
}
}
void LoadInstance(JNIEnv* j_env,
jobject j_obj,
jlong j_runtime_id,
jbyteArray j_byte_array,
jint j_offset,
jint j_length) {
auto buffer_data = JniUtils::AppendJavaByteArrayToBytes(j_env, j_byte_array, j_offset, j_length);
V8BridgeUtils::LoadInstance(hippy::base::checked_numeric_cast<jlong, int32_t>(j_runtime_id),
std::move(buffer_data));
}
} // namespace hippy
jint JNI_OnLoad(JavaVM* j_vm, __unused void* reserved) {
File diff suppressed because one or more lines are too long
@@ -89,11 +89,12 @@ class V8BridgeUtils {
std::function<void()> on_js_runner);
static void CallNative(hippy::napi::CBDataTuple* data,
const std::function<void(std::shared_ptr<Runtime>,
unicode_string_view,
unicode_string_view,
unicode_string_view,
bool,
bytes)>& cb);
unicode_string_view,
unicode_string_view,
unicode_string_view,
bool,
bytes)>& cb);
static void LoadInstance(int32_t runtime_id, bytes&& buffer_data);
private:
static std::function<void(std::shared_ptr<Runtime>,
unicode_string_view,
+4
View File
@@ -36,6 +36,7 @@
#include "dom/dom_manager.h"
#include "dom/render_manager.h"
#include "dom/scene_builder.h"
#include "dom/dom_value.h"
#ifdef ENABLE_INSPECTOR
#include "devtools/devtools_data_source.h"
#endif
@@ -59,6 +60,7 @@ class Scope {
using CtxValue = hippy::napi::CtxValue;
using Ctx = hippy::napi::Ctx;
using DomManager = hippy::dom::DomManager;
using DomValue = tdf::base::DomValue;
using RenderManager = hippy::dom::RenderManager;
using UriLoader = hippy::base::UriLoader;
using FunctionData = hippy::napi::FunctionData;
@@ -107,6 +109,8 @@ class Scope {
const unicode_string_view& name,
bool is_copy = true);
void LoadInstance(const std::shared_ptr<DomValue>& value);
inline std::shared_ptr<JavaScriptTaskRunner> GetTaskRunner() {
return engine_->GetJSRunner();
}
+2 -28
View File
@@ -23,31 +23,6 @@ global.hippyBridge = (_action, _callObj) => {
}
switch (action) {
case 'loadInstance': {
if (__GLOBAL__.appRegister[callObj.name]) {
Object.assign(callObj.params, {
__instanceName__: callObj.name,
__instanceId__: callObj.id,
});
Object.assign(__GLOBAL__.appRegister[callObj.name], {
id: callObj.id,
superProps: callObj.params,
});
const EventModule = __GLOBAL__.jsModuleList.EventDispatcher;
if (EventModule && typeof EventModule.receiveNativeEvent === 'function') {
const params = ['@hp:loadInstance', callObj.params];
EventModule.receiveNativeEvent(params);
}
__GLOBAL__.appRegister[callObj.name].run(callObj.params);
} else {
resp = `error: ${callObj.name} is not regist in js`;
throw Error(resp);
}
break;
}
case 'callBack': {
if (callObj.result === 1) {
resp = 'error: native no modules';
@@ -74,7 +49,7 @@ global.hippyBridge = (_action, _callObj) => {
delete __GLOBAL__.moduleCallList[callObj.callId];
}
} else {
resp = 'error: calljs id is not regist in js';
resp = 'error: calljs id is not registered in js';
}
break;
}
@@ -84,7 +59,7 @@ global.hippyBridge = (_action, _callObj) => {
} else {
const targetModule = __GLOBAL__.jsModuleList[callObj.moduleName];
if (!targetModule || typeof targetModule[callObj.methodName] !== 'function') {
resp = 'error: callJsModule targetting an undefined module or method';
resp = 'error: callJsModule targeting an undefined module or method';
} else {
targetModule[callObj.methodName](callObj.params);
}
@@ -106,6 +81,5 @@ global.hippyBridge = (_action, _callObj) => {
break;
}
}
return resp;
};
@@ -23,31 +23,6 @@ global.hippyBridge = (_action, _callObj) => {
}
switch (action) {
case 'loadInstance': {
if (__GLOBAL__.appRegister[callObj.name]) {
Object.assign(callObj.params, {
__instanceName__: callObj.name,
__instanceId__: callObj.id,
});
Object.assign(__GLOBAL__.appRegister[callObj.name], {
id: callObj.id,
superProps: callObj.params,
});
const EventModule = __GLOBAL__.jsModuleList.EventDispatcher;
if (EventModule && typeof EventModule.receiveNativeEvent === 'function') {
const params = ['@hp:loadInstance', callObj.params];
EventModule.receiveNativeEvent(params);
}
__GLOBAL__.appRegister[callObj.name].run(callObj.params);
} else {
resp = `error: ${callObj.name} is not regist in js`;
throw Error(resp);
}
break;
}
case 'callBack': {
if (callObj.result === 1) {
resp = 'error: native no modules';
@@ -106,6 +81,5 @@ global.hippyBridge = (_action, _callObj) => {
break;
}
}
return resp;
};
+1 -37
View File
@@ -7,10 +7,8 @@ global.__fbBatchedBridge = {};
__fbBatchedBridge.flushedQueue = () => {
JSTimersExecution.callImmediates();
const queue = __GLOBAL__._queue;
__GLOBAL__._queue = [[], [], [], __GLOBAL__._callID];
return queue[0].length ? queue : null;
};
@@ -23,51 +21,20 @@ __fbBatchedBridge.invokeCallbackAndReturnFlushedQueue = (cbID, args) => {
__fbBatchedBridge.__invokeCallback = (cbID, args) => {
const callback = __GLOBAL__._callbacks[cbID];
if (!callback) return;
if (!__GLOBAL__._notDeleteCallbackIds[cbID & ~1]
&& !__GLOBAL__._notDeleteCallbackIds[cbID | 1]) {
delete __GLOBAL__._callbacks[cbID & ~1];
delete __GLOBAL__._callbacks[cbID | 1];
}
if (args && args.length > 1 && (args[0] === null || args[0] === undefined)) {
args.splice(0, 1);
}
callback(...args);
};
__fbBatchedBridge.callFunctionReturnFlushedQueue = (module, method, args) => {
if (module === 'IOSBridgeModule' || module === 'AppRegistry') {
if (method === 'loadInstance' || method === 'runApplication') {
const callObj = {
name: args[0],
id: args[1].rootTag,
params: args[1].initialProps,
};
if (__GLOBAL__.appRegister[callObj.name]) {
Object.assign(callObj.params, {
__instanceName__: callObj.name,
__instanceId__: callObj.id,
});
Object.assign(__GLOBAL__.appRegister[callObj.name], {
id: callObj.id,
superProps: callObj.params,
});
const EventModule = __GLOBAL__.jsModuleList.EventDispatcher;
if (EventModule && typeof EventModule.receiveNativeEvent === 'function') {
const params = ['@hp:loadInstance', callObj.params];
EventModule.receiveNativeEvent.call(EventModule, params);
}
__GLOBAL__.appRegister[callObj.name].run(callObj.params);
} else {
throw Error(`error: ${callObj.name} is not regist in js`);
}
} else if (method === 'unmountApplicationComponentAtRootTag') {
if (method === 'unmountApplicationComponentAtRootTag') {
global.Hippy.emit('destroyInstance', args[0]);
const renderId = Date.now().toString();
Hippy.bridge.callNative('UIManagerModule', 'removeRootView', args[0]);
@@ -80,7 +47,6 @@ __fbBatchedBridge.callFunctionReturnFlushedQueue = (module, method, args) => {
} else if (module === 'EventDispatcher' || module === 'Dimensions') {
const targetModule = __GLOBAL__.jsModuleList[module];
if (!targetModule || !targetModule[method] || typeof targetModule[method] !== 'function') {
// console.error("no module or no function");
} else {
targetModule[method].call(targetModule, args[1].params);
}
@@ -100,8 +66,6 @@ __fbBatchedBridge.callFunctionReturnFlushedQueue = (module, method, args) => {
});
}
}
JSTimersExecution.callImmediates();
return __fbBatchedBridge.flushedQueue();
};
+2 -2
View File
@@ -10,11 +10,11 @@ require('../../global/ConsoleModule.js'); // console
require('../../global/UIManagerModule.js'); // Hippy.document
require('../../global/Network.js'); // Headers fetch Response
require('../../global/Storage.js'); // localStorageAsync
require('../../global/Event.js'); // dealloc event
require('../../global/android/Dimensions.js'); // Hippy.device.window Hippy.device.screen Hippy.device.pixelRatio
require('../../global/UtilsModule.js'); // Hippy.device.vibrate Hippy.device.cancelVibrate
require('../../global/android/global.js'); // __GLOBAL__
require('../../global/android/global.js'); // set __GLOBAL__ object
require('../../bridge/android/native2js.js');
require('../../global/Event.js'); // register global events callback
require('../../global/android/requestAnimationFrame.js'); // requestAnimationFrame cancelAnimationFrame
require('../../global/android/Turbo.js'); // turbo
+1 -1
View File
@@ -10,11 +10,11 @@ require('../../global/ConsoleModule.js'); // console
require('../../global/UIManagerModule.js'); // Hippy.document
require('../../global/Network.js'); // Headers fetch Response
require('../../global/Storage.js'); // localStorageAsync
require('../../global/Event.js'); // dealloc event
require('../../global/flutter/Dimensions.js'); // Hippy.device.window Hippy.device.screen Hippy.device.pixelRatio
require('../../global/UtilsModule.js'); // Hippy.device.vibrate Hippy.device.cancelVibrate
require('../../global/flutter/global.js'); // __GLOBAL__
require('../../bridge/flutter/native2js.js');
require('../../global/Event.js'); // register global events callback
require('../../global/flutter/requestAnimationFrame.js'); // requestAnimationFrame cancelAnimationFrame
// require('../../global/flutter/Turbo.js'); // turbo
+2 -2
View File
@@ -11,12 +11,12 @@ require('../../global/ConsoleModule.js'); // console
require('../../global/UIManagerModule.js'); // document
require('../../global/Network.js'); // Headers fetch Response
require('../../global/Storage.js'); // localStorageAsync
require('../../global/Event.js'); // dealloc event
require('../../global/ios/Dimensions.js'); // Hippy.device.window Hippy.device.screen Hippy.device.pixelRatio
require('../../global/UtilsModule.js'); // Hippy.device.vibrate Hippy.device.cancelVibrate
require('../../global/ios/global.js'); // __GLOBAL__
require('../../global/ios/global.js'); // set __GLOBAL__ object
require('../../modules/ios/jsTimersExecution.js'); // ios module for .h build
require('../../bridge/ios/native2js.js');
require('../../global/Event.js'); // register global events callback
require('../../global/ios/requestAnimationFrame.js'); // requestAnimationFrame cancelAnimationFrame
require('../../global/ios/Turbo.js'); // turbo
// alias
+46
View File
@@ -1,5 +1,51 @@
/*
* Tencent is pleased to support the open source community by making
* Hippy available.
*
* Copyright (C) 2017-2019 THL A29 Limited, a Tencent company.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable no-underscore-dangle */
global.HippyDealloc = () => {
if (global.Hippy) {
global.Hippy.emit('dealloc');
}
};
/**
* register load instance callback
*/
global.__loadInstance__ = ((obj) => {
const { name, id, params = {} } = obj || {};
if (__GLOBAL__.appRegister[name]) {
Object.assign(params, {
__instanceName__: name,
__instanceId__: id,
});
Object.assign(__GLOBAL__.appRegister[name], {
id,
superProps: params,
});
const EventModule = __GLOBAL__.jsModuleList.EventDispatcher;
if (EventModule && typeof EventModule.receiveNativeEvent === 'function') {
EventModule.receiveNativeEvent(['@hp:loadInstance', params]);
}
__GLOBAL__.appRegister[name].run(params);
} else {
throw new Error(`load instance error: [${name}] is not registered in js`);
}
});
-41
View File
@@ -1,47 +1,6 @@
/* eslint-disable no-undef */
/* eslint-disable no-underscore-dangle */
/*
IOS __HIPPYNATIVEGLOBAL__ : {
Device : 'iPhone XR',
SDKVersion : '0.2.1',
OS :'ios',
OSVersion : '12.0'
}
Android __HIPPYNATIVEGLOBAL__ : {
Platform : {
OS : 'android',
APILevel : 'xxx'
}
}
Hippy.device.platform = {
'OS': 'web',
'Device': '',
'OSVersion': '', // for ios
'SDKVersion': '',
'APILevel': '', // for android
'AppVersion': '', // to_do
'PixelRatio' : 1, // to_do
'Dimensions' : { // to_do
window : {
width : 1,
height : 1,
scale : 1,
fontScale : 1
},
screen : {
width : 1,
height : 1,
scale : 1,
fontScale : 1,
statusBarHeight : 1
}
}
};
*/
Hippy.device.platform = {};
if (typeof __HIPPYNATIVEGLOBAL__ !== 'undefined') {
@@ -757,9 +757,7 @@ std::shared_ptr<CtxValue> JSCCtx::CreateCtxValue(const std::shared_ptr<DomValue>
std::string str = wrapper->ToStringChecked();
unicode_string_view str_view(StringViewUtils::ToU8Pointer(str.c_str()), str.length());
return CreateString(str_view);
} else if (wrapper->IsInt32()) {
return CreateNumber(wrapper->ToInt32Checked());
} else if (wrapper->IsDouble()) {
} else if (wrapper->IsNumber()) {
return CreateNumber(wrapper->ToDoubleChecked());
} else if (wrapper->IsBoolean()) {
return CreateBoolean(wrapper->ToBooleanChecked());
@@ -11,6 +11,8 @@
#include "core/napi/v8/js_native_api_v8.h"
#include "core/napi/v8/serializer.h"
#include "devtools/devtools_macro.h"
#include "dom/deserializer.h"
#include "dom/dom_value.h"
namespace hippy::runtime {
@@ -19,6 +21,8 @@ using unicode_string_view = tdf::base::unicode_string_view;
using u8string = unicode_string_view::u8string;
using Ctx = hippy::napi::Ctx;
using CtxValue = hippy::napi::CtxValue;
using Deserializer = tdf::base::Deserializer;
using DomValue = tdf::base::DomValue;
using HippyFile = hippy::base::HippyFile;
using StringViewUtils = hippy::base::StringViewUtils;
using RegisterMap = hippy::base::RegisterMap;
@@ -45,9 +49,9 @@ static std::mutex engine_mutex;
std::function<void(std::shared_ptr<Runtime>,
unicode_string_view,
unicode_string_view)> V8BridgeUtils::on_throw_exception_to_js_ = [](
const std::shared_ptr<Runtime>&,
const unicode_string_view&,
const unicode_string_view&) {};
const std::shared_ptr<Runtime>&,
const unicode_string_view&,
const unicode_string_view&) {};
int64_t V8BridgeUtils::InitInstance(bool enable_v8_serialization,
bool is_dev_module,
@@ -109,7 +113,9 @@ int64_t V8BridgeUtils::InitInstance(bool enable_v8_serialization,
bool ret = ctx->SetGlobalJsonVar(kHippyNativeGlobalKey, global_config);
if (!ret) {
TDF_BASE_DLOG(ERROR) << "register HippyNativeGlobal failed";
V8BridgeUtils::on_throw_exception_to_js_(runtime, u"global_config parse error", global_config);
V8BridgeUtils::on_throw_exception_to_js_(runtime,
u"global_config parse error",
global_config);
}
};
std::unique_ptr<RegisterMap> scope_cb_map = std::make_unique<RegisterMap>();
@@ -216,12 +222,12 @@ bool V8BridgeUtils::RunScript(const std::shared_ptr<Runtime>& runtime,
}
bool V8BridgeUtils::RunScriptWithoutLoader(const std::shared_ptr<Runtime>& runtime,
const unicode_string_view& file_name,
bool is_use_code_cache,
const unicode_string_view& code_cache_dir,
const unicode_string_view& uri,
bool is_local_file,
std::function<unicode_string_view()> content_cb) {
const unicode_string_view& file_name,
bool is_use_code_cache,
const unicode_string_view& code_cache_dir,
const unicode_string_view& uri,
bool is_local_file,
std::function<unicode_string_view()> content_cb) {
TDF_BASE_LOG(INFO) << "RunScript begin, file_name = " << file_name
<< ", is_use_code_cache = " << is_use_code_cache
<< ", code_cache_dir = " << code_cache_dir
@@ -240,14 +246,14 @@ bool V8BridgeUtils::RunScriptWithoutLoader(const std::shared_ptr<Runtime>& runti
}
code_cache_path = code_cache_dir + file_name + unicode_string_view("_") +
unicode_string_view(std::to_string(modify_time));
unicode_string_view(std::to_string(modify_time));
std::promise<u8string> read_file_promise;
std::future<u8string> read_file_future = read_file_promise.get_future();
std::unique_ptr<CommonTask> task = std::make_unique<CommonTask>();
task->func_ =
hippy::base::MakeCopyable([p = std::move(read_file_promise),
code_cache_path, code_cache_dir]() mutable {
code_cache_path, code_cache_dir]() mutable {
u8string content;
HippyFile::ReadFile(code_cache_path, content, true);
if (content.empty()) {
@@ -287,9 +293,8 @@ bool V8BridgeUtils::RunScriptWithoutLoader(const std::shared_ptr<Runtime>& runti
}
auto ret = std::static_pointer_cast<hippy::napi::V8Ctx>(
runtime->GetScope()->GetContext())
->RunScript(script_content, file_name, is_use_code_cache,
&code_cache_content, true);
runtime->GetScope()->GetContext())->RunScript(script_content, file_name, is_use_code_cache,
&code_cache_content, true);
if (is_use_code_cache) {
if (!StringViewUtils::IsEmpty(code_cache_content)) {
std::unique_ptr<CommonTask> task = std::make_unique<CommonTask>();
@@ -306,8 +311,7 @@ bool V8BridgeUtils::RunScriptWithoutLoader(const std::shared_ptr<Runtime>& runti
StringViewUtils::SubStr(code_cache_path, 0, pos);
int check_parent_dir_ret =
HippyFile::CheckDir(code_cache_parent_dir, F_OK);
TDF_BASE_DLOG(INFO)
<< "check_parent_dir_ret = " << check_parent_dir_ret;
TDF_BASE_DLOG(INFO) << "check_parent_dir_ret = " << check_parent_dir_ret;
if (check_parent_dir_ret) {
HippyFile::CreateDir(code_cache_parent_dir, S_IRWXU);
}
@@ -478,12 +482,10 @@ void V8BridgeUtils::CallJs(const unicode_string_view& action,
std::shared_ptr<CtxValue> params;
if (runtime->IsEnableV8Serialization()) {
v8::Isolate* isolate = std::static_pointer_cast<hippy::napi::V8VM>(
runtime->GetEngine()->GetVM())
->isolate_;
runtime->GetEngine()->GetVM())->isolate_;
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> ctx = std::static_pointer_cast<hippy::napi::V8Ctx>(
runtime->GetScope()->GetContext())
->context_persistent_.Get(isolate);
runtime->GetScope()->GetContext())->context_persistent_.Get(isolate);
hippy::napi::V8TryCatch try_catch(true, context);
v8::ValueDeserializer deserializer(
isolate, reinterpret_cast<const uint8_t*>(buffer_data_.c_str()),
@@ -633,4 +635,34 @@ void V8BridgeUtils::CallNative(hippy::napi::CBDataTuple* data, const std::functi
cb(runtime, module, func, cb_id, is_heap_buffer, buffer);
}
void V8BridgeUtils::LoadInstance(int32_t runtime_id, bytes&& buffer_data) {
TDF_BASE_DLOG(INFO) << "LoadInstance runtime_id = " << runtime_id;
std::shared_ptr<Runtime> runtime = Runtime::Find(runtime_id);
if (!runtime) {
return;
}
auto runner = runtime->GetEngine()->GetJSRunner();
std::shared_ptr<JavaScriptTask> task = std::make_shared<JavaScriptTask>();
std::weak_ptr<Scope> weak_scope = runtime->GetScope();
task->callback = [weak_scope, buffer_data_ = std::move(buffer_data)] {
std::shared_ptr<Scope> scope = weak_scope.lock();
if (!scope) {
return;
}
Deserializer deserializer(
reinterpret_cast<const uint8_t*>(buffer_data_.c_str()),
buffer_data_.length());
DomValue value;
deserializer.ReadHeader();
auto ret = deserializer.ReadValue(value);
if (ret) {
scope->LoadInstance(std::make_shared<DomValue>(std::move(value)));
} else {
scope->GetContext()->ThrowException("LoadInstance param error");
}
};
runner->PostTask(task);
}
}
+29 -1
View File
@@ -45,6 +45,7 @@ using CtxValue = hippy::napi::CtxValue;
using TryCatch = hippy::napi::TryCatch;
constexpr char kDeallocFuncName[] = "HippyDealloc";
constexpr char kLoadInstanceFuncName[] = "__loadInstance__";
constexpr char kHippyBootstrapJSName[] = "bootstrap.js";
constexpr uint64_t kInvalidListenerId = 0;
@@ -324,7 +325,7 @@ std::shared_ptr<CtxValue> Scope::RunJSSync(const unicode_string_view& data,
p.set_value(rst);
});
std::shared_ptr<JavaScriptTaskRunner> runner = engine_->GetJSRunner();
auto runner = engine_->GetJSRunner();
if (runner->IsJsThread()) {
cb();
} else {
@@ -335,3 +336,30 @@ std::shared_ptr<CtxValue> Scope::RunJSSync(const unicode_string_view& data,
std::shared_ptr<CtxValue> ret = future.get();
return ret;
}
void Scope::LoadInstance(const std::shared_ptr<DomValue>& value) {
std::weak_ptr<Ctx> weak_context = context_;
auto cb = [weak_context, value]() mutable {
std::shared_ptr<Ctx> context = weak_context.lock();
if (context) {
std::shared_ptr<CtxValue> fn = context->GetJsFn(kLoadInstanceFuncName);
bool is_fn = context->IsFunction(fn);
TDF_BASE_DCHECK(is_fn);
if (is_fn) {
auto param = context->CreateCtxValue(value);
std::shared_ptr<CtxValue> argv[] = {param};
context->CallFunction(fn, 1, argv);
} else {
context->ThrowException("Application entry not found");
}
}
};
auto runner = engine_->GetJSRunner();
if (runner->IsJsThread()) {
cb();
} else {
auto task = std::make_shared<JavaScriptTask>();
task->callback = cb;
runner->PostTask(task);
}
}
File diff suppressed because one or more lines are too long
+12 -6
View File
@@ -37,6 +37,9 @@
#import "HippyView.h"
#import "UIView+Hippy.h"
#import "HippyBundleURLProvider.h"
#include "scope.h"
#include "dom/dom_value.h"
#include "HippyDomNodeUtils.h"
NSString *const HippyContentDidAppearNotification = @"HippyContentDidAppearNotification";
@@ -320,16 +323,19 @@ HIPPY_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
}
- (void)runApplication:(HippyBridge *)bridge {
NSAssert(_contentView, @"content view must exist");
if (_contentView == nil) {
assert(0); // 这里不正常了,走到这里联系下 pennyli
return;
}
NSString *moduleName = _moduleName ?: @"";
NSDictionary *appParameters =
@{ @"rootTag": _contentView.hippyTag, @"initialProps": _appProperties ?: @ {}, @"commonSDKVersion": HippySDKVersion };
HippyLogInfo(@"[Hippy_OC_Log][Life_Circle],Running application %@ (%@)", moduleName, appParameters);
[bridge enqueueJSCall:@"AppRegistry" method:@"runApplication" args:@[moduleName, appParameters] completion:NULL];
HippyLogInfo(@"[Hippy_OC_Log][Life_Circle],Running application %@ (%@)", moduleName, _appProperties);
NSDictionary *param = @{@"name": moduleName,
@"id": _contentView.hippyTag,
@"params": _appProperties ?: @{},
@"version": HippySDKVersion};
tdf::base::DomValue value = OCTypeToDomValue(param);
std::shared_ptr<tdf::base::DomValue> domValue = std::make_shared<tdf::base::DomValue>(value);
bridge.javaScriptExecutor.pScope->LoadInstance(domValue);
}
- (void)layoutSubviews {
File diff suppressed because one or more lines are too long
@@ -30,6 +30,8 @@ NS_ASSUME_NONNULL_BEGIN
HIPPY_EXTERN id domValueToOCType(const tdf::base::DomValue *const pDomValue);
extern tdf::base::DomValue OCTypeToDomValue(id value);
HIPPY_EXTERN NSDictionary *unorderedMapDomValueToDictionary(const std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<tdf::base::DomValue>>> &domValuesObject);
extern std::unordered_map<std::string, std::shared_ptr<tdf::base::DomValue>> dictionaryToUnorderedMapDomValue(NSDictionary *dictionary);