Добавлен
Собственно такой вопрос. Если сделать
GroupEnumUnitsInRange(group,500,500,500,Condition(function() )
то Condition удаляется или создает утечку ? или все таки лучше делать
b=Condition(function() )
GroupEnumUnitsInRange(group,500,500,500,b)
DestroyBoolexpr(b)
просто заметил, что внутри condition можно из первого примера использовать все локалки в триггере и это очень круто, что не скажешь про второй вариант, пытался давать функции обьекты и они не передавались а сама функция работала
b=Condition(function(object) )
GroupEnumUnitsInRange(group,500,500,500,b(object))
Или все таки лучше использовать глобалки и без них никак ? Просто волнует вопрос по поводу, что если одну глобалку использовать на группу для множества игроков, То не будет ли глобалка перебиваться вечно разными игроками и в конце концов будет ссылаться на других игроков, или там какая то шляпа, что такого не будет ? Вот что то типа этого. Просто хотелось бы создать кондишн 1 раз занести его в глобалку и использовать постоянно, но не будет ли вечено перебивать игроков ? Просто если даже создать локально то уже все локалки не могут быть использованы в групенум....
B=Condition(function())
	P=GetFilter()
	if P==PLAYER then
	
	end 
end)

function()
	PLAYER=GetTriggerPlayer()
	GroupEnumUnitsInRange(group,500,500,500,B)
end
Надеюсь понятно.

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

Чтоб не мучиться, обойдитесь вообще без фильтров:
GROUP = CreateGroup() -- Глобальная группа, чтоб не создавать каждый раз.

-- в самом триггере
GroupEnumUnitsInRange(GROUP, x, y, range, nil)
local target ---@type unit
while true do
	target = FirstOfGroup(GROUP)
	if target == nil then break end -- выходим из цикла при пустой группе
	
	if UnitAlive(target) then -- условия для перебора
		KillUnit(target) -- действия для перебора
	end
	
	GroupRemoveUnit(GROUP, target)
end
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
2
29
5 лет назад
Отредактирован nazarpunk
2
Чтоб не мучиться, обойдитесь вообще без фильтров:
GROUP = CreateGroup() -- Глобальная группа, чтоб не создавать каждый раз.

-- в самом триггере
GroupEnumUnitsInRange(GROUP, x, y, range, nil)
local target ---@type unit
while true do
	target = FirstOfGroup(GROUP)
	if target == nil then break end -- выходим из цикла при пустой группе
	
	if UnitAlive(target) then -- условия для перебора
		KillUnit(target) -- действия для перебора
	end
	
	GroupRemoveUnit(GROUP, target)
end
Принятый ответ
1
26
5 лет назад
Отредактирован Hate
1
NazarPunk:
Чтоб не мучиться, обойдитесь вообще без фильтров:
GROUP = CreateGroup() -- Глобальная группа, чтоб не создавать каждый раз.

-- в самом триггере
GroupEnumUnitsInRange(GROUP, x, y, range, nil)
local target ---@type unit
while true do
	target = FirstOfGroup(GROUP)
	if target == nil then break end -- выходим из цикла при пустой группе
	
	if UnitAlive(target) then -- условия для перебора
		KillUnit(target) -- действия для перебора
	end
	
	GroupRemoveUnit(GROUP, target)
end
это мнение, а не ответ на вопрос, и многим было бы полезно узнать его
6
16
5 лет назад
6
фильтры не текут
0
29
5 лет назад
0
это мнение, а не ответ на вопрос, и многим было бы полезно узнать его
Можно подумать логически и заглянуть в common.j.
---@class agent:handle -- all reference counted objects
---@class boolexpr:agent

---@class conditionfunc:boolexpr
---@class filterfunc:boolexpr

---@param func code
---@return filterfunc
function Filter(func) end

---@param func code
---@return conditionfunc
function Condition(func) end
Как видно Filter и Condition создают и возвращают boolexpr и вродибы раньше Condition кэшировалось, а как реализовали в lua хз, но поидее должен прийти сборщик мусора и всё подчистить.
0
24
5 лет назад
Отредактирован prog
0
DracoL1ch, при использовании в луа с анонимными функциями - очень даже текут потому как не удаляются, насколько я знаю, а анонимная функция при каждом вызове новая создается и передается в создание фильтра.

поидее должен прийти сборщик мусора и всё подчистить
Сборщик мусора Lua не подчищает нативные обьекты, к которым относятся и фильтры.

К сожалению, на данный момент на нативное кеширование фильтров и кондишнов при использовании луа полагаться нельзя, оно то ли не работает полностью то ли работает только в очень ограниченном наборе ситуаций, что и не удивительно, учитывая динамическую природу Lua. Нужно либо самостоятельно выполнять кеширование либо максимально обходиться без фильтров.
Решение которым пользуюсь я когда мне нужно передавать какие-то данные в фильтр из вызывающей функции выглядит примерно так:

local FilterData ={} -- локальная для кода карты глобалка для передачи данных в фильтры

local function FilterThemAll() --функция фильтра, использующая данные из глобалки
	local data = FilterData
	local p = data.player
	local target = data.target
	return false
end

local SomeFilter = Filter(FilterThemAll) -- создание фильтра для функции FilterThemAll - "ручное кеширование"

function GroupEnumUnitsInRangeCustom (g,r,x,y,f,data) -- функция инкапсулирующая передачу данных чрез глобалку и вызов GroupEnumUnitsInRange с фильтром
	local dataBack = FilterData
	FilterData = data
	GroupEnumUnitsInRange(g,r,x,y,f)
	FilterData = dataBack
end
Код примерный и писался сейчас из головы по памяти - для использования в реальных условиях могут быть нужны доработки и исправления ошибок.
0
29
5 лет назад
0
К сожалению, на данный момент на нативное кеширование фильтров и кондишнов при использовании луа полагаться нельзя
Тогда нужно отказываться от фильтров и не гадать, что там близы намудрили.
2
24
5 лет назад
Отредактирован prog
2
NazarPunk, отказываться есть смысл тольо от использования анонимных функций в фильтрах - один раз записать фильтр в переменную и использовать никто не мешает.
3
32
5 лет назад
3
NazarPunk, нужно отказыватся от луа и 1.31 до рефорджа и устранения всех проблем, то завтра близзарды сделают патч на котором будет утекать все и фаталить мили карты через 15 минут игры, будем как в том анекдоте, плакать, колоться и есть кактус?
0
28
5 лет назад
Отредактирован PT153
0
фильтры не текут
В Lua текут, в JASS нет, выясняли уже.
И лучше заносить фильтры в глобалки, тогда они доступны везде, даже до место определения фильтра. А вместо Condition советую использовать Filter, букв меньше.
0
8
5 лет назад
Отредактирован Castiel
0
PT153:
фильтры не текут
В Lua текут, в JASS нет, выясняли уже.
И лучше заносить фильтры в глобалки, тогда они доступны везде, даже до место определения фильтра. А вместо Condition советую использовать Filter, букв меньше.
Все конечно хорошо, но если Filter(function()) будет занесена глобалку,вне триггера, то использовать локалки триггера в фильтре уже не возможно и нужно нужное заносить в глобалки. А если допустим таймер каждые 0.05 сек вызывает группу, то если все локалки будут заменены глобалками и использованы в глобальном фильтре, не будет ли фарша, когда глобалка перебивается другим игроком вызвавшим таймер, вот к примеру
P=nil

F=Filter(function())
	local f=GetFilterUnit()
	if IsUnitAlly(f,P) then
		какой то код
	end
end)

function TRG()
	local ab=GetSpellAbilityId()
	local u=GetTriggerUnit()

	if ab==A000 then
		local t=CreateTimer()
		SavePlayerHandle(hash,GetHandleId(t),0,GetOwningPlayer(u))
		TimerStart(,0.05,true,function()
			local t=GetExpiredTimer()
			local p=LoadPH(hash,GetHandleId(t),0)
			local g=CreateGroup()
			P=p
			GroupEnumUnitsInRange(group,500,500,500,F)
			DestroyGroup(g)
			if какое то условие then
				DestroyTimer(t)
				Flush....
			end
	end)
	
end
0
28
5 лет назад
Отредактирован PT153
0
не будет ли фарша, когда глобалка перебивается другим игроком вызвавшим таймер, вот к примеру
Не будет, на этом построен vJass.
А так да, при занесении в глобалку фильтр пне может быть кложуром.
Можно так, но тут снова каждый раз будет создаваться новый объект.
function u (p, id)
    B = Condition(function()
	    if p == GetOwningPlayer(GetFilterUnit()) and id == GetUnitId(GetFilterUnit()) then

	    end
    end)

	GroupEnumUnitsInRange(group, 500, 500, 500, B)
end
А ещё в фильтрах групп работает всякие GetTriggerUnit и так далее, их даже передавать не надо.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.