TA的每日心情 | 慵懒 2015-1-8 08:46 |
---|
签到天数: 2 天 连续签到: 1 天 [LV.1]测试小兵
|
由于游戏设计的需要,在游戏中需要表现出不同武器的样式,于是决定武器有必要作为一个单独的对象出现。于是决定用XXManager的形式来管理所有的Weapon对象,这种设计没有问题,基本上是用的很泛滥的一种方法。但武器类是个大对象,new和delete它都是一个十分昂贵的操作。但游戏中装备的换上换下却是十分频繁的一件事情。如果不加控制的在WeaponManager中创建和销毁,将给游戏带来极大的负担
因此WeaponManager必须有必要的管理策略才行,所以采用一种回收站的策略即可以减轻这种频繁创建的问题。
当然如果采取Manager的形式,必然我们会有这样一个表
std::map<Ogre::String, Weapon*> m_WeaponList;
这和我们平常的设计并没有太大区别,把new出来的加入表中,把delete的从表中移除,如果要加入缓冲策略,我们必须加入类似回收站一样的一个东西。即我们加入下面一个表
std::list<Weapon*> m_RecycleWeaponList;
这就是我们的回收站,当WeaponManager通知deleteWeapon的时候,并不是直接把weapon删除掉,而是把Weapon指针直接丢到回收站里面,当然我们的回收站还是有容量的,当大于限定容量的就会把最尾部的那个Weapon真正的删除掉哦。
PS: 尾部就是我们最少使用的那个Weapon,垃圾回收中有个算法,就是当一个对象最近被使用,那么它再次被使用的概率一定比较大
同样的,在我们createWeapon的时候,我们要做的第一件事情就是在回收站里面去找有没有我们需要的武器,如果有的话我们直接将那个指针从回收站中拿出来,放到武器列表中(m_WeaponList)并把从回收站捡来的Weapon的名字改成新创建的名字,并把Weapon指针返回给用户,这一系列的操作对于用户是透明,他并不知道你内部在怎么运作在。
可能出现FATAL BUG
如果不注意可能会出现非常严重的问题,假设现在一种情况,当用户以"abc"为名字创建一个Weapon后,然后通知WeaponManager删除"abc"这个武器,在通知删除这个武器之后,可能出现一个用户觉得删除abc这个Weapon后,abc这个名字就变得再次可用了。但事实上这个名字为abc的Weapon只是被移到了回收站中了。当用户再使用abc创建新weapon有可能就和回收站里面的重复了,这时候BUG就有可能出现。
解决方法,在WeaponManager中提供一个生成名字的函数 Ogre::String generateName(), 由我们的系统给用户提供可用的名称,这样如果用户不用我们系统提供的名称来创建,只能一切责任由用户来承担了。其实就用一个conuter来作为名字就行了,在createWeapon函数调用中counter++, 最后名字返回的时候用一个前缀字符串加这个counter来组成名字返回用户就好了。
基本原理就这些了,这种缓冲策略同样可以适合于EffectManager. |
|