现有数据管理、读取、打包代码的改进
首先,我希望游戏中数据可以不光使用excel来制作、保存。
我们目前的问题,可以优化的地方有两个:
1.每种数据类型的管理器,都放在总管理器里面,作为一个成员变量,使用的时候,从总管理器里面直接拿指针。
这里就存在一个问题,既然作为成员变量,新添加数据管理器,就会修改总管理器的头文件,然后所有使用管理器的地方,都需要重新编译。
如果将管理器存放在一个容器里面,然后在初始化的地方动态添加,只要加一个查询接口,就不用在新添加管理器的时候,重新编译其他的依赖数据管理器的文件了。
这里的进步是减少重新编译的时间,折中就是从o(1)的时间变为o(logn)的时间,我认为这个是优化,并且没有什么性能损失和代码优雅方面的损失,反而我觉得比之前的实现更优雅。
2.每种数据打包之后,管理器不知道数据的size,要代码里面手动填写,比如itemDataManager.Reserve(1000);类似的代码,当打包的数据超过1000个,后面的数据就读取不到了。
这个简单的修改打包文件的格式,前面加入后面所有数据的个数,就ok了。
加入一个itemDataManager要对应3个打包后的文件呢?比如:item.dat, shopitem.dat, specialitem.dat(他们都是从excel转成2进制的)。这样就不能使用其中的任何一个,作为itemDataManager的总大小。
姑且不管一个manager对应若干打包后的文件是否合理,上面的问题,完全可以解决。假设.dat文件的header部分,存储了他们数据的大小,代码只要这样实现:
itemDataManager.AddData(item.dat);
itemDataManager.AddData(shopitem.dat);
itemDataManager.AddData(specialitem.dat);
itemDataManager.LoadData();
每个AddData()实现里面,都取出.dat文件的size,并且加到自己的total_reserve_size_里面,然后在LoadData()里面,一次分配足够的空间即可。上面的问题就都解决了。
DataManager::AddData(file_name) {//getDataSize从.dat文件头里面读取数据总量
int data_in_file = getDataSize(file_name);
total_reserve_size_ += data_in_file;
}DataManager::LoadData() {//这里分配足够的空间即可。Reserve(total_reserve_size_);}
经过上面的修改,还是可以保证数据管理器一次分配连续的大小,然后可以使用index这种o(1)的时间来取数据,也避免了硬编码数据大小的问题。
上面的改动,应该都不伤筋动骨。我走的更远一些,说一下我的其他想法。
上面的实现,需要每一个数据管理器,实现基类的接口,然后实现数据的二进制的序列化功能,这样可以在读取的时候,有最快的速度保障。
但是,不是所有的数据,都对加载时间有这么高的要求,一些小型的数据,加载速度也不是瓶颈的情况,能不能提供一个默认的序列化机制,提供一些键值对的读取。
这样一些数据,就不需要写额外的管理器代码,只要在编码的时候使用:
DataManager::GetData(id, column_name);或者DataManager::GetData(id, char* out_buffer, int &out_size);之类的。
当然,这样的使用方法,对于像item这样的大型数据集,效率是无法保证的,但是对于其他一些简单的数据,也不是不可以考虑。
当然,如果简单数据使用LUA,Json,等,可能连自己的打包和序列化代码都不用写了。
最后跑题了一下子,说了数据的灵活性,一开始的目的就是说,代码如何实现,对于使用起来的效率来讲,也是会有很大的差别的。
要睡觉了,就写这么多了,各位晚安。