/*
* Created by LuaView.
* Copyright (c) 2017, Alibaba Group. All rights reserved.
*
* This source code is licensed under the MIT.
* For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
*/
package com.taobao.luaview.global;
import android.content.Context;
import android.view.ViewGroup;
import com.taobao.luaview.fun.mapper.ui.UIViewGroupMethodMapper;
import com.taobao.luaview.provider.ImageProvider;
import com.taobao.luaview.scriptbundle.ScriptBundle;
import com.taobao.luaview.scriptbundle.ScriptFile;
import com.taobao.luaview.userdata.ui.UDView;
import com.taobao.luaview.util.LuaUtil;
import com.taobao.luaview.view.LVCustomPanel;
import com.taobao.luaview.view.LVViewGroup;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import java.io.InputStream;
/**
* LuaView 实现类
*
* @author song
* @date 15/8/20
*/
public class LuaView extends LVViewGroup {
//LuaViewCore
private LuaViewCore mLuaViewCore;
/**
* created callback
*/
public interface CreatedCallback {
void onCreated(LuaView luaView);
}
//---------------------------------------静态方法------------------------------------------------
/**
* create a luaview
*
* @param context
* @return
*/
public static LuaView create(final Context context) {
LuaViewCore luaViewCore = LuaViewCore.create(context);
return createLuaView(context, luaViewCore);
}
/**
* create LuaView async
*
* @param context
* @return
*/
public static LuaView createAsync(final Context context) {
LuaViewCore luaViewCore = LuaViewCore.createAsync(context);
return createLuaView(context, luaViewCore);
}
/**
* create LuaView async (兼容老的,可以使用无回调方法)
*
* @param context
* @param createdCallback
*/
public static void createAsync(final Context context, final CreatedCallback createdCallback) {
LuaViewCore.createAsync(context, new LuaViewCore.CreatedCallback() {
@Override
public void onCreated(LuaViewCore luaViewCore) {
final LuaView luaView = createLuaView(context, luaViewCore);
if (createdCallback != null) {
createdCallback.onCreated(luaView);
}
}
});
}
private static LuaView createLuaView(final Context context, LuaViewCore luaViewCore) {
final LuaView luaView = new LuaView(context, luaViewCore, createMetaTableForLuaView());
luaViewCore.setRenderTarget(luaView);
luaViewCore.setWindowUserdata(luaView.getUserdata());
return luaView;
}
//-----------------------------------------加载函数----------------------------------------------
/**
* 加载,可能是url,可能是Asset,可能是文件,也可能是脚本
* url : http or https, http://[xxx] or https://[xxx]
* asset : folder or file, file://android_asset/[xxx]
* file : folder or file, file://[xxx]
* script: content://[xxx]
*
* @param urlOrFileOrScript
* @return
*/
public LuaView load(final String urlOrFileOrScript) {
return load(urlOrFileOrScript, null, null);
}
public LuaView load(final String urlOrFileOrScript, final LuaScriptLoader.ScriptExecuteCallback callback) {
return load(urlOrFileOrScript, null, callback);
}
public LuaView load(final String urlOrFileOrScript, final String sha256) {
return load(urlOrFileOrScript, sha256, null);
}
public LuaView load(final String urlOrFileOrScript, final String sha256, final LuaScriptLoader.ScriptExecuteCallback callback) {
if (mLuaViewCore != null) {
mLuaViewCore.load(urlOrFileOrScript, sha256, callback);
}
return this;
}
/**
* 直接加载网络脚本
*
* @param url http://[xxx] or https://[xxx]
* @return
*/
public LuaView loadUrl(final String url, final String sha256) {
return loadUrl(url, sha256, null);
}
public LuaView loadUrl(final String url, final String sha256, final LuaScriptLoader.ScriptExecuteCallback callback) {
if (mLuaViewCore != null) {
mLuaViewCore.loadUrl(url, sha256, callback);
}
return this;
}
/**
* 加载 Asset路径下的脚本
*
* @param assetPath folder path or file path
* @return
*/
private LuaView loadAsset(final String assetPath) {
return loadAsset(assetPath, null);
}
private LuaView loadAsset(final String assetPath, final LuaScriptLoader.ScriptExecuteCallback callback) {
if (mLuaViewCore != null) {
mLuaViewCore.loadAsset(assetPath, callback);
}
return this;
}
/**
* 加载脚本库,必须在主进程中执行,先判断asset下是否存在,再去文件系统中查找
*
* @param luaFileName plain file name or file://[xxx]
* @return
*/
private LuaView loadFile(final String luaFileName) {
return loadFile(luaFileName, null);
}
private LuaView loadFile(final String luaFileName, final LuaScriptLoader.ScriptExecuteCallback callback) {
if (mLuaViewCore != null) {
mLuaViewCore.loadFile(luaFileName, callback);
}
return this;
}
/**
* Load plain Script Code
*
* @param script
* @return
*/
public LuaView loadScript(final String script) {
return loadScript(script, null);
}
public LuaView loadScript(final String script, final LuaScriptLoader.ScriptExecuteCallback callback) {
if (mLuaViewCore != null) {
mLuaViewCore.loadScript(script, callback);
}
return this;
}
/**
* 加载Script Bundle (zip file)
*
* @param scriptFile
* @return
*/
private LuaView loadScript(final ScriptFile scriptFile) {
return loadScript(scriptFile, null);
}
private LuaView loadScript(final ScriptFile scriptFile, final LuaScriptLoader.ScriptExecuteCallback callback) {
if (mLuaViewCore != null) {
mLuaViewCore.loadScript(scriptFile, callback);
}
return this;
}
/**
* 加载 Script Bundle
*
* @param scriptBundle
* @return
*/
public LuaView loadScriptBundle(final ScriptBundle scriptBundle) {
return loadScriptBundle(scriptBundle, null);
}
public LuaView loadScriptBundle(final ScriptBundle scriptBundle, final LuaScriptLoader.ScriptExecuteCallback callback) {
return loadScriptBundle(scriptBundle, LuaResourceFinder.DEFAULT_MAIN_ENTRY, callback);
}
public LuaView loadScriptBundle(final ScriptBundle scriptBundle, final String mainScriptFileName, final LuaScriptLoader.ScriptExecuteCallback callback) {
if (mLuaViewCore != null) {
mLuaViewCore.loadScriptBundle(scriptBundle, mainScriptFileName, callback);
}
return this;
}
/**
* load prototype (lua bytecode or sourcecode)
*
* @param inputStream
* @return
*/
public LuaView loadPrototype(final InputStream inputStream, final String name, final LuaScriptLoader.ScriptExecuteCallback callback) {
if (mLuaViewCore != null) {
mLuaViewCore.loadPrototype(inputStream, name, callback);
}
return this;
}
/**
* execute script
*
* @param value
* @param activity
* @param viewObj
* @param callback
* @return
*/
public boolean executeScript(LuaValue value, LuaValue activity, LuaValue viewObj, final LuaScriptLoader.ScriptExecuteCallback callback) {
return mLuaViewCore != null ? mLuaViewCore.executeScript(value, activity, viewObj, callback) : false;
}
//---------------------------------------注册函数------------------------------------------------
/**
* 加载一个binder,可以用作覆盖老功能
* Lib 必须注解上 LuaViewLib
*
* @param binders
* @return
*/
public LuaView registerLibs(LuaValue... binders) {
if (mLuaViewCore != null) {
mLuaViewCore.registerLibs(binders);
}
return this;
}
/**
* 注册一个名称到该lua对象的命名空间中
*
* @param luaName
* @param obj
* @return
*/
public LuaView register(final String luaName, final Object obj) {
if (mLuaViewCore != null) {
mLuaViewCore.register(luaName, obj);
}
return this;
}
/**
* 注册一个名称到该lua对象的命名空间中
*
* @param clazz
* @return
*/
public LuaView registerPanel(final Class<? extends LVCustomPanel> clazz) {
return registerPanel(clazz != null ? clazz.getSimpleName() : null, clazz);
}
/**
* 注册一个名称到该lua对象的命名空间中
*
* @param luaName
* @param clazz
* @return
*/
public LuaView registerPanel(final String luaName, final Class<? extends LVCustomPanel> clazz) {
if (mLuaViewCore != null) {
mLuaViewCore.registerPanel(luaName, clazz);
}
return this;
}
/**
* 解注册一个命名空间中的名字
*
* @param luaName
* @return
*/
public LuaView unregister(final String luaName) {
if (mLuaViewCore != null) {
mLuaViewCore.unregister(luaName);
}
return this;
}
//----------------------------------------call lua function-------------------------------------
/**
* 调用lua的某个全局函数
*
* @param funName
* @param objs
* @return
*/
public Object callLuaFunction(String funName, Object... objs) {
if (mLuaViewCore != null) {
mLuaViewCore.callLuaFunction(funName, objs);
}
return LuaValue.NIL;
}
/**
* 调用window.callback下的某个函数
*
* @param funName
* @param objs
* @return
*/
public Varargs callWindowFunction(String funName, Object... objs) {
if (funName != null) {
final UDView userdata = getUserdata();
if (userdata != null) {
final LuaValue callbacks = userdata.getCallback();
if (LuaUtil.isValid(callbacks)) {
return LuaUtil.callFunction(callbacks.get(funName), objs);
}
}
}
return LuaValue.NIL;
}
//----------------------------------------Image Provider----------------------------------------
/**
* 注册ImageProvider
*/
public static void registerImageProvider(final Class<? extends ImageProvider> clazz) {
LuaViewCore.registerImageProvider(clazz);
}
/**
* 获取ImageProvider
*
* @return
*/
public static ImageProvider getImageProvider() {
return LuaViewCore.getImageProvider();
}
//----------------------------------------setup functions---------------------------------------
/**
* 设置使用标准语法
*
* @param standardSyntax
*/
public void setUseStandardSyntax(boolean standardSyntax) {
if (mLuaViewCore != null) {
mLuaViewCore.setUseStandardSyntax(standardSyntax);
}
}
/**
* 刷新容器是否可以刷新(用在RefreshCollectionView初始化的地方)
*
* @param enable
*/
public void setRefreshContainerEnable(boolean enable) {
if (mLuaViewCore != null) {
mLuaViewCore.setRefreshContainerEnable(enable);
}
}
/**
* 刷新容器是否可以刷新(用在RefreshCollectionView初始化的地方)
*/
public boolean isRefreshContainerEnable() {
return mLuaViewCore != null ? mLuaViewCore.isRefreshContainerEnable() : true;
}
public String getUri() {
return mLuaViewCore != null ? mLuaViewCore.getUri() : null;
}
public Globals getGlobals() {
return mLuaViewCore != null ? mLuaViewCore.getGlobals() : null;
}
public LuaViewCore getLuaViewCore() {
return mLuaViewCore;
}
//-------------------------------------------私有------------------------------------------------
/**
* TODO 优化
* 创建LuaView的methods,这里可以优化,实现更加优雅,其实就是将window注册成一个userdata,并且userdata是UDViewGroup
*
* @return
*/
private static LuaTable createMetaTableForLuaView() {
return LuaViewManager.createMetatable(UIViewGroupMethodMapper.class);
}
/**
* @param context View级别的Context
* @param luaViewCore
* @param metaTable
*/
private LuaView(Context context, LuaViewCore luaViewCore, LuaValue metaTable) {
super(context, luaViewCore.getGlobals(), metaTable, LuaValue.NIL);
this.mLuaViewCore = luaViewCore;
}
//-----------------------------------------网络回调----------------------------------------------
/**
* 当显示的时候调用
*/
@Override
protected void onWindowVisibilityChanged(int visibility) {
if (mLuaViewCore != null) {
mLuaViewCore.onShow(visibility);
}
super.onWindowVisibilityChanged(visibility);
if (mLuaViewCore != null) {
mLuaViewCore.onHide(visibility);
}
}
/**
* 创建的时候调用
*/
@Override
protected void onAttachedToWindow() {
if (mLuaViewCore != null) {
mLuaViewCore.onAttached();
}
super.onAttachedToWindow();
}
/**
* 离开的时候调用
*/
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mLuaViewCore != null) {
mLuaViewCore.onDetached();
}
}
//----------------------------------------getter and setter-------------------------------------
/**
* create a default render target (viewgroup)
*
* @return
*/
public ViewGroup createDefaultRenderTarget() {
return new LVViewGroup(getGlobals(), createMetaTableForLuaView(), null);
}
/**
* set render target
*
* @param viewGroup
* @return
*/
public LuaView setRenderTarget(ViewGroup viewGroup) {
if (mLuaViewCore != null) {
mLuaViewCore.setRenderTarget(viewGroup);
//TODO 需要在这里设置setWindowUserdata(XXX)
}
return this;
}
/**
* get render target
*
* @return
*/
private ViewGroup getRenderTarget() {
return mLuaViewCore != null ? mLuaViewCore.getRenderTarget() : this;
}
//----------------------------------------生命周期 管理----------------------------------------
/**
* 销毁的时候从外部调用,清空所有外部引用
*/
public void onDestroy() {
if (mLuaViewCore != null) {
mLuaViewCore.onDestroy();
mLuaViewCore = null;
}
}
}