推荐地图:火影无级别混战推荐地图:楚汉争霸推荐地图:魔神推荐地图:人族无敌II
推荐专区:技能创作区推荐专区:WE讨论区推荐专区:模型作区推荐专区:申请公告区
 24 12
发新话题
打印

[提问] 单位组的一些问题

本主题由 singna 于 2008-12-2 00:37 关闭

单位组的一些问题

下面是选取圆周范围内的满足条件的单位的函数
COPY JASSCODE
JASS:

function GetUnitsInRangeOfLocMatching takes real radius, location whichLocation, boolexpr filter returns group
    local group g = CreateGroup()
    call GroupEnumUnitsInRangeOfLoc(g, whichLocation, radius, filter)
    call DestroyBoolExpr(filter)
    return g
endfunction

Shingo Jass Highlighter 0.4


下面是选取指定类型的单位的函数
COPY JASSCODE
JASS:

function GetUnitsOfTypeIdAll takes integer unitid returns group
    local group   result = CreateGroup()
    local group   g      = CreateGroup()
    local integer index

    set index = 0
    loop
        set bj_groupEnumTypeId = unitid
        call GroupClear(g)
        call GroupEnumUnitsOfPlayer(g, Player(index), filterGetUnitsOfTypeIdAll)
        call GroupAddGroup(g, result)

        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call DestroyGroup(g)

    return result
endfunction

Shingo Jass Highlighter 0.4


下面是选取单位组单位做动作的函数
COPY JASSCODE
JASS:

function ForGroupBJ takes group whichGroup, code callback returns nothing
    local boolean wantDestroy = bj_wantDestroyGroup
    set bj_wantDestroyGroup = false
    call ForGroup(whichGroup, callback)
    if (wantDestroy) then
        call DestroyGroup(whichGroup)
    endif
endfunction

Shingo Jass Highlighter 0.4


下面是添加单位组到单位组的函数
COPY JASSCODE
JASS:

function GroupAddGroup takes group sourceGroup, group destGroup returns nothing
    local boolean wantDestroy = bj_wantDestroyGroup
    set bj_wantDestroyGroup = false
    set bj_groupAddGroupDest = destGroup
    call ForGroup(sourceGroup, function GroupAddGroupEnum)
    if (wantDestroy) then
        call DestroyGroup(sourceGroup)
    endif
endfunction

Shingo Jass Highlighter 0.4



……………………………………………………………………

1、什么情况下要用DestroyBoolExpr来删除布尔表达式?这样不会破坏原来的布尔表达式的函数吗?
是不是用它判断完了如果不再用就应该删了。
2、看了ForGroupBJ函数明白了为什么设置了bj_wantDestroyGroup会排除泄露,那看一下下面的2个程序是不是会产生泄露。
第1个应该是不会的了,第2个好像没有清除由GetUnitsInRangeOfLocMatching内部创建的局部单位组,反而重复Destroy了这个g。
==============================
COPY JASSCODE
JASS:

//r,l,xyz具体就不要管了
set bj_wantDestroyGroup=true
call ForGroupBJ(GetUnitsInRangeOfLocMatching(r,l,null),function xyz)
call RemoveLocation(l)

Shingo Jass Highlighter 0.4


------------------------------
COPY JASSCODE
JASS:

//r,l,xyz具体就不要管了
set g=GetUnitsInRangeOfLocMatching(r,l,null)
call ForGroupBJ(g,function xyz)
call RemoveLocation(l)
call DestroyGroup(g)

Shingo Jass Highlighter 0.4


*******************************
3、刚看过大蛇的关于排泄的转帖,为什么用GetUnitsInRangeOfLocMatching选取单位进行动作能正常排泄,而用GetUnitsOfTypeIdAll就无法选取单位?
是不是因为GetUnitsOfTypeIdAll中使用GroupAddGroup导致运行一次后g被Destroy了?
4、第3个问题的解决方法,是否可以这样?
这里又与第二个问题的相关,个人认为是错的。如果不对是不是只能用选取地图上的满足匹配单位类型是'abcd'的所有单位来选取……
COPY JASSCODE
JASS:

set g=(GetUnitsOfTypeIdAll('abcd'))
set bj_wantDestroyGroup=true
call ForGroupBJ(g,function xyz)
call DestroyGroup(g)

Shingo Jass Highlighter 0.4


5、用GroupEnumUnitsOfPlayer这类函数是否会先清空单位组,再添加进去?
看GetUnitsOfTypeIdAll中的情况好像是,否则也不用中间变量的单位组g了。

……………………………………………………………………
以上是我目前遇到的一些问题,自己也回答了一遍,不知道是对是错,请高手指正,并提出解决方案

第5个问题经测试以确定,确实会清空

[ 本帖最后由 pbhpbhpbh 于 2008-11-4 21:08 编辑 ]
单位组么..我也想知道
1,这个基本不需要删,因为很少用到,就算泄露也就一两个而已。
2,set g=GetUnitsInRangeOfLocMatching(r,l,null) 和call DestroyGroup(g) 只需要一个就行了。具体看ForgroupBJ里。
3,什么意思?
4,测试了才知道。
5,估计只是添加,不是清空再加的。

lx继续补充。
nothing to say.
我没有补充
关于楼上的回答
2你理解错了
3我应该是对的吧
4跟2很像
5我过会来测试一下
第二个……
貌似两段代码效果差不多
只不过第二段代码多用了一个变量
不同的,第二个在赋值时不会清除GetUnitsInRangeOfLocMatching创建的单位组
而直接用ForGroupBJ就清除掉了,我是这么认为的,LX解答

TOP

GetUnitsInRangeOfLocMatching( )创建的单位组
就是GetUnitsInRangeOfLocMatching( )中的result

set g=GetUnitsInRangeOfLocMatching(r,l,null)
就是把result的值赋给g,过程中没有创建单位组,g就是result
call DestroyGroup(g)
删除g就是删除result

TOP

LS都说了,是把result赋值给g,那创建的result何时Destroy了?所以应该是存在泄露的

TOP

result 赋值给g,DestroyGroup(g) 就是DestroyGroup(result)

毕竟group变量也是handle型的

TOP

赋值不是内存地址传递,是值传递给内存空间,原来所占的内存还在,这是最基本的常识
如果说传递的是地址,那么DestroyGroup的目标自然是result,可惜传递的不是地址

TOP

说的头晕...

1.关于boolexpr
这是条件函数的返回值类型,具体又可以分为两种(见下面).跟触发条件差不多,删除为了减少泄露.
COPY JASSCODE
JASS:
type boolexpr               extends     handle
type conditionfunc      extends     boolexpr
type filterfunc               extends     boolexpr
native Condition        takes code func returns conditionfunc
native Filter                 takes code func returns filterfunc

Shingo Jass Highlighter 0.4



2.这两个是一样的.你说第二个在赋值时不会清除GetUnitsInRangeOfLocMatching创建的单位组,这是必然的,删除动作是最后那句call DestroyGroup(g) ,程序还没运行到那里...

3.你要看到,GetUnitsOfTypeIdAll函数内面有一个GroupAddGroup函数.如果你设置bj_wantDestroyGroup =true的话,那么在第一次运行GroupAddGroup函数的时候,g会被删除.一个被清空的单位组是能够再添加单位的,而被删除之后就不行了,除非再次set g=CreateGroup(),很显然,这里没有重新建立单位组,所以会导致出错.

4.3理解了4就不用说了.

5.我测试也是清空了,这样感觉再来个call GroupClear(g)就不是很必要了...谁来解释下...


关于值传递的问题,如果是set g = whichGroup这样的东西的话,传递的是内存地址(并非whichGroup自身的地址,而是单位组的地址),使用DestroyGroup(whichGroup)只是释放whichGroup指向的单位组占据的内存空间,但whichGroup本身自己占据的内存还是存在的,也就是还是有泄漏,这也是为什么经常看到set whichGroup=null.只有在set null之后才算是真正的无泄漏了.不过比起单位组来,一个whichGroup占据的空间基本可以忽略不计了,平时也不必太在意这个.

[ 本帖最后由 cctvfive 于 2008-11-5 11:19 编辑 ]

TOP

泄露不是说它占空间大,是说它占了Hash表,而war3搜索Hash表是很慢滴。

关于泄露只要不是局部变量,即使不清空也不会占多少Hash表,但是局部的就要注意了,因为局部变量不排泄,就是每运行一次那个函数都会产生一个Hash值,叠加起来是很恐怖的。

TOP

占用Hash表固然是个大问题,但是若不清理占用的内存空间的话,地图更容易卡......起码暴雪自己就没有太注意Hash表......

TOP

1、什么情况下要用DestroyBoolExpr来删除布尔表达式?这样不会破坏原来的布尔表达式的函数吗?
是不是用它判断完了如果不再用就应该删了。

是,和那个函数无关,直是实例化了1个对象


2、看了ForGroupBJ函数明白了为什么设置了bj_wantDestroyGroup会排除泄露,那看一下下面的2个程序是不是会产生泄露。
第1个应该是不会的了,第2个好像没有清除由GetUnitsInRangeOfLocMatching内部创建的局部单位组,反而重复Destroy了这个g。

第2个,g=那个局部变量的单位组

[quote]关于值传递的问题,如果是set g = whichGroup这样的东西的话,传递的是内存地址(并非whichGroup自身的地址,而是单位组的地址),使用DestroyGroup(whichGroup)只是释放whichGroup指向的单位组占据的内存空间,但whichGroup本身自己占据的内存还是存在的,也就是还是有泄漏,这也是为什么经常看到set whichGroup=null.只有在set null之后才算是真正的无泄漏了.不过比起单位组来,一个whichGroup占据的空间基本可以忽略不计了,平时也不必太在意这个.
[/quote]
就豆腐说的这个泄露

3、刚看过大蛇的关于排泄的转帖,为什么用GetUnitsInRangeOfLocMatching选取单位进行动作能正常排泄,而用GetUnitsOfTypeIdAll就无法选取单位?
是不是因为GetUnitsOfTypeIdAll中使用GroupAddGroup导致运行一次后g被Destroy了?


GetUnitsOfTypeIdAll可以选取单位啊?谁说不能?
他的原理是循环选取玩家1-16的所有单位 判断类型 如果是那个参数类型的 就加进单位组g
然后把g里单位加进result
之后清除单位组g中单位,再次选取下一个玩家
直到所有玩家的那个类型单位都被加进result后 就删除单位组g,并把result返回给函数

COPY JASSCODE
JASS:

function GetUnitsOfTypeIdAllFilter takes nothing returns boolean
    return GetUnitTypeId(GetFilterUnit()) == bj_groupEnumTypeId
endfunction

// =======================================
====================================
function InitBlizzardGlobals takes nothing returns nothing
set filterGetUnitsOfTypeIdAll = Filter(function GetUnitsOfTypeIdAllFilter)
endfunction
// =======================================
====================================
function GetUnitsOfTypeIdAll takes integer unitid returns group
    local group   result = CreateGroup()
    local group   g      = CreateGroup()
    local integer index

    set index = 0
    loop
        set bj_groupEnumTypeId = unitid
        call GroupClear(g)
        call GroupEnumUnitsOfPlayer(g, Player(index), filterGetUnitsOfTypeIdAll)
        call GroupAddGroup(g, result)

        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call DestroyGroup(g)

    return result
endfunction

Shingo Jass Highlighter 0.4




4、第3个问题的解决方法,是否可以这样?
这里又与第二个问题的相关,个人认为是错的。如果不对是不是只能用选取地图上的满足匹配单位类型是'abcd'的所有单位来选取……


这样和之前那个函数结果都一样。
他是分别选取每个玩家的所有单位 判断那个类型 再加进单位组

而你是 选取所有玩家的单位加进单位组 再判断那个类型


5、用GroupEnumUnitsOfPlayer这类函数是否会先清空单位组,再添加进去?
看GetUnitsOfTypeIdAll中的情况好像是,否则也不用中间变量的单位组g了。

我也去测试下
我的帖子总索引

求工具以及下载属性领取贴

一切都是浮云``对``就是浮云``

TOP

我写的第3条你没仔细看吧?......大蛇转的那帖是说,如果使用set bj_wantDestroyGroup=true的方法来给GetUnitsOfTypeIdAll排泄的话会出问题,具体原因我已经说了......不是说这个函数不能用......

TOP

对的,刚好我也回这个,结果已刷新,就已经出来了

TOP

那么在第一次运行GroupAddGroup函数的时候,g会被删除.一个被清空的单位组是能够再添加单位的,而被删除之后就不行了\

GroupAddGroup(A,B)
之后
B=A+B
A=A

A不变 并不会被删

不信你可以测试

附件

danweizu.w3m (12.53 KB)

2008-11-5 16:43, 下载次数: 0

我的帖子总索引

求工具以及下载属性领取贴

一切都是浮云``对``就是浮云``

TOP

看错 你写的了...请54楼上
我的帖子总索引

求工具以及下载属性领取贴

一切都是浮云``对``就是浮云``

TOP

set bj_wantDestroyGroup = true
call  ForGroupBJ(GetUnitsOfTypeIdAll('hpea'),function dongzuo)
如果这样会无法选取
COPY JASSCODE
JASS:

function GroupAddGroup takes group sourceGroup, group destGroup returns nothing //第3到了这 g被删除
    local boolean wantDestroy = bj_wantDestroyGroup 
    set bj_wantDestroyGroup = false 
    set bj_groupAddGroupDest = destGroup 
    call ForGroup(sourceGroup, function GroupAddGroupEnum) 
    if (wantDestroy) then 
        call DestroyGroup(sourceGroup) 
    endif 
endfunction 


function GetUnitsOfTypeIdAllFilter takes nothing returns boolean 
    return GetUnitTypeId(GetFilterUnit()) == bj_groupEnumTypeId 
endfunction 

// ======================================= 
==================================== 
function InitBlizzardGlobals takes nothing returns nothing 
set filterGetUnitsOfTypeIdAll = Filter(function GetUnitsOfTypeIdAllFilter) 
endfunction 
// ======================================= 
==================================== 
function GetUnitsOfTypeIdAll takes integer unitid returns group //第1步这个程序
    local group   result = CreateGroup() 
    local group   g      = CreateGroup() 
    local integer index 

    set index = 0 
    loop 
        set bj_groupEnumTypeId = unitid 
        call GroupClear(g) 
        call GroupEnumUnitsOfPlayer(g, Player(index), filterGetUnitsOfTypeIdAll) //然后第2到了这
        call GroupAddGroup(g, result) //这步完后 g被删除 再次循环时 就无法选取了

        set index = index + 1 
        exitwhen index == bj_MAX_PLAYER_SLOTS 
    endloop 
    call DestroyGroup(g) 

    return result 
endfunction


function ForGroupBJ takes group whichGroup, code callback returns nothing 
    local boolean wantDestroy = bj_wantDestroyGroup 
    set bj_wantDestroyGroup = false 
    call ForGroup(whichGroup, callback) 
    if (wantDestroy) then 
        call DestroyGroup(whichGroup) 
    endif 
endfunction 

Shingo Jass Highlighter 0.4

我的帖子总索引

求工具以及下载属性领取贴

一切都是浮云``对``就是浮云``

TOP

看完17楼大吃一惊,看完18楼恍然大悟

TOP

 24 12
发新话题