游戏引擎开发总结:序列化系统

news2025/3/1 15:53:29
序列化需要准备什么?

首先,我们需要一个被序列化类实现序列化函数,以及序列化库。准备我的序列化库是Yaml-cpp,序列话函数就命名为Serialize,另外我们不需要关心组件类型是具体是什么,所以我这边使用多态,接口类为

struct Serializer{
    virtual void Serialize() = 0; 
}

所有需要运行时序列化的类都实现接口;

另外当我们给定一个Carrier[Ecs系统中Enttity]时,我们需要知道这个实体的那些类实现了这个接口:

这边的话,我们可以在调用Carrier.AddComponent时用标准库type_traits中的std::is_base_of_v<base,T>方法来判断。那么这张表被谁持有呢?这边我是让Sence类型持有,原因如下:

1:每一个Sence的Carrier都应该被隔离,所以Serializable也应该被隔离,Sence的资源不应该交付给其他类托管;

2:方便管理

另外表的键值是组件名字的字符串;

看实现:

另外反序列话有点不同,序列话是类的数据流向文件,我们是知道组件类型的,但是反序列化是数据从文件流向组件,我们是不知道类类型,如果要调用成员函数的话,会比较复杂,所以我这边是用类静态成员,输入是Carrier和数据节点;

实现:

另外,怎么知道让哪个类调用哪个反序列化方法呢?或者说我们用什么数据将其与函数关联起来;

这边我选择的是用一张unordered_map<std::string,std::function<void(YAML::Node&,Carrier&)>>表,我们只需要在序列化的时候将类名字符串与数据对应起来,然后反序列化的时候取出节点中的对应数据即可;

接下来的问题是,我们怎么准备这张表?或者说,我们怎么在引擎loop运行前准备这张表,因为这张表是我们loop时随时可调用的;

有一个方法是硬编码,直接在邀请运行前增加unordered_map::emplace方法,但是...这太蠢了,硬编码一向不是我的风格;

我这边是利用了inline static变量会在运行main函数的第一段代码前都初始化好的特性,这意味这我们可以在引擎运行前就运行一些代码,而且这些代码是可以分布在不同类中的,这为我们软初始化表提供了可能;

我这边是定义了一个类,这种运行引擎前的做初始化的工具类我统称为Assistant类:

    template<class T>
    struct SerializeAssistant {
        SerializeAssistant(::std::string name, std::function<void(YAML::Node& node, Carrier& carrier)> deSerializerFun) {
            if constexpr (std::is_base_of_v<Serializable, T>)
                SenceSerializer::GetDeserializerFunMap().emplace(name, deSerializerFun);
            else
                LC_CORE_ASSERT(false, "Serializable permission needs to be added");

        }
    };

这边为什么是个模板,这个是另外一个组件依赖的系统,我称之为权限系统,作用是规范代码,这里不做介绍;

那么这张表被谁持有呢?当然不能被Sence持有,因为Sence不是唯一的,但是表是唯一的,被因为不是Carrier的属性,所以不能被Sence持有,这边我是让Serializer类持有;

我这边定义了一个宏:

#define COMPONENTREGISTER(ClassName) inline static DynamicEmbedAssistant<ClassName> DynamicEmbedAss{#ClassName,&ClassName::OnEmbed};

在类完善这个宏可以将该类中的反序列花函数登记到Serializer中所持有的表中;

到此为止,我们已经有两张表了,一张是运行时可动态增删的表,里面存储着每一个Carrier持有的可序列化组件指针,另外一张表是运行时确定的表,里面存储着每一个组件的反序列化函数;

大概的序列化步骤是这样的:

另外还有一张小表需要维护,那就是每一个Carrier持有的组件的类名字符串,这张表也会被流向文件当中,在反序列化时会被作为索引,指定对应的Carrier需要调用那些反序列化函数

准备前工作:将每个组件的反序列化函数登记;

运行时工作:当一个Carrier增加一个组件,我们需要判断这个组件是否实现了Serializable接口,如果实现了,那么在Sence的序列化指针表中增加对应的指针

序列化:

1:实例化一个接受数据的emitter

2:便利Scene中的每一个Carrier,调用该Carrier中的所有的序列化指针,其会将组件进行序列化;

3:将序列化好的数据流向文件

反序类化:

1:实例化一个新的Scene,并提供对应的数据

2:提取小表节点,遍历每一个Carrier需要调用那些反序列话函数,并将数据数据节点和Carrier传入反序列化函数,向Carrier中流入数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/404795.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring和MaBatis整合

Spring和MyBatis整合&#xff1a; 先瞅一眼各种文件路径&#xff1a; 将之前mybatis中的测试类中的SqlSessionFactory&#xff08;通过其openSession()来获得对象SqlSession&#xff09;&#xff0c;和Mybatis配置文件中的数据源&#xff08;url&#xff0c;username等&#…

【Java爬虫】HttpClient+Jsoup实现爬取校内新闻

警告网络爬虫作为一门技术&#xff0c;在使用过程中&#xff0c;应该遵守Robots协议。采集数据时应注意礼貌&#xff0c;不允许爬的网站尽量不要短时间大频率爬取&#xff0c;涉及hdd的网站更是不要去满足自己的好奇心&#xff0c;不然说不准哪天就和吴签一起吃大碗宽面了...介…

[洛谷-P2585][ZJOI2006]三色二叉树(树形DP+状态机DP)

[洛谷-P2585][ZJOI2006]三色二叉树&#xff08;树形DP状态机DP&#xff09;一、题目题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示数据规模与约定二、分析1、递归建树2、树形DP 状态机DP&#xff08;1&#xff09;状态表示&#xff08;2&#xff09;状态转移三、…

C++11异步编程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言1、std::future和std::shared_future1.1 std:future1.2 std::shared_future2、std::async3、std::promise4、std::packaged_task前言 C11提供了异步操作相关的类…

Vue3电商项目实战-结算支付 2【03-结算-对话框组件封装、04-结算-收货地址-切换】

文章目录03-结算-对话框组件封装04-结算-收货地址-切换03-结算-对话框组件封装 目的&#xff1a;实现一个对话框组件可设置标题&#xff0c;动态插入内容&#xff0c;动态插入底部操作按钮&#xff0c;打开关闭功能。 大致步骤&#xff1a; 参照xtx-confirm定义一个基础布局实…

MFC常用控件使用(文本框、编辑框、下拉框、列表控件、树控件)

简介 本文章主要介绍下MFC常用控件的使用&#xff0c;包括静态文本框(Static Text)、编辑框(Edit Control)、下拉框(Combo Box)、列表控件(List Control)、树控件(Tree Control)的使用。 创建项目 我们选择 文件->新建->新建项目&#xff0c;选择MFC程序 选择基于对话…

二叉树的三种遍历

二叉树的遍历可以有&#xff1a;先序遍历、中序遍历、后序遍历先序遍历&#xff1a;根、左子树&#xff0c;右子树中序遍历&#xff1a;左子树、根、右子树后序遍历&#xff1a;左子树、右子树、根下面是我画图理解三种遍历&#xff1a;二叉树里都是分为左子树和右子树。分治思…

Linux文件基础I/O

文件IO文件的常识基础IO为什么要学习操作系统的文件操作C语言对于函数接口的使用接口函数介绍如何理解文件文件描述符重定向更新给模拟实现的shell增加重定向功能为什么linux下一切皆文件&#xff1f;缓冲区为什么要有缓冲区缓冲区对应的刷新策略缓冲区的位置在哪里文件的常识 …

VSCode:添加SSH远程连接

有的时候我们的代码保存于远程服务器&#xff0c;通过VSCode可以通过SSH进行连接&#xff0c;完成远程的编辑。在VSCode的扩展中安装Remote - SSH点击左侧工具栏的远程资源管理器&#xff0c;然后点加号输入ssh的机器及用户名选择一个用于保存ssh配置文件的路径&#xff0c;默认…

Tabs Studio 5.3.0 多功能标签 Crack

在 Visual Studio 2022 和 SQL Server Management Studio 中轻松处理任意数量和类型的文档 你爱写代码&#xff0c;不会好好扫描文档找到你需要切换到的文件名&#xff0c;然后扫描文件菜单下拉列表&#xff0c;然后求助于解决方案资源管理器或搜索。只有在您需要切换到另一个…

javascript入门基础

目录 前言 引入&#xff1a;html中嵌入javascript有三种方式 0. 变量&#xff08;var、let&#xff09; 1. 函数 1.1 普通函数 和 箭头函数 1.1.2 普通函数中的this 1.1.3 箭头函数没有自己的this 1.1.4 普通函数有arguments方法&#xff0c;箭头函数没有 1.1.5 箭头函…

MS python学习(9)

开始学习第二辑 more python for beginners talking about formating https://learn.microsoft.com/en-us/shows/more-python-for-beginners/formatting-and-linting–more-python-for-beginners-2-of-20 Formating 代码格式化&#xff1a;使用pylint工具来帮助遵循PEP8(pyt…

conda创建一个地理开发环境

conda创建一个地理开发环境1. 环境内包说明2. 创建yml文件3. 创建地理开发环境使用conda安装包的时候&#xff0c;经常遇到包之间相互冲突。为了方便配置环境&#xff0c;测试了常用的地理开发所需要的各种包&#xff0c;生成了yml文件方便一键安装。 Linux下pip基本可以成功安…

手敲Mybatis(七)-细化xml语句解析和构建

前言为什么这一章节要细分之前的解析xml处理逻辑&#xff0c;原因是违反了单一原则设计&#xff0c;职责并不明确&#xff0c;将Sql语句、参数、返回值等等一切都进行解析&#xff0c;那么这种的需要拆开&#xff0c;为了后面可维护可扩展&#xff0c;例如Mapper级别的有mapper…

k8s client-go源码解析之informer三

Informer&#xff08;三&#xff09; 注意&#xff1a;本文内容为学习笔记&#xff0c;内容为个人见解&#xff0c;不保证准确性&#xff0c;但欢迎大家讨论何指教。 觉得文章不错请关注跟博客及github 本篇介绍DeltaFIFO及indexer。 informer大致工作流程如下&#xff1a; …

顺序表来喏!!!

前言&#xff1a;还记得前面的文章&#xff1a;《通讯录的实现》吗&#xff1f;通讯录的完成就借助了顺序表这种数据结构&#xff01;&#xff01;&#xff01;那么今天我们就来介绍我们的顺序表介绍顺序表前&#xff0c;我们来了解一下线性表的概念线性表&#xff1a;线性表&a…

mysql笔试题18道

部门表、员工表、薪水等级表 1.取得每个部门最高薪水人员名称 第一步&#xff1a;取得每个部门最高薪水作为临时表t select deptno,max(sal) as maxSal from emp group by deptno 第二步&#xff1a;临时表t与emp表连接条件 e.deptnot.deptno and e.salt.maxSal select …

Spring - Spring IoC 容器相关面试题总结

文章目录01. Spring IoC 和依赖注入是什么&#xff1f;02. Spring IoC 的优点和缺点分别是什么&#xff1f;03. Spring IoC 有什么作用和功能&#xff1f;04. Spring 依赖注入的方式&#xff1f;05. Spring 构造器注入和 setter 方法注入的区别&#xff1f;06. Spring 依赖注入…

嵌入式系统实验——【玄武F103开发板】按key1熄灭两个LED灯、松开恢复点亮

这里写目录标题一、任务目标&#xff08;一&#xff09;分析二、设计思路&#xff08;一&#xff09;开启KEY1对应的GPIOx时钟1.找到KEY1&#xff08;PE3&#xff09;所在的GPIOx端口2.开启GPIOE端口时钟3.清空PE3的端口位4.设置PE3的端口位为输出模式的上拉模式5.一个易错点&a…

二分——力扣篇

二分——力扣篇搜索旋转排序数组搜索旋转排序数组II寻找旋转排序数组中的最小值寻找旋转排序数组中的最小值II搜索旋转排序数组 定理一&#xff1a;只有在顺序区间内才可以通过区间两端的数值判断target是否在其中。 定理二&#xff1a;判断顺序区间还是乱序区间&#xff0c;只…