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

Thảo luận trong 'World Editor' bắt đầu bởi mvcthinh, 4/9/11.

  1. mvcthinh

    mvcthinh Mr & Ms Pac-Man

    Tham gia ngày:
    18/8/11
    Bài viết:
    140
    Nơi ở:
    HCM
    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 ----------

    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
     
  2. KuKulKan

    KuKulKan T.E.T.Я.I.S

    Tham gia ngày:
    2/8/09
    Bài viết:
    629
    Nơi ở:
    Quận Thủ Đức, Thành phố Hồ Chí Minh
    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: 5/9/11
  3. mvcthinh

    mvcthinh Mr & Ms Pac-Man

    Tham gia ngày:
    18/8/11
    Bài viết:
    140
    Nơi ở:
    HCM
    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.


    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 ???
     
  4. KuKulKan

    KuKulKan T.E.T.Я.I.S

    Tham gia ngày:
    2/8/09
    Bài viết:
    629
    Nơi ở:
    Quận Thủ Đức, Thành phố Hồ Chí Minh
    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
     
  5. mvcthinh

    mvcthinh Mr & Ms Pac-Man

    Tham gia ngày:
    18/8/11
    Bài viết:
    140
    Nơi ở:
    HCM
    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..
     

Chia sẻ trang này