《游戏引擎实现原理》10.1 反射驱动的属性面板
属性面板不该为每个组件手写 UI。本节把卷一第 16 章的反射描述符接进编辑器:从类型描述与实例展开出纯数据的「面板描述模型」——字段名、标签、类型、当前值、只读与枚举候选,不含任何 DOM。该数据模型在本机真跑并有 vitest 用例;DOM 渲染属 L3,需在浏览器中手动验证。
tag
属性面板不该为每个组件手写 UI。本节把卷一第 16 章的反射描述符接进编辑器:从类型描述与实例展开出纯数据的「面板描述模型」——字段名、标签、类型、当前值、只读与枚举候选,不含任何 DOM。该数据模型在本机真跑并有 vitest 用例;DOM 渲染属 L3,需在浏览器中手动验证。
PHP 属性与反射元编程实战:Attribute 语法与声明目标(TARGET_CLASS/METHOD/PROPERTY/PARAMETER)、ReflectionAttribute 读取与 newInstance 实例化、PHP 8.x 内置属性(Override/Deprecated/SensitiveParameter/AllowDynamicProperties)、属性驱动的路由/ORM 映射/参数校验、属性与 Doctrine 注解的对比迁移、反射性能与元数据缓存策略、构建迷你属性驱动框架。
第 16 章的类型描述符在这一节接上序列化器:同一张字段表既能写出可读 JSON,也能写出紧凑二进制。给出 helio 内核里可编译的 TypeRegistry、json-serde 与 binary-serde 三个完整文件与 vitest 用例,并实测同一个 Player 对象 JSON 93 字节、二进制 37 字节。
不用装饰器、不依赖 emitDecoratorMetadata:用一个构建期脚本扫描源码里带标记的类型定义,生成一份显式注册表 .ts 文件,再由运行时 import 进注册表。本节真跑一次扫描,把扫过的文件数、抽出的类型数与属性数、生成的代码行数都写进正文。
从零实现 helio 内核的 TypeRegistry:用 defineType 按字段类型累加偏移,产出名字、类型、偏移、默认值四件套的属性描述符;注册顺序被保留,遍历稳定可复现。本节给出完整可编译实现与 vitest 用例,并真跑一次 registry.get('Vec3').properties,把真实输出贴进正文。
编辑器要列出属性、存档要读写字段、脚本要绑定对象——这三件事都要求引擎在运行时知道「类型里到底有什么」。本节讲清这份类型信息为什么必须有,交代 Node 26 只做类型剥离、装饰器元数据走不通这个硬约束,并把它讲成一个主动的设计选择:显式注册表。
把反射的每一步成本拆到纳秒级:reflect.Value.Call 为何比直接调用慢约一百倍,一次 Method 调用、一次 Field 读取、一次 New 各花多少并分配多少字节;以及为什么 unsafe 的指针重解释是零成本,给出可替代反射的决策清单。
在 C++ 中实现编译期反射与序列化:结构化绑定展开聚合体、宏方案、Boost.PFR 等现成工具,以及与 Protobuf/FlatBuffers/Cap'n Proto 等二进制序列化方案的性能对比与工程选型。
深入 Java 泛型与反射机制:类型擦除与桥方法、PECS 通配符、Type 体系、反射 API 全解析、动态代理与 CGLIB、注解处理与代码生成,以及反射性能优化与安全考量。
全面解析 Go reflect 包的类型系统、接口值内部结构、结构体遍历、方法调用与动态值创建,涵盖高性能缓存、依赖注入与 ORM 映射等实战案例,以及反射与泛型的对比选择策略。