refactor: devkit depends on doric

This commit is contained in:
王劲鹏
2019-11-23 15:50:28 +08:00
parent 72e59ffb86
commit 10f343a95b
18 changed files with 103 additions and 96 deletions

View File

@@ -26,7 +26,6 @@ import java.util.HashMap;
import java.util.Map;
import pub.doric.async.AsyncResult;
import pub.doric.devkit.IStatusCallback;
import pub.doric.plugin.DoricJavaPlugin;
import pub.doric.shader.RootNode;
import pub.doric.utils.DoricConstant;
@@ -45,10 +44,9 @@ public class DoricContext {
private final String source;
private String script;
private JSONObject initParams;
public boolean isDebugging = false;
private DoricDebugDriver doricDebugDriver;
private IDoricDriver doricDriver;
DoricContext(Context context, String contextId, String source) {
protected DoricContext(Context context, String contextId, String source) {
this.mContext = context;
this.mContextId = contextId;
this.source = source;
@@ -73,7 +71,11 @@ public class DoricContext {
.put("width", width)
.put("height", height).toJSONObject();
callEntity(DoricConstant.DORIC_ENTITY_INIT, this.initParams);
callEntity(DoricConstant.DORIC_ENTITY_CREATE);
}
public void reInit() {
callEntity(DoricConstant.DORIC_ENTITY_INIT, this.initParams);
callEntity(DoricConstant.DORIC_ENTITY_CREATE);
}
@@ -82,11 +84,14 @@ public class DoricContext {
}
public IDoricDriver getDriver() {
if (isDebugging) {
return doricDebugDriver;
} else {
return DoricNativeDriver.getInstance();
if (doricDriver == null) {
doricDriver = DoricNativeDriver.getInstance();
}
return doricDriver;
}
public void setDriver(IDoricDriver doricDriver) {
this.doricDriver = doricDriver;
}
public RootNode getRootNode() {
@@ -143,22 +148,4 @@ public class DoricContext {
public void onHidden() {
callEntity(DoricConstant.DORIC_ENTITY_HIDDEN);
}
public void startDebug() {
doricDebugDriver = new DoricDebugDriver(new IStatusCallback() {
@Override
public void start() {
isDebugging = true;
callEntity(DoricConstant.DORIC_ENTITY_INIT, initParams);
callEntity(DoricConstant.DORIC_ENTITY_CREATE);
}
});
}
public void stopDebug() {
doricDebugDriver.destroy();
isDebugging = false;
callEntity(DoricConstant.DORIC_ENTITY_INIT, initParams);
callEntity(DoricConstant.DORIC_ENTITY_CREATE);
}
}

View File

@@ -1,134 +0,0 @@
/*
* Copyright [2019] [Doric.Pub]
*
* 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.
*/
package pub.doric;
import android.os.Handler;
import android.os.Looper;
import com.github.pengfeizhou.jscore.JSDecoder;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import pub.doric.async.AsyncCall;
import pub.doric.async.AsyncResult;
import pub.doric.devkit.IStatusCallback;
import pub.doric.engine.DoricJSEngine;
import pub.doric.utils.DoricConstant;
import pub.doric.utils.DoricLog;
import pub.doric.utils.ThreadMode;
/**
* @Description: Doric
* @Author: pengfei.zhou
* @CreateDate: 2019-07-18
*/
public class DoricDebugDriver implements IDoricDriver {
private final DoricJSEngine doricJSEngine;
private final ExecutorService mBridgeExecutor;
private final Handler mUIHandler;
private final Handler mJSHandler;
public DoricDebugDriver(IStatusCallback statusCallback) {
doricJSEngine = new DoricJSEngine(false, statusCallback);
mBridgeExecutor = Executors.newCachedThreadPool();
mUIHandler = new Handler(Looper.getMainLooper());
mJSHandler = doricJSEngine.getJSHandler();
}
@Override
public AsyncResult<JSDecoder> invokeContextEntityMethod(final String contextId, final String method, final Object... args) {
final Object[] nArgs = new Object[args.length + 2];
nArgs[0] = contextId;
nArgs[1] = method;
if (args.length > 0) {
System.arraycopy(args, 0, nArgs, 2, args.length);
}
return invokeDoricMethod(DoricConstant.DORIC_CONTEXT_INVOKE, nArgs);
}
@Override
public AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args) {
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<JSDecoder>() {
@Override
public JSDecoder call() {
try {
return doricJSEngine.invokeDoricMethod(method, args);
} catch (Exception e) {
DoricLog.e("invokeDoricMethod(%s,...),error is %s", method, e.getLocalizedMessage());
return new JSDecoder(null);
}
}
});
}
@Override
public <T> AsyncResult<T> asyncCall(Callable<T> callable, ThreadMode threadMode) {
switch (threadMode) {
case JS:
return AsyncCall.ensureRunInHandler(mJSHandler, callable);
case UI:
return AsyncCall.ensureRunInHandler(mUIHandler, callable);
case INDEPENDENT:
default:
return AsyncCall.ensureRunInExecutor(mBridgeExecutor, callable);
}
}
@Override
public AsyncResult<Boolean> createContext(final String contextId, final String script, final String source) {
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() {
@Override
public Boolean call() {
try {
doricJSEngine.prepareContext(contextId, script, source);
return true;
} catch (Exception e) {
DoricLog.e("createContext %s error is %s", source, e.getLocalizedMessage());
return false;
}
}
});
}
@Override
public AsyncResult<Boolean> destroyContext(final String contextId) {
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() {
@Override
public Boolean call() {
try {
doricJSEngine.destroyContext(contextId);
return true;
} catch (Exception e) {
DoricLog.e("destroyContext %s error is %s", contextId, e.getLocalizedMessage());
return false;
}
}
});
}
@Override
public DoricRegistry getRegistry() {
return doricJSEngine.getRegistry();
}
public void destroy() {
doricJSEngine.teardown();
mBridgeExecutor.shutdown();
}
}

View File

@@ -47,7 +47,7 @@ public class DoricNativeDriver implements IDoricDriver {
}
private DoricNativeDriver() {
doricJSEngine = new DoricJSEngine(true, null);
doricJSEngine = new DoricJSEngine();
mBridgeExecutor = Executors.newCachedThreadPool();
mUIHandler = new Handler(Looper.getMainLooper());
mJSHandler = doricJSEngine.getJSHandler();

View File

@@ -28,7 +28,6 @@ import com.github.pengfeizhou.jscore.JavaValue;
import java.util.ArrayList;
import pub.doric.DoricRegistry;
import pub.doric.devkit.IStatusCallback;
import pub.doric.extension.bridge.DoricBridgeExtension;
import pub.doric.extension.timer.DoricTimerExtension;
import pub.doric.utils.DoricConstant;
@@ -45,11 +44,11 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time
private HandlerThread handlerThread;
private final Handler mJSHandler;
private final DoricBridgeExtension mDoricBridgeExtension = new DoricBridgeExtension();
private IDoricJSE mDoricJSE;
protected IDoricJSE mDoricJSE;
private final DoricTimerExtension mTimerExtension;
private final DoricRegistry mDoricRegistry = new DoricRegistry();
public DoricJSEngine(final boolean isNative, final IStatusCallback statusCallback) {
public DoricJSEngine() {
handlerThread = new HandlerThread(this.getClass().getSimpleName());
handlerThread.start();
Looper looper = handlerThread.getLooper();
@@ -57,12 +56,7 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time
mJSHandler.post(new Runnable() {
@Override
public void run() {
if (isNative) {
mDoricJSE = new DoricNativeJSExecutor();
} else {
mDoricJSE = new DoricRemoteJSExecutor(statusCallback);
}
initJSEngine();
injectGlobal();
initDoricRuntime();
}
@@ -74,6 +68,10 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time
return mJSHandler;
}
protected void initJSEngine() {
mDoricJSE = new DoricNativeJSExecutor();
}
private void injectGlobal() {
mDoricJSE.injectGlobalJSFunction(DoricConstant.INJECT_LOG, new JavaFunction() {
@Override

View File

@@ -1,63 +0,0 @@
/*
* Copyright [2019] [Doric.Pub]
*
* 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.
*/
package pub.doric.engine;
import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JSRuntimeException;
import com.github.pengfeizhou.jscore.JavaFunction;
import com.github.pengfeizhou.jscore.JavaValue;
import pub.doric.devkit.IStatusCallback;
import pub.doric.devkit.remote.RemoteJSExecutor;
public class DoricRemoteJSExecutor implements IDoricJSE {
private final RemoteJSExecutor mRemoteJSExecutor;
public DoricRemoteJSExecutor(IStatusCallback statusCallback) {
this.mRemoteJSExecutor = new RemoteJSExecutor(statusCallback);
}
@Override
public String loadJS(String script, String source) throws JSRuntimeException {
return mRemoteJSExecutor.loadJS(script, source);
}
@Override
public JSDecoder evaluateJS(String script, String source, boolean hashKey) throws JSRuntimeException {
return mRemoteJSExecutor.evaluateJS(script, source, hashKey);
}
@Override
public void injectGlobalJSFunction(String name, JavaFunction javaFunction) {
mRemoteJSExecutor.injectGlobalJSFunction(name, javaFunction);
}
@Override
public void injectGlobalJSObject(String name, JavaValue javaValue) {
mRemoteJSExecutor.injectGlobalJSObject(name, javaValue);
}
@Override
public JSDecoder invokeMethod(String objectName, String functionName, JavaValue[] javaValues, boolean hashKey) throws JSRuntimeException {
return mRemoteJSExecutor.invokeMethod(objectName, functionName, javaValues, hashKey);
}
@Override
public void teardown() {
mRemoteJSExecutor.destroy();
}
}

View File

@@ -0,0 +1,5 @@
package pub.doric.engine;
public interface IStatusCallback {
void start();
}

View File

@@ -1,181 +0,0 @@
/*
* Copyright [2019] [Doric.Pub]
*
* 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.
*/
package pub.doric.utils;
import android.content.Context;
import android.content.res.AssetManager;
import android.net.Uri;
import android.util.Log;
import android.webkit.MimeTypeMap;
import com.github.pengfeizhou.jscore.JSONBuilder;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import fi.iki.elonen.NanoHTTPD;
import pub.doric.DoricContext;
import pub.doric.DoricContextManager;
/**
* @Description: com.github.penfeizhou.doricdemo
* @Author: pengfei.zhou
* @CreateDate: 2019-08-03
*/
public class LocalServer extends NanoHTTPD {
private final Context context;
private Map<String, APICommand> commandMap = new HashMap<>();
public LocalServer(Context context, int port) {
super(port);
this.context = context;
commandMap.put("allContexts", new APICommand() {
@Override
public String name() {
return "allContexts";
}
@Override
public Object exec(IHTTPSession session) {
Collection<DoricContext> ret = DoricContextManager.aliveContexts();
JSONArray jsonArray = new JSONArray();
for (DoricContext doricContext : ret) {
JSONBuilder jsonBuilder = new JSONBuilder();
jsonBuilder.put("source", doricContext.getSource());
jsonBuilder.put("id", doricContext.getContextId());
jsonArray.put(jsonBuilder.toJSONObject());
}
return jsonArray;
}
});
commandMap.put("context", new APICommand() {
@Override
public String name() {
return "context";
}
@Override
public Object exec(IHTTPSession session) {
String id = session.getParms().get("id");
DoricContext doricContext = DoricContextManager.getContext(id);
if (doricContext != null) {
return new JSONBuilder()
.put("id", doricContext.getContextId())
.put("source", doricContext.getSource())
.put("script", doricContext.getScript())
.toJSONObject();
}
return "{}";
}
});
commandMap.put("reload", new APICommand() {
@Override
public String name() {
return "reload";
}
@Override
public Object exec(IHTTPSession session) {
Map<String, String> files = new HashMap<>();
try {
session.parseBody(files);
} catch (Exception e) {
e.printStackTrace();
}
String id = session.getParms().get("id");
DoricContext doricContext = DoricContextManager.getContext(id);
if (doricContext != null) {
try {
JSONObject jsonObject = new JSONObject(files.get("postData"));
doricContext.reload(jsonObject.optString("script"));
} catch (Exception e) {
e.printStackTrace();
}
return "success";
}
return "fail";
}
});
}
private static String getIpAddressString() {
try {
for (Enumeration<NetworkInterface> enNetI = NetworkInterface
.getNetworkInterfaces(); enNetI.hasMoreElements(); ) {
NetworkInterface netI = enNetI.nextElement();
for (Enumeration<InetAddress> enumIpAddr = netI
.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (inetAddress instanceof Inet4Address && !inetAddress.isLoopbackAddress()) {
return inetAddress.getHostAddress();
}
}
}
} catch (SocketException e) {
e.printStackTrace();
}
return "0.0.0.0";
}
@Override
public void start() throws IOException {
super.start();
Log.d("Debugger", String.format("Open http://%s:8910/index.html to start debug", getIpAddressString()));
}
@Override
public Response serve(IHTTPSession session) {
Uri uri = Uri.parse(session.getUri());
List<String> segments = uri.getPathSegments();
if (segments.size() > 1 && "api".equals(segments.get(0))) {
String cmd = segments.get(1);
APICommand apiCommand = commandMap.get(cmd);
if (apiCommand != null) {
Object ret = apiCommand.exec(session);
return NanoHTTPD.newFixedLengthResponse(Response.Status.OK, "application/json", ret.toString());
}
}
String fileName = session.getUri().substring(1);
AssetManager assetManager = context.getAssets();
try {
InputStream inputStream = assetManager.open("debugger/" + fileName);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileName.substring(fileName.lastIndexOf(".") + 1));
return NanoHTTPD.newFixedLengthResponse(Response.Status.OK, mimeType, inputStream, inputStream.available());
} catch (IOException e) {
e.printStackTrace();
}
return NanoHTTPD.newFixedLengthResponse(Response.Status.OK, "text/html", "HelloWorld");
}
public interface APICommand {
String name();
Object exec(IHTTPSession session);
}
}