Cần giúp về đoạn code Jass này.

  • Thread starter Thread starter mvcthinh
  • Ngày gửi Ngày gửi

mvcthinh

Mr & Ms Pac-Man
Tham gia ngày
18/8/11
Bài viết
140
Reaction score
5
Mã:
scope Arrows initializer Ar

globals
    private integer idSpell = 'A001'
    private integer idDummy = 'h000'
endglobals

private struct data
    unit hero
    unit dummy
    location castloc
    real angle
    integer tick
    timer t
endstruct
    
private function Conditions takes nothing returns boolean
                        return GetSpellAbilityId() == idSpell
endfunction

    private function Knockback takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local data d = GetTimerData(t)
    local group g = CreateGroup()
    local unit temp
       local location loc
       local boolean check
       
        if d.tick < 150 then
            set loc = PolarProjectionBJ(d.castloc,50*d.tick,d.angle)
            call SetUnitPositionLoc(d.dummy,loc)
            call GroupEnumUnitsInRangeOfLoc(g,loc,100,null)
            set temp =FirstOfGroup(g)
                    loop
                        exitwhen temp == null 
                                if IsUnitEnemy(temp , GetOwningPlayer(d.dummy))  then
                                call SetUnitPositionLoc(temp,loc)
                                call UnitDamageTargetBJ(d.dummy,temp,10, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
                                call GroupRemoveUnit(g,temp)
                                set temp = FirstOfGroup(g)
                                endif
                                call GroupRemoveUnit(g,temp)
                                set temp = FirstOfGroup(g)
                    endloop
            call DestroyGroup(g)
            set temp = null
                        
            call RemoveLocation(loc)
            else
            call RemoveUnit(d.dummy)
            call ReleaseTimer(d.t)
            call d.destroy()
            endif
        
    
    call DestroyGroup(g)
    set t = null
    set d.tick = d.tick + 1
    set t = null
    
endfunction

private function Actions takes nothing returns nothing
    local data d = data.create()
    
    local unit hero = GetSpellAbilityUnit()
    local location targloc = GetSpellTargetLoc()
    local location castloc = GetUnitLoc(hero)
    
    local real angle = AngleBetweenPoints(castloc,targloc)
    
 set d.hero = hero
 set d.castloc = castloc
 set d.angle = angle 
 set d.dummy = CreateUnitAtLoc(GetOwningPlayer(hero),idDummy,castloc,angle)
 set d.tick = 1
 set d.t = NewTimer()
    
    call SetTimerData(d.t,d)
    call TimerStart(d.t,0.02,true,function Knockback )
    
 [B]   call RemoveLocation(targloc)
    call RemoveLocation(castloc)

    set hero = null
    set targloc = null
    set castloc = null[/B]

endfunction

//===========================================================================
private function Ar takes nothing returns nothing
    local trigger t = CreateTrigger(  )
  
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition( function Conditions ) )
    call TriggerAddAction( t, function Actions )
    set t=null
endfunction

endscope

Cái này chạy trên 1 System TimerUtils ...

Mình có thắc mắc ở cái chỗ in đậm này..
Bây giờ nếu mình không có nó thì Spell cast bình thường và không có vấn đề gì xảy ra , Unit Dummy có vị trí xuất phát ở castloc sẽ chạy ra từ đúng vị trí.
Nhưng nếu mình đặt cái lệnh để xóa leak thì khi cast spell , Unit Dummy lại có vị trí bắt đầu từ giữa bản đồ.. không hiểu vì sao lại như vậy nữa.. ai có thể giải thích dùm mình được không .. không xóa cái này Leak là 100% +_+

---------- Post added at 21:18 ---------- Previous post was at 21:16 ----------

call RemoveLocation(targloc)
call RemoveLocation(castloc)

set hero = null
set targloc = null
set castloc = null

hix.. in đậm mà nhìn nó chả có gì.. em Quote lại cái đoạn mà em nói tới ở trên
 
Thật ra bạn nên hiểu, leak là những vùng nhớ chứa dữ liệu/thông tin mà CPU sẽ phải xử lí, nếu xài xong không xóa, mặc dù dữ liệu đó ta không cần dùng/xài nữa nhưng CPU vẫn sẽ phải xử lí nó, leak càng nhiều nên CPU càng xử lí những thứ thừa thải, làm nặng/lag máy.

Trường hợp trên là trường hợp bạn chưa dùng xong dữ liệu của 1 vùng nhớ mà đã vội xóa nó đi, dẫn đến tình trạng khi bạn xử lí phần timer, nó có hiểu dữ liệu là gì đâu.

Rõ hơn là khi bạn location castloc = GetUnitLoc(hero) thì sẽ có 1 vùng nhớ chứa dữ liệu về cái điểm cast point đó, và castloc là 1 biến trỏ về vùng nhớ đó
Sau đó bạn set d.castloc = castloc thì biến d.castloc củng chỉ là 1 biến trỏ về vùng nhớ đó
Khi bắt đầu timer, thì bạn ngay lập tức call RemoveLocation(castloc), tức là bạn vừa hủy dữ liệu tại vùng nhớ mà biến castloc trỏ tới, trong khi đó biến d.castloc đang còn trỏ đến vùng nhớ đó mà dữ liệu bạn đã xóa đi...nên dẫn đến tình trạng như trên (xem như d.castloc = null, í chỉ vùng nhớ đó không còn dữ liệu gì cả)

Hi vọng là bạn hiểu sâu hơn về vấn đề đó :)
 
Chỉnh sửa cuối:
Thật ra bạn nên hiểu, leak là những vùng nhớ chứa dữ liệu/thông tin mà CPU sẽ phải xử lí, nếu xài xong không xóa, mặc dù dữ liệu đó ta không cần dùng/xài nữa nhưng CPU vẫn sẽ phải xử lí nó, leak càng nhiều nên CPU càng xử lí những thứ thừa thải, làm nặng/lag máy.

Trường hợp trên là trường hợp bạn chưa dùng xong dữ liệu của 1 vùng nhớ mà đã vội xóa nó đi, dẫn đến tình trạng khi bạn xử lí phần timer, nó có hiểu dữ liệu là gì đâu.

Rõ hơn là khi bạn location castloc = GetUnitLoc(hero) thì sẽ có 1 vùng nhớ chứa dữ liệu về cái điểm cast point đó, và castloc là 1 biến trỏ về vùng nhớ đó
Sau đó bạn set d.castloc = castloc thì biến d.castloc củng chỉ là 1 biến trỏ về vùng nhớ đó
Khi bắt đầu timer, thì bạn ngay lập tức call RemoveLocation(castloc), tức là bạn vừa hủy dữ liệu tại vùng nhớ mà biến castloc trỏ tới, trong khi đó biến d.castloc đang còn trỏ đến vùng nhớ đó mà dữ liệu bạn đã xóa đi...nên dẫn đến tình trạng như trên (xem như d.castloc = null, í chỉ vùng nhớ đó không còn dữ liệu gì cả)

Hi vọng là bạn hiểu sâu hơn về vấn đề đó :)

Nhưng lạ ở chỗ là khi mình đảo ngược vị trí của nó thì cái Code này lại hoạt động.


set hero = null
set targloc = null
set castloc = null

call RemoveLocation(targloc)
call RemoveLocation(castloc)

là như vậy nè..
Nếu như bạn nói mình không cần phải khai báo lệnh xóa nó đi thì nếu chiu đó được cast nhìu lần nhiều con nó có gây lag không .. vì cái này mình không biết nên đặt Xóa leak chỗ nào cho đúng.. Bạn nói rõ hơn cách khắc phục đoạn code trên được không ???
 
Chài, set castloc = null, tức là castloc giờ không còn trỏ tới vùng nhớ nào nữa rồi (cụ thể là vùng nhớ chưa dữ liệu GetUnitLoc(hero)), sau đó bạn lại ra lệnh hủy vùng nhớ mà nó trỏ tới ? -> Bất lôgic không ?

Bạn làm như thế là làm cho nó leak hơn ấy chứ, rất may thay trước đó bạn đã set d.castloc = castloc, tức là biến d.castloc cũng trỏ tới vùng nhớ này, bên timer bạn dùng nó nên mới chạy được đấy, nhưng khi chạy xong bạn lại không xóa vùng nhớ nó đi tức là RemoveLocation(d.castloc) -> leak đây

Vậy nếu như bạn hỏi cách xóa leak đó ra sao thì câu trả lời là chỉ cần thêm vào RemoveLocation(d.castloc) khi timer chạy xong
 
Chài, set castloc = null, tức là castloc giờ không còn trỏ tới vùng nhớ nào nữa rồi (cụ thể là vùng nhớ chưa dữ liệu GetUnitLoc(hero)), sau đó bạn lại ra lệnh hủy vùng nhớ mà nó trỏ tới ? -> Bất lôgic không ?

Bạn làm như thế là làm cho nó leak hơn ấy chứ, rất may thay trước đó bạn đã set d.castloc = castloc, tức là biến d.castloc cũng trỏ tới vùng nhớ này, bên timer bạn dùng nó nên mới chạy được đấy, nhưng khi chạy xong bạn lại không xóa vùng nhớ nó đi tức là RemoveLocation(d.castloc) -> leak đây

Vậy nếu như bạn hỏi cách xóa leak đó ra sao thì câu trả lời là chỉ cần thêm vào RemoveLocation(d.castloc) khi timer chạy xong

Oh`.. thế mà không hiểu nổi.. thanks bạn nha.. giờ đã hiểu được phần đó rồi hihi..
Như vậy khi khai báo xong, nếu phần biến nào còn dùng cho Timer thì phải giữ lại chưa xóa vội.. sau khi timer chạy xong thì xóa ở cái function có timer chạy .. như vậy phải không..
 
Back
Top