XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Закрытая тема
 
StoneHeartis
Kicked by ScorpioT1002
offline
Опыт: 1,009
Активность:
Утечки в коде.
В общем, выкладываю сей карту, надеясь, что кто-нибудь помжет отыскать в моем быдлокоде коде лулзы утечки. Итак. (уже голову сломал, мб дело в потоке через глобалку - если да, то предложить лучший вариант)
scope Light initializer Init
globals
hashtable ht=InitHashtable()
unit u_g
endglobals

function Trig_Lighing_Timer takes nothing returns nothing
local timer t=GetExpiredTimer()
local unit u=LoadUnitHandle(ht, GetHandleId(t), 0)
local unit u2=LoadUnitHandle(ht, GetHandleId(t), 3)
local lightning l=LoadLightningHandle(ht, GetHandleId(t), 1)
local real time=LoadReal(ht, GetHandleId(t), 2)
local real d=SquareRoot( (GetUnitX(u)-GetUnitX(u2))*(GetUnitX(u)-GetUnitX(u2))+(GetUnitY(u)-GetUnitY(u2))*(GetUnitY(u)-GetUni​tY(u2)))
set time=time-0.025
if time == 0. or d > 600. or IsUnitVisible(u2, GetOwningPlayer(u)) == false or GetWidgetLife(u2) <= 0.405 then
call BJDebugMsg("Комплитед")
call DestroyLightning(l)
call FlushChildHashtable(ht, GetHandleId(t))
call DestroyTimer(t)
call SetUnitUserData(u2, 0)
elseif IsUnitVisible(u2, GetOwningPlayer(u)) and GetWidgetLife(u2) > 0.405 then
call BJDebugMsg("Дмг")
call SaveReal(ht, GetHandleId(t), 2, time)
call MoveLightning(l, true, GetUnitX(u), GetUnitY(u), GetUnitX(u2), GetUnitY(u2))
call UnitDamageTarget(u, u2, 0.4*I2R(GetUnitAbilityLevel(u, 'A000')), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
endif
set t=null
set u=null
set u2=null
set l=null
endfunction

function Trig_Lighing_Group takes nothing returns boolean
    local unit u=GetFilterUnit()
    local timer t=null
    local lightning l=null
    local real time=5.
    local unit u2=u_g
    if GetUnitUserData(u2) == 0 and IsUnitVisible(u2, GetOwningPlayer(u)) and GetUnitAbilityLevel(u, 'A000') >0 and GetWidgetLife(u2) > 0.405 then
    set t=CreateTimer()
    set l = AddLightning("CLPB", true, GetUnitX(u), GetUnitY(u), GetUnitX(u2), GetUnitY(u2))
    call SaveUnitHandle(ht, GetHandleId(t), 0, u)
    call SaveLightningHandle(ht, GetHandleId(t), 1, l)
    call SaveReal(ht, GetHandleId(t), 2, time)
    call SaveUnitHandle(ht, GetHandleId(t), 3, u2)
    call SetUnitUserData(u2, 1)
    call TimerStart(t, 0.025, true, function Trig_Lighing_Timer)
    endif
    set u=null
    set t=null
    set l=null
    set u2=null
    return false
endfunction

function Trig_Lighing_Actions takes nothing returns boolean
    local group g=null
    local unit u=null
    set u_g=u
    if GetUnitAbilityLevel(GetTriggerUnit(), 'A000')  == 0 then
    set g = CreateGroup()
    set u = GetTriggerUnit()
    set u_g = u
    call BJDebugMsg("Cast")
    call GroupEnumUnitsInRange(g, GetUnitX(u), GetUnitY(u), 600., Condition(function Trig_Lighing_Group))
    call DestroyGroup(g)
    set g=null
    set u=null
    endif
    
    return false
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition(function Trig_Lighing_Actions) )
    set t=null
endfunction
endscope
Прикрепленные файлы
Тип файла: w3x 2.w3x (19.2 Кбайт, 11 просмотров )

Отредактировано StoneHeartis, 09.06.2010 в 18:46.
Старый 08.06.2010, 23:26
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
StoneHeartis, первое что заметил еще не открывая карту это проврка а уровень спела == 0
if GetUnitAbilityLevel(u, 'A000') == 0 then
странно и после ты наносишь им дмж то-есть наносишь 0 эпично
0.1*I2R(GetUnitAbilityLevel(u, 'A000'))
Старый 08.06.2010, 23:46
StoneHeartis
Kicked by ScorpioT1002
offline
Опыт: 1,009
Активность:
AlexKARASb, нет. читать лучше спел. это проверяется, чтобы юнит который скастовал был != юниту у которого эта аура.
дальше пикается вокргу этого юнита. если вокруг него есть этот герой с нужной аурой, то далее действия.
зы глянь карту, так проще. только кол-во юнитов поубавь, чтобы не увидеть страшный лагодром...
Старый 08.06.2010, 23:48
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
все теперь понял почему..
AlexKARASb добавил:
0.01
минимально .025
+
call GroupEnumUnitsInRange(g, GetUnitX(u), GetUnitY(u), 600., null)
call ForGroup(g, function Trig_Lighing_Group)
call GroupClear(g)
call DestroyGroup(g)
убрал бы куча строк и сделал бы это
call GroupEnumUnitsInRange(g, GetUnitX(u), GetUnitY(u), 600., Condition(function Trig_Lighing_Group))
call DestroyGroup(g)


//а эт замена старой
function Trig_Lighing_Group takes nothing returns boolean
    local unit u=GetFilterUnit()
    local timer t
    local lightning l
    local real time=5.
    local unit u2=u_g
    if GetUnitUserData(u2) == 0 and IsUnitVisible(u2, GetOwningPlayer(u)) and GetUnitAbilityLevel(u, 'A000') >0 and GetWidgetLife(u2) > 0.405 then
    t = CreateTimer() //создавай если прошел проверку, а то не пройдя таймер висеть будет
    set l = AddLightning("CLPB", true, GetUnitX(u), GetUnitY(u), GetUnitX(u2), GetUnitY(u2))
    call SaveUnitHandle(ht, GetHandleId(t), 0, u)
    call SaveLightningHandle(ht, GetHandleId(t), 1, l)
    call SaveReal(ht, GetHandleId(t), 2, time)
    call SaveUnitHandle(ht, GetHandleId(t), 3, u2)
    call SetUnitUserData(u2, 1)
    call TimerStart(t, 0.025, true, function Trig_Lighing_Timer)
    endif
    set u=null
    set t=null
    set l=null
    set u2=null
	return false
endfunction
AlexKARASb добавил:
0.1*I2R(GetUnitAbilityLevel(u, 'A000'))
а смысл перевода то, вар при перемножении ж выполнит операцию
AlexKARASb добавил:
и да вариант не через глоб а через хеш
//set u_g=u вместо
SaveUnitHandle(ht, GetHandleId(GetExpiredTimer()), 0, u)
и таким же загрузишь ее в фильтре
LoadUnitHandle(ht, GetHandleId(GetExpiredTimer()), 0)

Отредактировано AlexKARASb, 09.06.2010 в 00:02.
Старый 09.06.2010, 00:07
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
во-первых: лучше использовать scope, нежели library (хотя как хочешь)
во-вторых: у тебя нет условия и действия (конкретно - создание и инитиализация группы и кастера в локалки проиходят все время, когда кто-нибудь приводит способность в действие), решение:
function Conditions takes nothing returns boolean
    local group g=null
    local unit u=null
    
    if GetUnitAbilityLevel(u, 'A000')  == 0 then
        set g = CreateGroup()
        set u = GetTriggerUnit()
        set u_g = u
        call BJDebugMsg("Cast")
        call GroupEnumUnitsInRange(g, GetUnitX(u), GetUnitY(u), 600., null)
        call ForGroup(g, function Trig_Lighing_Group)
        call GroupClear(g)
        call DestroyGroup(g)
        g = null
        u = null
    endif
    
    return false
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition(function Conditions) )
    set t=null
endfunction
вот так будет лучше, быстрее , и красивее.
в-третьих: null-фильтр в группе - не есть хорошо.
дальше не смотрел
Старый 09.06.2010, 07:34
StoneHeartis
Kicked by ScorpioT1002
offline
Опыт: 1,009
Активность:
set u_g=u вместо
AlexKARASb, к группе нельзя приаттачить. а в остальном же, как видишь, используется хэш. (глобалка используется только для потока)
Старый 09.06.2010, 08:50
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
к группе нельзя приаттачить.
возьми и проверь, раньше тоже думал что нельзя
быстрее
самые быстрые фильтры, про красивее - 2 строки красивее 4ех ^-^
AlexKARASb добавил:
(глобалка используется только для потока)
знаю что для потока, просто ты написал это:
мб дело в потоке через глобалку - если да, то предложить лучший вариант)
вариант не лучше дал, но быстрее, и надежнее если у тебя муи
AlexKARASb добавил:
в принципе единственной ошибкой, именно ошибкой, это слишком малый период, это и вызывало лаги
остальное только дело вкуса(скорость кода, итд)
Старый 09.06.2010, 10:07
StoneHeartis
Kicked by ScorpioT1002
offline
Опыт: 1,009
Активность:
AlexKARASb, осталное - оптимизация. И она у меня страдает. Что-то я не совсем понял как аттачить. Ладно, перепишу, апдейтну код. Потом и увидишь.
P.s. Переписал код, все равно утечки где-то есть. Перемещение молнии вызывает утечки?

Отредактировано StoneHeartis, 09.06.2010 в 15:54.
Старый 09.06.2010, 13:03
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
local real d=SquareRoot( (GetUnitX(u)-GetUnitX(u2))*(GetUnitX(u)-GetUnitX(u2))+(GetUnitY(u)-GetUnitY(u2))*(GetUnitY(u)-GetUni​&#8203;tY(u2)))
d > 600.
сменяем на это:
local real x=GetUnitX(u)
local real y=GetUnitY(u)
local real x2=GetUnitX(u2)
local real y2=GetUnitY(u2)
local real d=(x-x1)*(x-x1)+(y-y1)*(y-y1)
if d > 3600.00 
кароч ты обьявляешь 2 раза реальные, + заставляешь вар не нужно считать квадрат, когда ты сам можешь сразу возвести в квадрат
AlexKARASb добавил:
код новый скинь
переписанный с реальными выше строками
AlexKARASb добавил:
Перемещение молнии вызывает утечки?
нет, стабильная нативка
Старый 09.06.2010, 17:16
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
Перемещение молнии вызывает утечки?
нет, стабильная нативка
лол? это бж
перемещение на нативках - уничтожении молнии; создание новой на новом месте
Старый 09.06.2010, 18:16
krosaf4eg

offline
Опыт: 1,859
Активность:
разве бж?
native MoveLightning takes lightning whichBolt, boolean checkVisibility, real x1, real y1, real x2, real y2 returns boolean
Старый 09.06.2010, 18:40
StoneHeartis
Kicked by ScorpioT1002
offline
Опыт: 1,009
Активность:
AlexKARASb, дак ладно считает... НО утечки то где? после 1 минуты уже начинает лагать. Вывод в коде где-то какая-то ошибка. Пересчитывание не должно повлиять по сути.
upd
упс. вышла ошибочка. в функции гурпп не должно было быть реальных с точками
Старый 09.06.2010, 18:43
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
это бж
на ф-цию что показал krosaf4eg, посмотри
НО утечки то где?
хм без кода сказать тяжеловато сам понимаешь
Пересчитывание не должно повлиять по сути.
нет но временно занимает память, и требует времени на инициирование(ничтожное но всеже.)
Старый 09.06.2010, 19:18
DioD

offline
Опыт: 45,134
Активность:
прапорщик нелогичность видимо ваш родственник, так и не понял в чём смысл сочетать хеш и юзер дату, когда эти вещи взаимоисключающие по определению, или то или другое...
кроме того вы создаёте по таймеру на каждого юнита, хотя можно создать один таймер на систему целиком, и просто двигать массив молний...
в общем вы ничего не понимаете в OOP ваше OOP говно.
Старый 09.06.2010, 20:09
StoneHeartis
Kicked by ScorpioT1002
offline
Опыт: 1,009
Активность:
AlexKARASb, код уже апдейтил давно. это он и есть.
DioD, я в ооп не понимал и не понимаю. ПИсал только с пониманием джасса. ооп тему не затрагивал.
тут только синтаксис вджасс...
Старый 09.06.2010, 20:25
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
в общем вы ничего не понимаете в OOP.
прав, но пытаемся понять, а эт главное
StoneHeartis, хороший совет дал DioD,
попробую обмозговать то что DioD сказал:
» проба
scope Light initializer Init
globals
hashtable ht=InitHashtable()
unit u_g
endglobals

struct Data
unit u
group g
endstruct

function ForGr takes nothing returns boolean
local Data D = LoadInteger(ht, GetHandleId(GetExpiredTimer()), 0)
local unit u = GetEnumUnit()
local lightning l=LoadLightningHandle(ht, GetHandleId(u), 0)
local real time=LoadReal(ht, GetHandleId(u), 1)-0.025
local real x=GetUnitX(u)
local real y=GetUnitY(u)
local real x2=GetUnitX(D.u)
local real y2=GetUnitY(D.u)
local real d=(x-x1)*(x-x1)+(y-y1)*(y-y1)
if time <= 0.00 or d > 3600.00 or IsUnitVisible(D.u, GetOwningPlayer(u)) == false or GetWidgetLife(D.u) <= 0.405 or GetWidgetLife(u) <= 0.405 then
call DestroyLightning(l)
call FlushChildHashtable(ht, GetHandleId(u))
call GroupRemoveUnit(D.g, u)
elseif IsUnitVisible(D.u, GetOwningPlayer(u)) and GetWidgetLife(D.u) > 0.405 then
call SaveReal(ht, GetHandleId(u), 1, time)
call MoveLightning(l, true, x, y, x1, y1)
call UnitDamageTarget(u, D.u, 0.4*I2R(GetUnitAbilityLevel(u, 'A000')), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL, null)
endif
set u=null
set l=null
return false
endfunction

function Lighing_Timer takes nothing returns nothing
local timer t=GetExpiredTimer()
local Data D = LoadInteger(ht, GetHandleId(t), 0)
if CountUnitsInGroup(D.g)!=0 then
call ForGroup(D.g, Condition(function ForGr))
else
call PauseTimer(t)
call DestroyGroup(D.g)
set D.u=null
set D.g=null
set D.destroy()
call FlushChildHashtable(ht, GetHandleId(t))
call DestroyTimer(t)
endif
set t=null
endfunction

function Lighing_Group takes nothing returns boolean
    local unit u=GetFilterUnit()
    local Data D = LoadInteger(ht, GetHandleId(GetExpiredTimer()), 0)
    local lightning l
    if GetUnitUserData(D.u) == 0 and IsUnitVisible(D.u, GetOwningPlayer(u)) and GetUnitAbilityLevel(u, 'A000') >0 and GetWidgetLife(D.u) > 0.405 then
    set l = AddLightning("CLPB", true, GetUnitX(u), GetUnitY(u), GetUnitX(D.u), GetUnitY(D.u))
    call GroupAddUnit(D.g, u)
    call SaveLightningHandle(ht, GetHandleId(u), 0, l)
    call SaveReal(ht, GetHandleId(u), 1, 5.00)
    call TimerStart(t, 0.025, true, function Lighing_Timer)
    endif
    set u=null
    set l=null
	return false
endfunction

function Trig_Lighing_Actions takes nothing returns nothing
    local timer t 
    local Data D 
    if GetUnitAbilityLevel(GetTriggerUnit(), 'A000') == 0 then
        set D = Data.create()
        set t = CreateTimer()
        set D.g = CreateGroup()
        set D.u = GetTriggerUnit()
        call SaveInteger(ht, GetHandleId(GetExpiredTimer()), 0, D)
        call GroupEnumUnitsInRange(D.g, GetUnitX(D.u), GetUnitY(D.u), 600.00, Condition(function Lighing_Group))
        call SaveInteger(ht, GetHandleId(t), 0, D)
    endif
    set t=null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition(function Trig_Lighing_Actions) )
    set t=null
endfunction
endscope
AlexKARASb добавил:
сочетать хеш и юзер дату
возможно назовете копитаном, или кем нибудь еще
но, объясните пожалуйста "юзер дата" что это, как использовать
Старый 09.06.2010, 20:54
Doc

offline
Опыт: 63,163
Активность:
AlexKARASb, юзер дата омг, стыдно не знать. Это то, что в гуи называется custom value. То есть некое число, уникальное для каждого юнита, причем вы можете его менять.
Старый 09.06.2010, 22:26
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
custom value.
и с этим знаком только по названию, узучать когда-то пробовал но узнав что это старо перестал
стыдно не знать.
ничего постыдного не вижу
пробелы в знаниях jass восполняю онли по надобности, другим способом изучать не могу
Но благодарю что объяснил
Кстати на счет сабжа StoneHeartis, код менее лаговым стал?
Старый 09.06.2010, 22:46
StoneHeartis
Kicked by ScorpioT1002
offline
Опыт: 1,009
Активность:
AlexKARASb, я, конечно не шарю совсем в ооп. но ты используешь в коде метод дестрой, а сам метод не создан. поэтому жгнп выдает ошибку. Но, т.к. я не шарю, без знания ооп я не полезу править код)
Старый 09.06.2010, 22:58
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
писал в блокноте, ошибок штук 8
завтра скину код
Старый 10.06.2010, 00:05
Закрытая тема

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 19:08.