Когда-то уже просил найти утечки тут, и через годы... Снова...
Одну не знаю как удалить, а вторую не могу найти, подробности на скрине.

Лучший ответ:
Alexey103, посмотрел карту которую ты скинул
отключая по строчке выяснил что утечка возникает при установке переменной playergroup
т.е. утекает группа игроков
это происходит из за не обнулённой переменной в бж функции
чтобы исправить надо не использовать эту бж функцию
желательно перейти на джасс



Просмотров: 1 135

» Лучшие комментарии


biridius #1 - 3 месяца назад (отредактировано ) 2
код этой гуишной функции которая поворачивает юнита к точке (отключенная на скрине под коментом "тут утечка как удалить")
как видно на скрине не обнуляется локалка
как исправить - заменить на установку угла поворота равным углу между точками вместо этой функции
как всегда не редактируются вложения ну почините уже плиз
прикреплены файлы
NazarPunk #2 - 3 месяца назад (отредактировано ) 2
Переведите всё в JASS и раскройте BJ функции, всёравно там один Custom Script.
Obelick #3 - 3 месяца назад 0
Само событие утекает. Оно реагирует абсолютно на всех юнитов, которые "отдают" приказ в цель (даже если поставить условие). Для этих событий желательно устанавливать конкретного юнита, это меньшее зло.
ScopteRectuS #4 - 3 месяца назад 4
Obelick, впервые такое слышу..
NazarPunk #5 - 3 месяца назад 2
Obelick:
Само событие утекает. Оно реагирует абсолютно на всех юнитов, которые "отдают" приказ в цель (даже если поставить условие). Для этих событий желательно устанавливать конкретного юнита, это меньшее зло.
Как событие может утекать то? Событие происходит и дёргает всех "слушателей" которые на него повешены. И чем больше "слушателей", тем хуже.
Мне вот интересно, когда нейтрально пассивный Order("smart") отдаёт?
Sergarr #6 - 3 месяца назад 0
biridius:
код этой гуишной функции которая поворачивает юнита к точке (отключенная на скрине под коментом "тут утечка как удалить")
как видно на скрине не обнуляется локалка
как исправить - заменить на установку угла поворота равным углу между точками вместо этой функции
как всегда не редактируются вложения ну почините уже плиз
Еще надо не забыть удалить оба эти Position of (unit), т.к. они тоже точки создают. На ГУИ проще всего будет сперва записать их в переменные типа Temp_Loc1, Temp_Loc2, произвести действия триггера, а затем их удалить.
Alexey103 #7 - 3 месяца назад 0
Sergarr, Это очевидно, и не нужно создавать переменных, они у меня уже там созданы
NazarPunk, Там же нейтрально пассивный цель отданного приказа.
Msey #8 - 3 месяца назад (отредактировано ) 2
впервые такое слышу..
    private function init takes nothing returns nothing
     local trigger t=CreateTrigger()
        call TriggerAddCondition(t, Condition( function spellIdMatch) )
        call TriggerAddAction(t,    function onSpellCast)
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST )

     set t=null
    endfunction
Возможно он имел ввиду триггер, который висит в памяти, после регистрации событий и условий с действиями соответственно. Код выше его обнуляет, чего в гуи нет.
Alexey103 #9 - 3 месяца назад 0
Obelick, Ты не прав, я проверил заменив детектор расстояния между юнитами сообщением в чат, события и условия не утекают.
biridius, NazarPunk, Obelick, ScopteRectuS, Sergarr, Msey,
Путём исключения безутечных частей триггера удалось локализовать область поиска утечек до вот такого маленького участка, кто-нибудь может теперь понять что там не так, или просто написать джасс замену этого участка без утечек, хотя там и так всё на кастом скрипте. Я вообще удивляюсь, у меня такая-же проблема была в аналогичном триггере только в системе генерации мобов для карты, и там тоже никто толком не помог. Видимо гет енам юнитс нифига не безутечный, судя по хендл каунтеру. Или я не знаю как обьяснить его рост.
прикреплены файлы
NazarPunk #10 - 3 месяца назад 2
Alexey103:
Obelick, Ты не прав, я проверил заменив детектор расстояния между юнитами сообщением в чат, события и условия не утекают.
biridius, NazarPunk, Obelick, ScopteRectuS, Sergarr, Msey,
Путём исключения безутечных частей триггера удалось локализовать область поиска утечек до вот такого маленького участка, кто-нибудь может теперь понять что там не так, или просто написать джасс замену этого участка без утечек, хотя там и так всё на кастом скрипте. Я вообще удивляюсь, у меня такая-же проблема была в аналогичном триггере только в системе генерации мобов для карты, и там тоже никто толком не помог. Видимо гет енам юнитс нифига не безутечный, судя по хендл каунтеру. Или я не знаю как обьяснить его рост.
Внесите проблемный триггер в отдельную карту и прикрепите сообщение. Сложно разбираться по картинкам.
NazarPunk, Там же нейтрально пассивный цель отданного приказа.
Что-то недоглядел.
ScopteRectuS #11 - 3 месяца назад (отредактировано ) 0
Msey, эту локальную переменную можно не обнулять, она ссылается на статичный триггер, который будет висеть в памяти до конца игры. Другое дело, если бы это был динамичный триггер...
NazarPunk #12 - 3 месяца назад 0
ScopteRectuS:
Msey, эту локальную переменную можно не обнулять, она ссылается на статичный триггер, который будет висеть в памяти до конца игры. Другое дело, если бы это был динамичный триггер...
И зачем вам лишний handle, который вы не сможете дальше использовать?
ScopteRectuS #13 - 3 месяца назад 0
NazarPunk, ну так set t = null не освободит handle. Handle освободится, когда объект будет удалён и всё ссылки на него стёрты. А так как триггер статичный, он будет висеть в памяти до конца игры.
nvc123 #14 - 3 месяца назад (отредактировано ) 0
Alexey103, в редакторе триггеров вверху нажми правка --> конвертировать в текст
твой триггер преобразуется в джасс код
кинь этот код сюда
так же не забудь использовать форматирование код при вставке кода в комментарий
NazarPunk #15 - 3 месяца назад 2
Вот, набросал библиотеку. Под себя заточить несложно
» zinc
//! zinc
library NeutralPassiveTalk {
    /* настройки */
    constant real FontSize = 8.;
    constant real FontTime = 1.5;
    constant real Range = 500.;
    constant string Effect = "Abilities\\Spells\\Human\\InnerFire\\InnerFireTarget.mdl";
    
    //функция спецэффекта
    function Eff(player p, unit u) {
        string e = "";
        if (p == GetLocalPlayer()) {
            e = Effect;
        }
		DestroyEffect(AddSpecialEffectTarget(Effect, u, "overhead"));
    }
    
    // функция текстага
    function TextTag(player p, unit u, string s){
        texttag tt = CreateTextTag();
        SetTextTagText(tt,s,FontSize*.0023);
        SetTextTagPosUnit(tt, u, 20.);
        SetTextTagVelocity(tt, .05325 * Cos(1.570795), .05325 * Sin(1.570795));
        SetTextTagPermanent(tt, false);
        SetTextTagLifespan(tt, FontTime);
        SetTextTagFadepoint(tt, 0.);
        
        //скрываем от всех
        SetTextTagVisibility(tt, false);
        
        //показываем локальному игроку
        if (p == GetLocalPlayer()){
            SetTextTagVisibility(tt, true);
        }
        
        //утечки
        tt = null;
    }
    
    // применяем действия
    function Actions(player p, unit u1, unit u2,real angle){
        integer id = GetUnitTypeId(u2);
        string s = null;
        
        //проверяем юнитов
        if (id == 'hfoo'){
            s = "я бью";
        } else if (id == 'hsor') {
            s = "я колдую";
        } else if (id == 'hrif') {
            s = "у меня ружжо";
        } else if (id == 'earc') {
            s = "я стреляю";
        } else if (id == 'ugho') {
            KillUnit(u2);
        }
        
        // создаём текстаг, поворачиваем юнита и накидываем спецэффеты 
        if (s != null){
            // поворачиваем юнита
            SetUnitFacingTimed( u2, angle, 0. );
            
            // показываем текстаг
            TextTag(p, u2, s);
            
            // аттачим эффект
            Eff(p, u2);
            
            // шаманим с LocalPlayer
            if (p == GetLocalPlayer()){
                //говорим от юнита, возможен десинк, нужно проверить!
                SetCinematicScene(id, GetPlayerColor(GetOwningPlayer(u2)), GetUnitName(u2), s, I2R(StringLength(s)) * .3, .0);
                //мигаем индикатор, возможен десинк, нужно проверить!
                AddIndicator(u2, 255, 255, 255, 255);
            }
        }
    }
    
    // условия триггера
    function Cond() -> boolean {
        return (GetOwningPlayer(GetOrderTargetUnit()) == Player(PLAYER_NEUTRAL_PASSIVE) && GetIssuedOrderId() == 851971);
    }

    // инициализация
    function onInit(){
        trigger t = CreateTrigger();
        integer i;
        
        // вешаем событие только играющим людям
        for (0 <= i < 12) {
            if (GetPlayerController(Player(i)) == MAP_CONTROL_USER && GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING) {
                TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null);
            }
        }
        
        // вешаем условие
        TriggerAddCondition( t, Condition( function Cond));
        
        // вешаем действие
        TriggerAddAction( t, function(){
            unit u1 = GetTriggerUnit(); //юнит отдавший приказ
            unit u2 = GetOrderTargetUnit(); // юнит - цель приказа
            real x1 = GetUnitX(u1);
            real y1 = GetUnitY(u1);
            real x2 = GetUnitX(u2);
            real y2 = GetUnitY(u2);
            real dx = x2 - x1;
            real dy = y2 - y1;
            real angle = bj_RADTODEG * Atan2(y1 - y2, x1 - x2);
            real distance = SquareRoot(dx * dx + dy * dy);
            player p = GetOwningPlayer(u1);
            
            // применяем действия
            if (distance <= Range) {
                Actions(p,u1,u2,angle);
            }
                        
            // утечки
            u1 = null;
            u2 = null;
        });
    }
}
//! endzinc
прикреплены файлы
Alexey103 #16 - 3 месяца назад 0
прикреплены файлы
NazarPunk #17 - 3 месяца назад 2
Alexey103 #18 - 3 месяца назад (отредактировано ) 0
NazarPunk, Круто вроде, но ошибку выдаёт при проверке.
function Trig_speak_system_____________________u_Func001Func001Func006C takes nothing returns boolean
    if ( not ( IsUnitInGroup(GetOrderedUnit(), udg_units) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_speak_system_____________________u_Func001Func001C takes nothing returns boolean
    return true
endfunction

function Trig_speak_system_____________________u_Func001C takes nothing returns boolean
    if ( not ( GetIssuedOrderIdBJ() == String2OrderIdBJ("smart") ) ) then
        return false
    endif
    if ( not ( GetOwningPlayer(GetOrderTargetUnit()) == Player(PLAYER_NEUTRAL_PASSIVE) ) ) then
        return false
    endif
    return true
endfunction

function Trig_speak_system_____________________u_Actions takes nothing returns nothing
    if ( Trig_speak_system_____________________u_Func001C() ) then
        if ( Trig_speak_system_____________________u_Func001Func001C() ) then
            set udg_playergroup = GetPlayersByMapControl(GetPlayerController(GetOwningPlayer(GetOrderedUnit())))
            set udg_speak = GetUnitLoc(GetOrderTargetUnit())
            set udg_speak2 = GetUnitLoc(GetOrderedUnit())
            set udg_units = CreateGroup()
            call GroupEnumUnitsInRangeOfLoc(udg_units, udg_speak, 500., null)
            if ( Trig_speak_system_____________________u_Func001Func001Func006C() ) then
                // Если расстояние от юнита до цели меньше 500 то цель поворачивается и говорит в чат с подсветкой кружка
                call SetUnitFacingTimed( GetOrderTargetUnit(), AngleBetweenPoints(udg_speak, udg_speak2), 0.30 )
                call TransmissionFromUnitWithNameBJ( udg_playergroup, GetOrderTargetUnit(), "", null, "", bj_TIMETYPE_SET, 1.00, true )
                call UnitAddIndicatorBJ( GetOrderTargetUnit(), 100, 100, 100, 0 )
                call DisplayTextToForce( udg_playergroup, udg_strings[GetRandomInt(0, udg_count)] )
            else
            endif
            call RemoveLocation(udg_speak)
            call RemoveLocation(udg_speak2)
            call DestroyGroup(udg_units)
            call DestroyForce(udg_playergroup)
        else
        endif
    else
    endif
endfunction

//===========================================================================
function InitTrig_speak_system_____________________u takes nothing returns nothing
    set gg_trg_speak_system_____________________u = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_speak_system_____________________u, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
    call TriggerAddAction( gg_trg_speak_system_____________________u, function Trig_speak_system_____________________u_Actions )
endfunction 
nvc123, Ну и гайд по форматированию, только по примеру понял как его сделать. Вот текст уже только с одной утечкой и удалённым лишним кодом. Хорошо бы устранить утечку так чтоб не полностью перейти на джасс, но если нельзя то нельзя.
прикреплены файлы
ScopteRectuS #19 - 3 месяца назад 3
А зачем через группу проверять расстояние? Есть же функция IsUnitInRange( ).
NazarPunk #20 - 3 месяца назад 0
но ошибку выдаёт при проверке.
Попробуйте обновить JGNP и pjass и выключить Adic Parser и Adic Optimizer в cjass
чтоб не полностью перейти на джасс
Что вы так JASS'а боитесь то? Если юзать его с препроцессорами, то с разрастанием карты не потеряешься в куче глобальных переменных и триггеров.
ScopteRectuS:
А зачем через группу проверять расстояние? Есть же функция IsUnitInRange( ).
Это наследие GUI, всё через глобалки сделано же.
» JASS
function SpeakSystem_Actions takes nothing returns nothing
    local force f = GetPlayersByMapControl(GetPlayerController(GetOwningPlayer(GetOrderedUnit())))
    local location loc1 = GetUnitLoc(GetOrderTargetUnit())
    local location loc2 = GetUnitLoc(GetOrderedUnit())
    /* 851971 это id приказа smart, ненужно лишний раз конвертить из строки */
    if GetOwningPlayer(GetOrderTargetUnit()) == Player(PLAYER_NEUTRAL_PASSIVE)  and GetIssuedOrderId() == 851971 and  IsUnitInRange(GetOrderTargetUnit(),GetOrderedUnit(),500.) then
        // Если расстояние от юнита до цели меньше 500 то цель поворачивается и говорит в чат с подсветкой кружка
        call SetUnitFacingTimed( GetOrderTargetUnit(), AngleBetweenPoints(loc1, loc2), 0.30 )
        call TransmissionFromUnitWithNameBJ( f, GetOrderTargetUnit(), "", null, "", bj_TIMETYPE_SET, 1.00, true )
        call UnitAddIndicatorBJ( GetOrderTargetUnit(), 100, 100, 100, 0 )
        call DisplayTextToForce( f, udg_strings[GetRandomInt(0, udg_count)] )
    endif
    call ForceClear(f)
    call DestroyForce(f)
    set f = null
    call RemoveLocation(loc1)
    call RemoveLocation(loc2)
endfunction

function SpeakSystem takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer i = 0

    //вешаем только играющим
    loop
        exitwhen i > 12
        if GetPlayerController(Player(i)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
        endif
        set i = i + 1
    endloop
    call TriggerAddAction(t, function SpeakSystem_Actions)
    set t = null
endfunction 
Msey #21 - 3 месяца назад 0
Adic Parser и Adic Optimizer
Достаточно просто отключить парсер. Оптимизация без него не будет работать.
NazarPunk #22 - 3 месяца назад 0
Msey:
Adic Parser и Adic Optimizer
Достаточно просто отключить парсер. Оптимизация без него не будет работать.
То во что превращает код Adic сложно назвать оптимизацией, да и при сохранении карты он тормозит и частенько вылетает.
Мне вот пригдянулся zinc из-за простоты реализации и удобства отладки.
JASS
function Temp takes string s returns boolean r
..
return true
endfunction
против
zinc
function Temp (string s) -> boolean {
...
return true;
}
nvc123 #23 - 3 месяца назад (отредактировано ) 2
NazarPunk, cjass
bool Temp(string s){
	return true;
}
Alexey103, да что там понимать?
>> кат
""
тут находится джасс код
""
<<
получается:
» кат
тут находится джасс код

при беглом просмотре утечек не заметил
убери группу и используй простую проверку расстояния между точками:
"если расстояние между точками speak и speak2 меньше чем 500 то"
всеравно ведь точки используешь
так же проверь утечки при многократном повторении этого триггера
т.е. последовательно запусти этот триггер раз 20 и посмотри на показатель счётчика
Msey #24 - 3 месяца назад 0
То во что превращает код Adic сложно назвать оптимизацией
Есть такой момент. Хоть он и деликатен в написании, суммарное количество времени на компиляцию и возню с ошибками затрачивается при 500+ запусках для отладки значительно больше.
nvc123 #25 - 3 месяца назад 6
NazarPunk, Msey, оптимизация с точки зрения человека и с точки зрения машины разные вещи
код оптимизированный для машины плохо понятен человеку
а красивый и понятный код как правило дольше обрабатывается машиной
хотя существуют уникумы которые могут писать медленно работающий непонятный код
по сути задача любого препроцессора и компилятора превратить красивый и удобный код в нечитаемое говно которое устраивает машину
NazarPunk #26 - 3 месяца назад 1
NazarPunk, cjass
bool Temp(string s){
return true;
}
У zinc (Z Is Not C) тоже С-подобный синтаксис, но мне он не приглянулся изза того, что вылетает при ошибках, долго компилит и как сказано выше
Хоть он и деликатен в написании, суммарное количество времени на компиляцию и возню с ошибками затрачивается при 500+ запусках для отладки значительно больше.
по сути задача любого препроцессора и компилятора превратить красивый и удобный код в нечитаемое говно которое устраивает машину
JASS по сути сам является препроцессором для байткодов (Java Ass), которые и будут исполнятся игрой. И на это мы уже никак повлиять не можем.
хотя существуют уникумы которые могут писать медленно работающий непонятный код
Эти уникумы будут всегда и это ещё чудо, что их код может как-то исполняться не вызывая тотальный трындец всему, к чему дотягивается))
Alexey103 #27 - 3 месяца назад 0
nvc123,
убери группу и используй простую проверку расстояния между точками:
"если расстояние между точками speak и speak2 меньше чем 500 то"
всеравно ведь точки используешь
так же проверь утечки при многократном повторении этого триггера
т.е. последовательно запусти этот триггер раз 20 и посмотри на показатель счётчика
Спасибо за идею, избавился от глобалки, и упростил триггер, но хендл всё равно добавляется( Хотя я освоил новый триггер...
NazarPunk,
Эти уникумы будут всегда и это ещё чудо, что их код может как-то исполняться не вызывая
тотальный трындец всему, к чему дотягивается))
Ну зачем так жестоко, нужно рассматривать код начинающих как детский рисунок, а ещё лучше сохранить и потом троллить сабжа когда он научится писать понятно и кратко)
NazarPunk,
Что вы так JASS'а боитесь то? Если юзать его с препроцессорами, то с разрастанием карты не
потеряешься в куче глобальных переменных и триггеров.
Да я не боюсь, вот осваиваю потихоньку, просто сейчас система понятна, а когда переделаешь в джасс то мне придётся заново её изучать, а там свои нюансы, и главное условия после действий идут что сильно путает, и графического древа нету, короче если она не будет работать или работать не так, то меньше шансов что я смогу самостоятельно её отредактировать как мне нужно.
nvc123 #28 - 3 месяца назад (отредактировано ) 2

Alexey103, посмотрел карту которую ты скинул
отключая по строчке выяснил что утечка возникает при установке переменной playergroup
т.е. утекает группа игроков
это происходит из за не обнулённой переменной в бж функции
чтобы исправить надо не использовать эту бж функцию
желательно перейти на джасс
ScopteRectuS #29 - 3 месяца назад (отредактировано ) 0
nvc123, можно ещё сделать так:
» - На это:
только не udg_playerforce, а udg_playergroup. Очепятку допустил.
прикреплены файлы
nvc123 #30 - 3 месяца назад (отредактировано ) 2
ScopteRectuS, ну я и говорю
не использовать бж функцию
Alexey103:
и главное условия после действий идут что сильно путает
лол что?
кто тебе такой бред сказал