跳转到内容

标签系统

标签系统是 cfggen 提供的一种灵活的数据筛选机制,用于在代码生成过程中选择性提取配置数据。通过为数据表、结构体和字段添加标签,可以精确控制哪些数据需要被包含在生成的代码中。

  • 标签 (Tag): 在配置文件中定义的标识符,用于标记特定的数据元素
  • 白名单模式: 只包含带有指定标签的数据
  • 黑名单模式: 排除带有指定标签的数据
  • 应用场景:
    • 客户端只需要部分数据以减少内存占用
    • 编辑器工具只需要特定字段
    • 服务器端排除敏感或不必要的数据

通过命令行参数可以限制读取的目录范围:

  • -exceldirs: 指定读取的 Excel 目录
  • -jsondirs: 指定读取的 JSON 目录

详细说明请参考 文件和目录结构 - 高级功能 一节。

使用 -gen 命令的 own 参数配合标签来实现白名单筛选:

Terminal window
-gen lua,own:client

此命令只会提取标记了 client 标签的数据。

在数据表、结构体和字段上可以配置任意标签,通常使用 client(或更简洁的 c)来标记客户端需要的数据。

  • 在字段上标注标签即可,无需标注外键
  • 外键是否被提取取决于是否可行,能包含就包含
  1. 所有字段无标签,表有标签:包含所有字段

    table task[id] (client){
    id:int;
    desc:text;
    }
  2. 部分字段有标签:只包含设置了标签的字段

    table task[id] { // 可以不加(client),因为有字段加了(client)
    id:int (client);
    desc:text (client);
    reward:Reward;
    }
  3. 字段使用负标签:提取未设置负标签的字段

    table task[id] (client){
    id:int;
    desc:text;
    reward:Reward(-client);
    }
  • 一般情况下,实现类不需要设置标签
  • 如果在实现类上设置标签,目的是为了能够筛选出空结构
  • 普通结构体不支持筛选出空结构

假设有一个技能动作接口,服务端需要完整的动作数据,但客户端只需要知道动作类型,不需要具体数据:

interface action (client) {
struct attack {
damage:int;
critRate:int;
}
struct heal {
amount:int;
range:int;
}
struct buff {
icon:int ->res.icon;
buffId:int;
duration:int;
}
struct run {
footstepSound:int ->res.sound;
speed:float;
}
struct sfx {
sfx:int ->res.sfx;
}
}

上面的配置会为客户端生成包含所有字段的 attackhealbuffrunsfx 实现类。但如果客户端只需要类型标识和资源相关字段,不需要数据,可以这样做:

interface action (client) {
struct attack (client) { // impl上设置tag,表示只保留空结构
damage:int;
critRate:int;
}
struct heal (client) {
amount:int;
range:int;
}
struct buff {
icon:int ->res.icon (client);
buffId:int;
duration:int;
}
struct run {
footstepSound:int ->res.sound;
speed:float (-client);
}
struct sfx {
sfx:int ->res.sfx;
}
}

使用 -gen lua,own:client 生成后:

  • attackheal 会被保留,但字段被过滤,变成空结构(只有类名)
  • buff 则只包含icon
  • run 则只包含footstepSound
  • sfx 则完全保留

等价于

interface action {
struct attack {
}
struct heal {
}
struct buff {
icon:int ->res.icon
}
struct run {
footstepSound:int ->res.sound;
}
struct sfx {
sfx:int ->res.sfx;
}
}

这种设计使得客户端可以用 action 类型来区分技能动作类型,同时大幅减少内存占用。

使用负标签实现黑名单模式:

Terminal window
-gen java,own:-noserver

此命令会忽略所有标记了 noserver 标签的数据。

在表、结构体或接口上设置 noserver 标签,则完全排除该表:

table avatar[id] (noserver){
id:int;
path:str;
}

在字段上设置 noserver 标签,只排除该特定字段:

table task[id]{
id:int;
desc:text (noserver);
reward:Reward;
}
  1. 标签命名规范: 使用有意义的标签名称,如 clientservereditor
  2. 一致性: 在整个项目中保持标签使用的一致性
  3. 文档化: 在项目文档中记录使用的标签及其含义
  4. 测试验证: 生成代码后验证标签筛选是否正确工作

通过合理使用标签系统,可以实现灵活的数据分发策略,优化不同平台的内存使用和性能表现。