Cocos2dx 3.X jsb加载JavaScript源码文件分析

2024-04-06 03:58

本文主要是介绍Cocos2dx 3.X jsb加载JavaScript源码文件分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Cocos2dx 3.X jsb加载JavaScript源码文件分析:
1、其实js和lua差不多,lua中通过require函数加载lua文件,js中也是通过一个函数require,加载js源码文件,而且思路差不多,那这个函数是如何执行的呢?2、require函数
在ScriptingCore.cpp文件中有个registerDefaultClasses函数,这个函数注册了一些C++ 函数供javascript调用,require就是其中之一:
void registerDefaultClasses(JSContext* cx, JS::HandleObject global) {
………不需要的东西,都去掉了。
// register some global functions
//这里就是重点,注册了一个require函数,实际调用的是/*** run a script from script :)*/static bool executeScript(JSContext *cx, uint32_t argc, jsval *vp);
函数,找到源头,我们可以去看下代码,具体如何实现得了。JS_DefineFunction(cx, global, "require", ScriptingCore::executeScript, 1, JSPROP_READONLY | JSPROP_PERMANENT);//顺便说下这个,这个log如果是jsb可以直接使用,但不能在h5上面使用,所以最好还是使用cc.logJS_DefineFunction(cx, global, "log", ScriptingCore::log, 0, JSPROP_READONLY | JSPROP_PERMANENT);}
3、
//这个函数是我们的重点
bool ScriptingCore::executeScript(JSContext *cx, uint32_t argc, jsval *vp)
{JS::CallArgs args = JS::CallArgsFromVp(argc, vp);//获取参数if (argc >= 1) {JSString* str = JS::ToString(cx, JS::RootedValue(cx, args.get(0)));JSStringWrapper path(str);bool res = false;if (argc == 2 && args.get(1).isString()) {JSString* globalName = args.get(1).toString();JSStringWrapper name(globalName);JS::RootedObject debugObj(cx, ScriptingCore::getInstance()->getDebugGlobal());if (debugObj) {res = ScriptingCore::getInstance()->runScript(path.get(), debugObj);} else {JS_ReportError(cx, "Invalid global object: %s", name.get());return false;}} else {JS::RootedObject glob(cx, JS::CurrentGlobalOrNull(cx));res = ScriptingCore::getInstance()->runScript(path.get(), glob);}return res;}args.rval().setUndefined();return true;
}------》》其实最终都是执行这个path就是我们传进来,也就是想要加载的js文件
ScriptingCore::getInstance()->runScript(path.get(), glob);
4、这个函数就是真正加载的函数:
bool ScriptingCore::runScript(const char *path, JS::HandleObject global, JSContext* cx)
{if (cx == NULL) {cx = _cx;}//进行编译compileScript(path,global,cx);JS::RootedScript script(cx, getScript(path));bool evaluatedOK = false;
if (script) {
//编译完后,就可以调用JS_ExecuteScript函数执行了。JS::RootedValue rval(cx);JSAutoCompartment ac(cx, global);evaluatedOK = JS_ExecuteScript(cx, global, script, &rval);if (false == evaluatedOK) {cocos2d::log("(evaluatedOK == JS_FALSE)");JS_ReportPendingException(cx);}}return evaluatedOK;
}
5、编译函数
void ScriptingCore::compileScript(const char *path, JSObject* global, JSContext* cx)
{if (!path) {return;}if (getScript(path)) { //如果已经编译过,则直接返回,这里有一个缓存
// name ~> JSScript map
static std::unordered_map<std::string, JSScript*> filename_script;return;}cocos2d::FileUtils *futil = cocos2d::FileUtils::getInstance();if (global == NULL) {global = _global.ref().get();}if (cx == NULL) {cx = _cx;}JSAutoCompartment ac(cx, global);JS::RootedScript script(cx);JS::RootedObject obj(cx, global);// a) check jsc file first  //先测试字节码,我们一般把js文件弄成字节码,防止被人使用std::string byteCodePath = RemoveFileExt(std::string(path)) + BYTE_CODE_FILE_EXT;// Check whether '.jsc' files exist to avoid outputing log which says 'couldn't find .jsc file'.if (futil->isFileExist(byteCodePath)){ //如果找到字节码文件,则进行JS_DecodeScript解码Data data = futil->getDataFromFile(byteCodePath);if (!data.isNull()){script = JS_DecodeScript(cx, data.getBytes(), static_cast<uint32_t>(data.getSize()), nullptr);}}// b) no jsc file, check js file, 如果没有jsc字节码文件,则找js文件if (!script){/* Clear any pending exception from previous failed decoding.  */ReportException(cx);std::string fullPath = futil->fullPathForFilename(path);JS::CompileOptions op(cx);op.setUTF8(true);op.setFileAndLine(fullPath.c_str(), 1);bool ok = false;
//这里对不同平台有个不同的处理,主要是存放文件的方式不同,然后调用
JS::Compile编译即可。
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)std::string jsFileContent = futil->getStringFromFile(fullPath);if (!jsFileContent.empty()){ok = JS::Compile(cx, obj, op, jsFileContent.c_str(), jsFileContent.size(), &script);}
#elseok = JS::Compile(cx, obj, op, fullPath.c_str(), &script);
#endifif (ok) {filename_script[fullPath] = script;}}else {filename_script[byteCodePath] = script;}
}

这篇关于Cocos2dx 3.X jsb加载JavaScript源码文件分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/878939

相关文章

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

Springboot项目启动失败提示找不到dao类的解决

《Springboot项目启动失败提示找不到dao类的解决》SpringBoot启动失败,因ProductServiceImpl未正确注入ProductDao,原因:Dao未注册为Bean,解决:在启... 目录错误描述原因解决方法总结***************************APPLICA编

深度解析Spring Security 中的 SecurityFilterChain核心功能

《深度解析SpringSecurity中的SecurityFilterChain核心功能》SecurityFilterChain通过组件化配置、类型安全路径匹配、多链协同三大特性,重构了Spri... 目录Spring Security 中的SecurityFilterChain深度解析一、Security