GPU PRO 4 - 5.1 An Aspect-Based Engine Architecture 笔记

本笔记仅为个人的理解,如果有误欢迎指出

An Aspect-Based Engine Architecture 一种基于方面的引擎架构

        不是很明白为什么GPU的书籍会有游戏引擎架构的文章。

        这里Aspect在文章中的意义更像是表述一个功能模块,在Java中有将Aspect翻译成切面,但是Java切面主要是横向的代码注入,与本文的概念不相符。

大多数系统架构都会考虑将各个功能封装成模块或者组件,在面向对象编程的思想下,这个封装是基于对象去实现的,本文则描述了一种在引擎层面的封装功能的架构思想,封装后的产物被称为Aspect,每一个Aspect负责提供一些功能子集,并通过一个通用的接口与引擎核心通信。

引擎核心:

        引擎核心的功能是保存游戏或者仿真时的数据结构以及相关状态,功能Aspect将会与这些数据进行交互。一般来说引擎核心会定义一些接口,外部的Aspect则通过接口访问当前的游戏数据

        

        用MVC架构的角度去理解的话引擎核心相当于M层,而各个Aspect则相当于C层。

        
        场景图、场景节点:

                与市面上大多数的引擎类似,游戏和仿真环境都抽象成场景概念,交互的数据都以树形的场景节点整合

        

        有虚幻,Unity等引擎经验的人都很熟悉,这就类似里面的场景以及节点,而Aspect则会处理这些数据。但是Node的结构文章中有特别说明,Node在这里设计的思路不是编程里习惯的想法用一个类来表示,在后面的内容中解释了Node的结构应该是一个Map或者Set容器的实例,这里的想法有点像Unity中面向数据的技术栈 (DOTS),这里则将类成员以及相关的值都转化到Map上。

        数据访问:

       用这种聚合的方式实现Node一个影响是没有一个直接访问Node内指定数据的结构,因此访问数据需要通过请求来完成,通过查询Node里面的内容并整合出一个访问接口让Aspect去处理。在多线程的环境下还需要通过添加锁来处理冲突问题,但一般是通过复制相关的数据到Aspect内部去处理

        其他的还有事件系统,这是耳熟能详的基本功能,这里不再赘述。

方面(Aspects):

        Aspect这个概念是这篇文章的核心。

        引擎核心存储着数据当前的状态以及发生的任何变更,核心不关心游戏的具体内容或是运作方式。这些操作都交由Aspect去处理。

        每个Aspect都是一个引擎的功能模块,他可能包括渲染、动画、物理、音频、甚至是游戏运行逻辑。每个Aspect都可以封装着第三方引擎、框架或者API。

        Aspect之间不应该有相互调用,这样会造成Aspect之间产生耦合与依赖,破坏了Aspect的封闭性。这就是简单的分层思想,同层的模块之间不能有任何联系,如果实在要跨Aspect协作,那这应该要放到上层或者在引擎核心处理。

        设计Aspect的时候应该避免一些类似当前的图形设备/上下文或窗口句柄之类的静态资源的共享,如果这些共享无法避免,则应该控制好访问的顺序,比如互斥锁之类的。  

        在这篇文章中Aspect要做到的是能够独立运行,所以才更容易维护与替换,所以每个Aspect都可以独立开发和测试,并通过引擎核心来互相交互,

        引擎则会通过一个单一的接口来管理所有的Aspect的生命周期,初始化、更新、关闭等

        

        场景解释(Scene Interpretation):

        这个概念比较抽象,按我的理解这个小节的主要作用是想说Aspect如何去处理场景里面的数据。

        每个Aspect都会维护一个内部结构,管理他所关注的Node。一般来说Aspect会查询Node上的一些属性值来去确定哪些Node是需要他去处理的,这部分应该是在下一节【节点接口】里面解释。比如物理Aspect则会处理每个Node里面刚体相关的数据,渲染Aspect则会处理节点里面关于网格材质相关的数据。

        当一个Aspect被注册到引擎上后,它会遍历所有场景图里面的Node,把Aspect所关注的Node收集到Aspect的内部里,后面Node上的变更事件则会通知到这个Aspect,以此同步自身的内部结构。

        

        节点接口(Node Interfaces):

        这个节点接口理解的不是透彻

        个人理解的是每个Aspect都会定义一个Interface用来给引擎核心判断当前Node是否符合Aspect这边的要求,同时Aspect也会用这个接口去同步数据到引擎核心侧

        

实现:

        这个引擎架构的一个关键原则是Node不是一个实例化的类而是一个容器,文章给的示例如下:

        

        通过这种Map的形式将Node的成员属性以及相关数据的实例化关联起来

        对应的属性接口类则是如下设计:

方面的更新:

        方面执行相关逻辑的时候会先向引擎申请锁以确保不会出现脏数据的情况,对于数据访问的管理引擎核心则是通过锁来完成,每次Aspect处理完数据后都要将锁交还给核心。

        

例子:受到物体受到伤害时改变颜色

        假如子弹击中游戏中的一个角色并导致目标的材质值改变时可能发生的一系列操作:

        1,在物理方面的更新过程中,子弹与角色的相交被检测到,这里便会生成一个事件并推送到事件队列中。完成这些操作后同步数据到引擎核心。

        2,逻辑方面更新的时候,在事件队列里获得了碰撞事件,并调用子弹和角色的碰撞事件处理脚本函数,并更新相关的相关数据,比如生命值,颜色属性,子弹还会从当前场景中被移除。完成这些操作后同步数据到引擎核心。

        3,渲染方面更新的时候,则按照当前的数据渲染出物体

        目前这个面向方面思想设计的引擎实现的有Cohort Studios’ proprietary engine。

分析:

        与所有设计一样,基于方面构建引擎有其优势和局限性。基于方面的架构将各个功能模块化,这有益于开发过程,但其僵化的结构和间接访问方式也对效率产生了限制。

优势:基于方面构建引擎的优势包括:

  • 提倡数据驱动的开发理念,有助于吸引资产创作者和设计师参与。
  • 高度模块化的即插即用架构允许对引擎进行快速更改。
  • 模块化特性有助于更快地追踪和调试错误。
  • 封装加速了第三方API的集成。
  • 着色器和脚本输入的直连使得开发新图形技术和原型游戏功能更容易、更快速。
  • 功能知识和管理的去中心化让开发有更多的操作空间。

局限性: 以下是一些局限性:

  • 在各个方面内部创建重复或冗余数据,以及在核心中存储数据所使用的聚合结构,可能会显著降低内存效率。
  • 方面的异步特性可能使程序员难以处理,因为因果关系在代码中很少直接相邻。
  • 试图在多个执行线程上的各个方面之间保持完全自主,需要额外的机制来协调更新顺序。

  个人总结:

        本文更像是讲述的一种在数据高度集中的情况下如何将各个功能在引擎层面中封装成模块,这种引擎的特点就是数据被管理到引擎核心中,功能模块化后对于引擎的修改会更加方便,因为只需要关注当前模块的功能即可。

        这边文章个人觉得核心想法的理解难度不高,涉及的技术难点也不多,主要是各个概念的定义让人摸不着头脑。

参考链接:

【什么是面向切面编程AOP? - 欲眼熊猫的回答 - 知乎】

【在Unity中简单使用AOP为方法添加自定义属性】

【DOTS 技术深度解析】

Read more

Flutter 与 Web 混合开发:跨平台的完美融合

Flutter 与 Web 混合开发:跨平台的完美融合

Flutter 与 Web 混合开发:跨平台的完美融合 写在前面 今天想和你聊聊一个让跨平台开发更具可能性的话题——Flutter 与 Web 混合开发。在我眼里,Flutter 就像一位多才多艺的艺术家,既能在移动平台上展现精彩,也能在 Web 世界中绽放光芒。 Flutter Web 的崛起 Flutter Web 是 Flutter 的一个重要方向,它允许我们使用同一套代码库构建运行在浏览器中的应用。随着 Flutter 3.0 的发布,Flutter Web 的性能和稳定性得到了显著提升,为混合开发开辟了新的可能。 Flutter Web 的优势 1. 代码复用:使用同一套代码库构建移动应用和 Web 应用,减少开发和维护成本 2. 一致的用户体验:在不同平台上提供一致的视觉和交互体验 3. 高性能:

一键拯救大模型的前端审美能力 - 使用Frontend-Design Skill提升AI设计水平

# 一键拯救大模型的前端审美能力 ## 前言 目前,在不额外给风格规范/设计系统/示例参考的情况下,拥有前端审美能力的编程模型只有4款: - Gemini 3 Pro - Gemini 3 Flash   - Claude Opus 4.5 - Claude Sonnet 4.5 当我们看到GPT-5.2-Codex等明明其他方面都很厉害,但是唯独前端审美不行的模型时,常常感叹"哀其不幸、怒其不争"。那么,是否有快速提升他们前端审美能力的方法呢? 答案是:**使用 Anthropic 官方提供的 frontend-design skill** ## 什么是 Frontend-Design Skill? Frontend-Design Skill 是 Anthropic 官方提供的一款技能包,可以为所有主流编程大模型(

前端大文件分片上传实现与断点续传方案(含完整代码讲解)

在上传大文件(如视频、安装包、模型文件)时,直接上传容易出现以下问题: * 文件过大 → 浏览器/服务器容易超时 * 上传过程中断 → 重新上传浪费时间 * 网络波动 → 上传失败率高 因此,大文件分片上传 + 断点续传 + 秒传校验 是目前最通用、最稳定的解决方案。 本文将通过一段完整可运行的示例代码,详细讲解如何在前端实现分片上传、断点续传、服务端校验等关键功能。 ✨ 实现效果 * ✔ 自动切片(默认 5MB/片,可配置) * ✔ 查询已上传分片(断点续传) * ✔ 自动跳过已上传的片段 * ✔ 每片上传成功后重新校验 * ✔ 所有片段上传完成后自动触发合并 * ✔ 错误处理完善 📌 核心代码(uploadLargeFile) 以下代码就是本文的核心逻辑,也是你提供的代码版本,经过梳理解释后会更易理解: export async function uploadLargeFile({ file, fileId, id, chunkSize = 5 * 1024

Spring Boot 3.x开发中CSP(内容安全策略)配置导致前端资源加载失败问题详解及解决方案

目录 * Spring Boot 3.x开发中CSP(内容安全策略)配置导致前端资源加载失败问题详解及解决方案 * 引言 * 1. 问题表现:CSP拦截的典型症状 * 2. 原因分析:CSP指令与Spring Boot配置 * 2.1 CSP指令概览 * 2.2 Spring Boot 3.x 中配置CSP的方式 * 2.3 常见的配置失误 * 3. 解决方案:从诊断到修复的完整步骤 * 3.1 步骤一:查看浏览器控制台错误 * 3.2 步骤二:整理资源来源清单 * 3.3 步骤三:调整CSP策略 * 3.3.1 允许外部域名 * 3.3.2