Доброго времени суток.
Мне необходимо написать код без утечек, которые забивают память.
Но я новичок, который с каждым годом открывает для себя все новее и новее вар. По этой причине мне сразу сложно разобраться во всех его аспектах. А редактор для меня стал просто "заставить мозг думать"
Исходя из небольших статей с обучалками (а также спасибо большое rsfghd), я понял что сам юнит забивает память, но и точка, которая создается при создании юнита в позиции выбранного юнита.
Идея, добавить нужных юнитов в переменную (отряд), к примеру asd.
А после мне нужно создать ДАММИ юнита около каждого юнита в переменной asd.
И тут момент с оптимизацией "Позиции выбранного юнита". Ибо, как я понял из статей, она создает точку (которая вызывает утечку).
Ну и после всех манипуляций функцией (ниже) удалять переменную (отряда).
call DestroyGroup(udg_asd)
Сама логика триггера.
Действие:
Выбрать каждого юнита в зоне карты и совершить действие
Создать 1 юнита, для игрока 1, в позиции выбранного юнита.
Так вот, мне необходим код, который будет удалять эти "утечки". Ну либо совмещенная сборка с функциями.
Надеюсь я правильно донес свою мысль хд

Принятый ответ

создать DAMI юнита
dummy* - дамми

вот пример выбора юнитов в темповую группу без утечек с использованием точек

есть несколько функций для выбора юнитов
native GroupEnumUnitsInRange takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing
native GroupEnumUnitsInRangeOfLoc takes group whichGroup, location whichLocation, real radius, boolexpr filter returns nothing
native GroupEnumUnitsInRect takes group whichGroup, rect r, boolexpr filter returns nothing
native GroupEnumUnitsOfPlayer takes group whichGroup, player whichPlayer, boolexpr filter returns nothing
native GroupEnumUnitsOfType takes group whichGroup, string unitname, boolexpr filter returns nothing
native GroupEnumUnitsSelected takes group whichGroup, player whichPlayer, boolexpr filter returns nothing
у некоторых есть аналоги с потолком выбора (кол-ва юнитов)

DestroyGroup( ... ) нужно использовать только если ты постоянно создаёшь группу до этого (в основном это требуется, если ты должен сделать действия с теми же юнитами спустя какое-то время, например выбрать кого-то там в области, наложить эффект, подождать 2 секунды и продамажить), но для темповых действий лучше иметь одну группу и просто очищать её
Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...
1
27
2 года назад
1
создать DAMI юнита
dummy* - дамми

вот пример выбора юнитов в темповую группу без утечек с использованием точек

есть несколько функций для выбора юнитов
native GroupEnumUnitsInRange takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing
native GroupEnumUnitsInRangeOfLoc takes group whichGroup, location whichLocation, real radius, boolexpr filter returns nothing
native GroupEnumUnitsInRect takes group whichGroup, rect r, boolexpr filter returns nothing
native GroupEnumUnitsOfPlayer takes group whichGroup, player whichPlayer, boolexpr filter returns nothing
native GroupEnumUnitsOfType takes group whichGroup, string unitname, boolexpr filter returns nothing
native GroupEnumUnitsSelected takes group whichGroup, player whichPlayer, boolexpr filter returns nothing
у некоторых есть аналоги с потолком выбора (кол-ва юнитов)

DestroyGroup( ... ) нужно использовать только если ты постоянно создаёшь группу до этого (в основном это требуется, если ты должен сделать действия с теми же юнитами спустя какое-то время, например выбрать кого-то там в области, наложить эффект, подождать 2 секунды и продамажить), но для темповых действий лучше иметь одну группу и просто очищать её
Загруженные файлы
Принятый ответ
0
2
2 года назад
0
> создать DAMI юнита
dummy* - дамми

вот пример выбора юнитов в темповую группу без утечек с использованием точек

есть несколько функций для выбора юнитов
native GroupEnumUnitsInRange takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing
native GroupEnumUnitsInRangeOfLoc takes group whichGroup, location whichLocation, real radius, boolexpr filter returns nothing
native GroupEnumUnitsInRect takes group whichGroup, rect r, boolexpr filter returns nothing
native GroupEnumUnitsOfPlayer takes group whichGroup, player whichPlayer, boolexpr filter returns nothing
native GroupEnumUnitsOfType takes group whichGroup, string unitname, boolexpr filter returns nothing
native GroupEnumUnitsSelected takes group whichGroup, player whichPlayer, boolexpr filter returns nothing
у некоторых есть аналоги с потолком выбора (кол-ва юнитов)

DestroyGroup( ... ) нужно использовать только если ты постоянно создаёшь группу до этого (в основном это требуется, если ты должен сделать действия с теми же юнитами спустя какое-то время, например выбрать кого-то там в области, наложить эффект, подождать 2 секунды и продамажить), но для темповых действий лучше иметь одну группу и просто очищать её
Еще раз доброго времени суток :)
Главный хранитель этого ресурса хд
Спасибо большое за ответ.
Хотел уточнить:
  1. Я правильно понимаю, я могу заранее через действие "Отряд выбрать каждого с условиями совпадения" записать позиции(точку) в переменную типа "точка". А после взаимодействовать с ней и далее очистить ее. Тем самым я освобождаю память?
И еще, извините за свою любознательность.
call GroupEnumUnitsInRect( udg_TempGroup, bj_mapInitialPlayableArea, udg_TempBlxpr )
  1. Эта функция записывает всех юнитов в группу TempGroup, которые совпадают выше условиями из переменной TempBlxpr, на всей карте mapInitialPlayableArea?
  2. Выходит я могу менять условия и тип юнита/игрока в переменной TempBlxpr?
  3. А если я сделаю через действие "Отряд выбрать каждого с условиями совпадения" и запишу юнитов в группу TempGroup - память в этом случае забивается? Если да, то как?
1
27
2 года назад
1
Я правильно понимаю, я могу заранее через действие "Отряд выбрать каждого с условиями совпадения" записать позиции(точку) в переменную типа "точка". А после взаимодействовать с ней и далее очистить ее. Тем самым я освобождаю память?
да, но использовать другую функцию для выбора нужно - GroupEnumUnitsInRangeOfLoc
если дружишь с английским то я думаю понятно что оно делает, если нет - выбор юнитов в группу в радиусе от точки, вот пример использования
512.00 - радиус
zpxo:
Эта функция записывает всех юнитов в группу TempGroup, которые совпадают выше условиями из переменной TempBlxpr, на всей карте mapInitialPlayableArea?
да. если, опять же, дружишь с английским, то я думаю mapInitialPlayableArea уже говорит сама за себя (исходная игровая зона карты), то есть по сути вся карта (исключая тёмные края вроде)
zpxo:
Выходит я могу менять условия и тип юнита/игрока в переменной TempBlxpr?
да, следующим ответом станет понятно почему нужно использовать переменную TempBlxpr
zpxo:
А если я сделаю через действие "Отряд выбрать каждого с условиями совпадения" и запишу юнитов в группу TempGroup - память в этом случае забивается? Если да, то как?
я уже помогал другому челу с этой утечкой, тогда я тоже впервые для себя открыл её

если вкратце, гуишные функции с приставкой Matching выглядят примерно так
function GetUnitsInRectMatching takes rect r, boolexpr filter returns group
    local group g = CreateGroup()
    call GroupEnumUnitsInRect(g, r, filter)
    call DestroyBoolExpr(filter)
    return g
endfunction
меняется только функция выбора если не ошибаюсь. в общем-то всё просто - не обнуляется переменная g, то есть нет действия set g = null, и собственно, с использованием локалки такое действие ты сюда никак не пихнёшь, только глобалка нужна, потому что после действия return больше никакие действия пихнуть нельзя (на гуи называется "пропустить остальные действия"). но это бж функция, ты её не изменишь, кастомную писать только надо, но зачем, когда я уже скинул примеры как выбирать юнитов в группу

в следующий раз не нужно выделять весь текст, просто кликни по моему нику, либо выдели нужный текст и нажми кнопку цитировать
Загруженные файлы
0
2
2 года назад
Отредактирован zpxo
0
да. если, опять же, дружишь с английским, то я думаю mapInitialPlayableArea уже говорит сама за себя (исходная игровая зона карты), то есть по сути вся карта (исключая тёмные края вроде)
а как я могу использовать ВСЮ карту?
call GroupEnumUnitsInRect( udg_TempGroup, bj_mapInitialPlayableArea, udg_TempBlxpr )
Так как bj_mapInitialPlayableArea ссылается на карту, которая игровая. Если правильно понимаю. А мне нужно всю карту захватить.
Ибо иногда Дамми создаются за краем игровой карты. Тем самым я не могу с ними взаимодействовать, если они не в игровой зоне.
Я просто пытаюсь найти фразу для замены "mapInitialPlayableArea"
Можно еще подсказку.
Как провернуть такое же действие, как выше, но с предметами?
У меня просто есть триггер, который берет все предметы на карте и совершает действие:
  • Условия: (определенный тип)
  • Действие: Удалить
Возможно, я ошибаюсь, но вдруг это тоже создает утечки

А также, хотел узнать, про счетчик Handle.
Если убрать все утечки, прям все все, цифра счетчика будет возвращаться к первоначальной позиции? Или она будет продолжать расти с каждым запуском триггера?

Я сейчас ломаю голову над данным триггером:
Его задача брать юнитов на карте и совершать действие со случайным из них.
Триггер работает на ура. Но...
По началу счетчик Handle показывает при активации триггера +4/-4 и такие мелкие значения. Отклонения бывают на 1/2 единицы. Вроде бы это норма...
Но после 60-й секунды, когда появляется текстовое уведомление на карте всем игрокам - Счетчик Handle повышается резко на +30/40
А после Каждый раз, когда триггер запускается - идет уже по +12 и спад не появляется, только рост и рост с каждой активацией.
Не могу понять... Почему в начале он показывает рост счетчика в 0, а после 60 секунды рост идет сильный и нет спада.
Проверял триггеры, ничего не работает параллельно с данным триггером (призыва мобов). Также отключал сам триггер с призывом мобов и на 60 секунду, когда появляется текст - счетчик Handle даже не дрогнулся.
Также отключал триггер появления текста, просто происходит резкий рост и нет спада... И дальше счетчик увеличивается то на +12/14/20/40/50/
Загруженные файлы
1
27
2 года назад
1
а как я могу использовать ВСЮ карту?
для этого нужно использовать GetWorldBounds( ) вместо bj_mapInitialPlayableArea, но дело в том, что вызов GetWorldBounds( ) каждый раз вызывает утечку, чтобы этого не происходило, нужно создать переменную типа рект и присвоить ей значение, то есть вот это:
а потом использовать udg_названиеПеременной в кастомскрипте (в данном случае udg_EntireMapRect), тогда будут учитываться и тёмные зоны

Как провернуть такое же действие, как выше, но с предметами?
зачем? выбор предметов не утечен на твоём скрине, вот используемый код
function EnumItemsInRectBJ takes rect r, code actionFunc returns nothing
    call EnumItemsInRect(r, null, actionFunc)
endfunction

function GetPlayableMapRect takes nothing returns rect
    return bj_mapInitialPlayableArea
endfunction
Если убрать все утечки, прям все все, цифра счетчика будет возвращаться к первоначальной позиции? Или она будет продолжать расти с каждым запуском триггера?
счётчик хэндлов не особо точен, если у тебя не скачет что-то дохрена вверх постоянно, то всё норм, иногда нужно подождать какое-то время чтобы всё стабилизировалось (трупы там допустим исчезнут, эффекты пропадут после смерти и тому подобное)
Загруженные файлы
0
2
2 года назад
0
rsfghd, Извиняюсь, мы в один момент выложили сообщения :) и возможно выше не видел ты, новые.
Я сейчас ломаю голову над данным триггером:
Это тут.
а потом использовать udg_названиеПеременной в кастомскрипте (в данном случае udg_EntireMapRect), тогда будут учитываться и тёмные зоны
Спасибо большое за подсказку. Выходит если через переменную сделать как на скриншоте - то утечек не будет.
зачем? выбор предметов не утечен на твоём скрине, вот используемый код
Слава Богу.
1
27
2 года назад
1
Я сейчас ломаю голову над данным триггером:
ну да, тут есть утечка.
эх. сложно живётся гуишникам, сейчас объясню

у тебя юзается точка с полярным смещением, код выглядит примерно так
function PolarProjectionBJ takes location source, real dist, real angle returns location
    local real x = GetLocationX(source) + dist * Cos(angle * bj_DEGTORAD)
    local real y = GetLocationY(source) + dist * Sin(angle * bj_DEGTORAD)
    return Location(x, y)
endfunction
то есть функция принимает точку, а когда ты указываешь позицию юнита, ты её создаёшь, то есть она тут уже нигде не исчезает как ты видишь, а заодно возвращает ещё одну, новую точку, то есть создаётся по факту 2 точки, одна это позиция юнита, другая это смещение, вот именно смещение ты и присваиваешь и удаляешь в последствии. чтобы исправить это, тебе нужно запеременить позицию юнита, указать её в смещении, а потом уже удалить и позицию, и смещение, выглядит вот так

ну и есть ощущения что выбор рандомных юнитов из группы юнитов тоже утекает

function GetRandomSubGroup takes integer count, group sourceGroup returns group
    local group g = CreateGroup()

    set bj_randomSubGroupGroup = g
    set bj_randomSubGroupWant  = count
    set bj_randomSubGroupTotal = CountUnitsInGroup(sourceGroup)

    if (bj_randomSubGroupWant <= 0 or bj_randomSubGroupTotal <= 0) then
        return g
    endif

    set bj_randomSubGroupChance = I2R(bj_randomSubGroupWant) / I2R(bj_randomSubGroupTotal)
    call ForGroup(sourceGroup, function GetRandomSubGroupEnum)
    return g
endfunction
да, утекает, опять переменная не обнуляется и не уничтожается, сейчас скажу что нужно делать
Загруженные файлы
2
2
2 года назад
Отредактирован zpxo
2
то есть функция принимает точку, а когда ты указываешь позицию юнита, ты её создаёшь, то есть она тут уже нигде не исчезает как ты видишь, а заодно возвращает ещё одну, новую точку, то есть создаётся по факту 2 точки, одна это позиция юнита, другая это смещение, вот именно смещение ты и присваиваешь и удаляешь в последствии. чтобы исправить это, тебе нужно запеременить позицию юнита, указать её в смещении, а потом уже удалить и позицию, и смещение, выглядит вот так
Да, это я как раз начал понимать (благодаря тебе) когда создавал эту переменную.
Но выстроил иллюзии, что вероятно точка создается одна, а не две.
По этой причине думал ничего не будет страшного. А оказывается все страшно 😄
Выходит я просто должен в 1 переменной указать внутри позицию другой переменной.
А не страшно что у меня указан случайный угол, в момент создания точки со смещением?
да, утекает, опять переменная не обнуляется и не уничтожается, сейчас скажу что нужно делать
А вот это совсем неожиданно.
Рандомный выбор именно утекает? Или любая работа со случайностью?
К примеру случайный угол, случайное число.
1
27
2 года назад
Отредактирован rsfghd
1
Рандомный выбор именно утекает?
выбор, я же скинул код с группой

вот это не утекает вроде
  • bj_randomSubGroupWant* - кол-во рандомных юнитов
группа 0 основная, группа 1 с рандомами

А не страшно что у меня указан случайный угол, в момент создания точки со смещением?
случайный угол это ровно то же действие, что и случайное число от 0 до 360. числа, реальные, строки и подобное не утекает

ну наверное постоянная вставка такого огромного кол-ва кода тебя может напрягать, так что сейчас сделаю отдельную функцию для тебя

function GetRandomSubGroupEx takes group sourceGroup, group g, integer count returns nothing
    set bj_randomSubGroupGroup = g
    set bj_randomSubGroupWant  = count
    set bj_randomSubGroupTotal = CountUnitsInGroup( sourceGroup )

    if ( bj_randomSubGroupWant <= 0 or bj_randomSubGroupTotal <= 0 ) then
        return
    endif

    set bj_randomSubGroupChance = I2R( bj_randomSubGroupWant ) / I2R( bj_randomSubGroupTotal )
    call ForGroup( sourceGroup, function GetRandomSubGroupEnum )
endfunction
первый аргумент группа, из которой нужно достать рандомных юнитов, второй аргумент куда этих рандомных юнитов засунуть и третий кол-во, код можешь закинуть куда угодно, в шапку карты например
Загруженные файлы
1
27
2 года назад
1
м, файлы заменились из-за автоматической склейки сообщений, потому что имели одинаковое название, неприятно
2
2
2 года назад
2
rsfghd, Использовал твои наработки выше и наработки из прошлых советов, в других вопросах.
Я скажу так. Ты монстр, спасибо тебе огромное.
Счетчик вообще не двигается, а мои знания сегодня выросли еще на планку выше, чем за годы!
Сейчас данный триггер отрабатывает как часы и без каких либо утечек.
Также разобрался как в сценарии превратить реальное в целое число. И под себя получилось идеально
Дождусь твоего ответа :) А после закреплю правильный ответ
Загруженные файлы
1
27
2 года назад
1
zpxo, я могу отвечать на закрытые вопросы, не волнуйся, абилка прокачана, это тебе приходится убирать ответ, писать коммент, а потом снова закрывать вопрос
юзай отдельную функцию что я скинул, мне кажется так удобнее будет, а то какая-то дрисня со склейкой получилась
2
2
2 года назад
Отредактирован zpxo
2
rsfghd, Небольшой совет хочу.
В этом триггере я понимаю что точно идет утечка, из-за случайности.
Просто у этого триггера идет арифметика в таком ключе: Взять 40 процентов из суммы юнитов.
Могу ли я заранее создать переменную с арифметикой? Где возьму сумму из группы юнитов и высчитаю 40%, а после переведу в реальное число и вставлю в bj_randomSubGroupWant?

юзай отдельную функцию что я скинул, мне кажется так удобнее будет, а то какая-то дрисня со склейкой получилась
Кстати, да, она такая упрощенная.
Вместо цифры "4" я могу туда по сути вставить переменную, верно?
И я могу внутри функции перевести переменную из реального в целое, в момент ссылания на переменную?
К примеру так: call GetRandomSubGroupEx( udg_TempGroup[ 0 ], udg_TempGroup[ 1 ], R2I(udg_ANOMABalanceUron_Time_Procent) )
Загруженные файлы
1
27
2 года назад
1
а после переведу в реальное число и вставлю в bj_randomSubGroupWant?
не в реальное, а в целочисленное
да, ты можешь так сделать, вот пример

И я могу внутри функции перевести переменную из реального в целое, в момент ссылания на переменную?
по совпадению сразу и на это ответил в примере)

Загруженные файлы
2
2
2 года назад
2
rsfghd, Спасибо еще раз огромное, за такую бесценную помощь! ❤️
Чтобы оставить комментарий, пожалуйста, войдите на сайт.