|
楼主 |
发表于 2009-10-18 15:49:21
|
显示全部楼层
关于绑定数据的存储系统
存储数据的系统是做系统的基本。我是绝对赞成vj的struct的。就算1.24b还没有能用的vj,我也非常喜欢直接写伪vjstruct源码。
首先,存储数据有这样几个结构:
gamecache
hashtable
array
其中,cache的效率<hashtable的效率<array的效率。
这个应该是公认的……?
cache因为效率又慢,还可能因为Sync而产生互通图所以是早就应该被抛弃的鬼东西。
悲剧的是这个东西居然是jass教程中的“高级教程”…………
在下面我们不考虑cache。
1.24b的hashtable因为可以嵌套存储hashtable,所以可以很方便的实现任意长度的N维数组,在功能上比array和gamecache(那个东西其实也可以多维数组,但是因为会产生大量基本无实际作用的String所以废弃)要好得多。
array虽然效率最高,但是因为根本没有直接存储的方法,所以实际情况还要讨论。
1.vj的struct
vj的struct的原理就是两个函数:
allocate()
这个用来分配一个1-8190的不会与当前存储的struct实例重复的struct实例(在这里你可以把struct实例当成integer)
destroy()
这个用来回收struct实例,以备下次allocate()使用。
struct的原理其实就是用这个integer(Struct实例)作为索引(index),在全局变量数组中找到对应struct实例的数据。
需要给绑定对象绑定一个integer。
至于其他的我们先不管,因为如果需要用到hashtable(1.24b)的话,那么就只要把这两个函数翻译成jass基本上就没问题了。
2.直接求差法。
典型例子就是TimerDataSystem。直接把当前handle的Id减去最小handle的id就得到了index。
不过这个handle是不能被删除的。
这个是所有绑定无限事先声明的数据方法中,应该是最快的方法了。
我绑定数据的方法是,能用struct就用struct(其实求差法也是可以写成struct的,只不过这个struct不需要allocate()和destroy()而已)。
把所有数据全部写在struct里。
然后再使用hashtable(我现在是写数组hashtable,不过下一个系统考虑到N维数组可能就直接1.24b的hashtable了)把这个struct绑定在被绑定目标上。
比如:
[jass]
globals
hashtable HT = null
endglobals
function Init takes nothing returns nothing
call FlushParentHashtable( HT )
set HT = InitHashtable()
endfunction
struct Buff
timer t
buff b
unit u
static method create takes unit u, buff b returns thistype
local thistype this = thistype.allocate()
set .b = b
set .u = u
call SaveInteger( HT, GetHandleId( b ), StringHash( "TheStruct" ), this )
return this
endmethod
static method get takes buff b returns thistype
return LoadInteger( HT, GetHandleId( b ), StringHash( "TheStruct" ) )
endmethod
endstruct
[/jass]
(以上代码在我写这个帖子的时候,实际上是连我的WE是编译都编译不出来的,只不过是示意而已)
至于我为什么很喜欢用struct,因为看起来绑定的数据的类型、名称都一目了然。而如果全部使用hashtable或者gamecache,那么在编很大的系统时,就会比较麻烦,不知道自己绑定的数据在哪里,有没有绑定什么的。
最关键在于它可以和任何其他的存储系统结合在一起,而且因为每次它只需要在操作最开始get一下,然后就可以直接用index从数组里读数据,效率也是非常高的~
当然对于没学过vj的人来说应该是没用的吧…………
只绑定1个integer,移动数据的时候也是比较方便的。
理解面向对象这个概念的人应该会觉得struct非常好用。 |
|