游戏助手-LuaJava框架实现脚本中断的方法

脚本有需求,需要实现一个forceStop方法供脚本主动中断。

LuaJava框架中,Lua脚本从入口LuaState.pcall方法开始,会一直阻塞当前Java线程的运行,直到Lua脚本执行结束。

关键代码

实现中断退出使用的是Lua虚拟机的lua_error方法,

LUA_API int   (lua_error) (lua_State *L);
复制代码

然后就是找到该方法的调用时机。

不能随便找个地方就直接使用lua_error来中断pcall,这样会导致Java层出现各种莫名其妙的异常使得整个程序崩溃。

解决方案

选择在luajava.cpp的luaJavaFunctionCall方法中修改,所有通过框架注册的自定义Java函数都会走到这里,

int luaJavaFunctionCall(lua_State *L) {
  ...
   /* the Object must be an instance of the JavaFunction class */
    if (javaEnv->IsInstanceOf(*obj, java_function_class) ==
        JNI_FALSE) {
        fprintf(stderr, "Called Java object is not a JavaFunction/n");
        return 0;
    }
    ret = javaEnv->CallIntMethod(*obj, java_function_method,(jlong)L);
    javaEnv->CallVoidMethod(*obj, java_function_method_cleanup);
  ...
   checkLuaStop(L);
}
复制代码

在方法末尾增加个检查退出函数 checkLuaStop(LuaState* L),通过全局标识位forceStop来判断是否需要退出,顺便给Lua脚本一个结束回调,最后才抛出lua_error结束。

FUNC_EXPORT void checkLuaStop(lua_State *L) {
    if (forceStop == 1) {
        /*在用户主动终止脚本运行之前执行的回调函数 */
        LOGE("beforeUserExit");
        lua_getglobal(L, "beforeUserExit");
        lua_call(L, 0, 0);
        lua_pop(L, 1);

        lua_pushstring(L, "lua force close!");
        lua_error(L);
    }
}
复制代码

forceStop的值由自定义注册的forceStop函数控制的。

void jni_forceStop(JNIEnv *env, jobject jobj, jobject cptr) {
    forceStop = 1;
}

jboolean jni_isClosing(JNIEnv *env, jobject jobj, jobject cptr) {
    if (forceStop == 1) {
        return JNI_TRUE;
    } else {
        return JNI_FALSE;
    }
}
复制代码

原文 

https://juejin.im/post/5ec28521f265da496763929d

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 游戏助手-LuaJava框架实现脚本中断的方法

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址