【Creator】简单分割 Creator 生成的代码

简单分割 Creator 生成的代码

在这篇文章中,我们将详细解析一段用于解析 Cocos Creator 生成代码的 JavaScript 代码。我们会逐步讲解这段代码的每个部分,帮助大家理解其背后的逻辑。

初始化函数与变量

const functionPattern = ':[function(';
const codeBlockStart = '{';
const metadataPattern = 'cc._RF.push(';

这段代码初始化了三个变量,用于在代码字符串中查找特定的标记:

  • functionPattern:表示函数定义的起始位置。
  • codeBlockStart:表示代码块的开始标记。
  • metadataPattern:用于查找元数据的标记。

定位函数定义

const functionIndex = code.indexOf(functionPattern);
if (functionIndex === -1) {
    console.log('代码解析结束');
    return null;
}

通过 indexOf 方法查找 functionPattern 在代码中的位置,functionIndex 表示模块函数定义的起始位置。如果没有找到,解析过程将终止。

提取模块名

const splitIndex = code.lastIndexOf(',', functionIndex);
if (splitIndex === -1) {
    console.log('未找到起始的 ","');
    return null;
}

let moduleName = code.substring(splitIndex + 1, functionIndex);
moduleName = moduleName.replace(/"/g, '');
console.log("模块名称 = ", moduleName);

在找到函数定义位置后,代码通过 lastIndexOf 方法查找最靠近的逗号,并提取其中的字符串作为模块名。随后,去掉模块名中的引号,以便后续使用。

处理严格模式

const strictModeIndex = code.indexOf(codeBlockStart);
if (strictModeIndex === -1) {
    console.log('未找到起始的严格模式代码');
    return null;
}

通过查找代码块开始标记 codeBlockStart,定位严格模式代码块的位置。如果没有找到该标记,说明代码结构不符合预期,解析过程将结束。

解析函数参数

let functionArgs = code.substring(functionIndex + functionPattern.length, code.indexOf(")"));
let argArray = functionArgs.split(",");

this.classes[moduleName] = "";
if (argArray.length >= 3) {
    this.classes[moduleName] = `let ${argArray[0]} = require;\nlet ${argArray[1]} = module;\nlet ${argArray[2]} = exports;\n`;
} else if (argArray.length >= 2) {
    this.classes[moduleName] = `let ${argArray[0]} = require;\nlet ${argArray[1]} = module;\n`;
} else if (argArray.length >= 1 && argArray[0].length > 0) {
    this.classes[moduleName] = `let ${argArray[0]} = require;\n`;
}

这部分代码解析模块的函数参数,并根据参数的数量生成相应的 requiremoduleexports 代码。这样做的目的是为了在解析后的代码中保留模块依赖的引用。

查找下一个函数定义

code = code.substring(strictModeIndex + 1);
let nextFunctionIndex = code.indexOf(functionPattern);
if (nextFunctionIndex === -1) {
    nextFunctionIndex = code.length;
} else {
    nextFunctionIndex = code.lastIndexOf(',', nextFunctionIndex);
    if (nextFunctionIndex === -1) {
        console.log('未找到下一个 ","');
        return null;
    }
}

在处理完当前模块后,代码会继续查找下一个函数定义的起始位置。如果找到了下一个函数定义,则继续分割代码块;如果没有找到,说明代码解析已经完成。

提取当前代码块

let currentCodeBlock = code.substring(0, nextFunctionIndex);
const codeSeparator = "},{";
const codeEndIndex = currentCodeBlock.lastIndexOf(codeSeparator);
if (codeEndIndex === -1) {
    console.log('代码分割失败 "},{"');
    return null;
}

this.classes[moduleName] += currentCodeBlock.substring(0, codeEndIndex);

这段代码负责提取当前代码块的内容,并使用分隔符 },{ 将代码块进行分割,确保只提取有用的代码部分。

元数据解析

let metaIndex = this.classes[moduleName].indexOf(metadataPattern);
if (metaIndex != -1) {
    let metaString = this.classes[moduleName].substring(metaIndex + metadataPattern.length);
    let metaEndIndex = metaString.indexOf(")");
    metaString = metaString.substring(0, metaEndIndex);
    let metaArray = metaString.split(",");
    this.metaMap[moduleName] = UuidUtils.decompressUuid(metaArray[1].replace(/"/g, ''));
}

通过查找 metadataPattern,代码可以提取并解析元数据。元数据通常包含 UUID 信息,代码会解压并存储这些 UUID 信息,方便后续使用。

递归解析剩余代码

code = code.substring(nextFunctionIndex);
this.parseCreatorCode(code);

代码递归调用自身,继续解析剩余的代码块,直到所有代码都被解析完成。

导入项目并运行

最后,将导出的代码与meta文件导入creator工程,运行项目调试。


2 学习与交流
  • 欢迎加 qq 985251414,一起学习与交流!
  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值