есть 3 таймерных кода, по которым есть вопросы
код 1:
globals
timerdialog TestDialog
endglobals

function Test1 takes nothing returns nothing
call BJDebugMsg("11")
//call DestroyTimerDialog(TestDialog)
call BJDebugMsg("22")
//if IsTimerDialogDisplayed(TestDialog) then
//call BJDebugMsg("true")
//endif
call BJDebugMsg("33")
endfunction
  1. цель - удалить все таймер-диалоги с экрана
  2. запуск -test1 из чата - получаем прекрасную выписку прохождения по коду 11 22 33
  3. если убрать "//" между 11 и 22 - то
  • если перед запуском -test1 на экране не было таймер-диалога - карта частично перестает работать, выписка покажет 11 без 22
  • если перед запуском -test1 на экране был 1 таймер-диалог - то он уничтожается - и дальше в карте всё работает как и должно, выписка покажет 11 22 33
  • если перед запуском -test1 на экране было несколько таймер-диалогов - то уничтожается только последний созданный и дальше все работает как и должно, выписка 11 22 33
  1. если убрать "//" между 22 и 33 - то в выписке получим только 22, а вот 33 уже не отпишется
  2. если через функцию Test0 (запущенную из чата через -test0) создать и сразу удалить таймер, то это как бы "активирует" глобалку с таймером? и после этого в Test1 между 11 и 22 код не останавливается, между 22 и 33 код тоже не останавливается. то есть как будто глобалки инициализируются call InitGlobals() не перед полной загрузкой карты, а после первого присвоения значения. а пока значение ни разу не присвоено к TestDialog - то это вообще какой-то noname мимо проходил и никакого отношения к таймердиалогу не имел никогда
globals
timer t=CreateTimer()
timerdialog TestDialog
endglobals

function Test0 takes nothing returns nothing
TimerStart(t,60,false,null)
set TestDialog=CreateTimerDialogBJ(t,"Time")
call DestroyTimerDialog(TestDialog)
endfunction
вопросы:
1-1 как вообще использовать нативку IsTimerDialogDisplayed(TestDialog) ? если таймер-диалог показан на экране - то она выдаст "true", а если таймер не показан на экране то вместо выдачи "false" код тупо остановится и не пойдёт дальше выполняться. (но как описано в п.5 - код остановится только если в игре до этого не создавался ни один таймер)?
1-2 как всё-таки удалить хотя бы один (либо все имеющиеся на экране) таймер-диалог, если до запуска функции неизвестно показан он на экране или нет. для всех таймеров не нашел решение, а для одного существующего таймера подходит только два решения? call DestroyTimerDialog(GetLastCreatedTimerDialogBJ()) и DestroyTimerDialog(TestDialog) ?
код 2:
globals
timer t=CreateTimer()
timerdialog TestDialog=null
endglobals

function Test3 takes nothing returns nothing
TimerStart(t,60,false,null)
set TestDialog=CreateTimerDialogBJ(t,"Time")
endfunction
вопросы:
2-1 если создать несколько таких таймер-диалогов подряд через -test3 -test3 -test3, то т.к. у них один и тот же -null-handle (code handlerFunc), то к ним уже никак не обратиться и поштучно не удалить? (или все разом или поштучно через цикл)
код 3:
call PauseTimer(t)
call DestroyTimer(t)
вопросы:
3-1 зачем перед удалением таймера его останавливают? это всё равно что перед написанием integer a = null сначала эту a обнулять - a = 0, т.е. бессмысленно?
итого 4 вопроса:
1-1 - решение найдено в процессе написания этого вопроса - нужно правильно объявлять - timerdialog TestDialog=null
1-2 - решение найдено только для 1 шт, а не для всех
2-1 - решение найдено при поддержке Borodach - ответ такой же как и для вопроса 1-2 - можно работать только с последним окном (если мы никак не могли повлиять на процесс создания окон), а если могли повлиять - то можно работать со всеми окнами
3-1 - решение пока не найдено
`
ОЖИДАНИЕ РЕКЛАМЫ...
1
13
1 год назад
Отредактирован Borodach
1
2.1 Тебе нужен массив и каждий записать в пустую ячейку
globals 
timerdialog tDialog array [20] //- 20 макс количество таймеров
endglobals
// Записать новый таймер диалог
local integer i = 0
loop
     exitwhen 20 >= i
if tDialog[i] == null then
     tDialog[i] = new CreateDialog()
     exithen true
endif
set i = i + 1
endloop

// Удалить таймер диалоги
local integer i = 0
loop
     exitwhen 20 >= i
if tDialog[i] != null then
     tDialog[i] = DestroyDialog()
endif
set i = i + 1
endloop
endif
     
3.1 Помню читал, что в редких случаях если не запаузить таймер, игра может вызвать внутрисистемную ошибку. Мне не повезло с такой ошибкой встретится, но на всякий также на паузу ставил
0
14
1 год назад
Отредактирован host_pi
0
Borodach:
P.S. в 2.1 имелся ввиду такой случай, когда уже созданы три таймер-диалога и посажены на один триггер, на единый таймер. три окошка с одинаковым таймером. т.е. когда мы уже оказались в такой ситуации и не можем больше повлиять на создание таймер-диалогов. и если попытаться 3 раза удалить, то вместо трёх удалится только один, а остальные 2 останутся висеть и никак не удаляются. вопрос состоял в том - в данной ситуации есть ли возможность удалить эти висячие 2 окошка? или ответ будет - нет, эти висячие 2 окошка никак не удалить больше, кроме как перезапуском карты?
TimerStart(t,60,false,null)
set TestDialog=CreateTimerDialogBJ(t,"Time")
set TestDialog=CreateTimerDialogBJ(t,"Time")
set TestDialog=CreateTimerDialogBJ(t,"Time")
// мы тут
call DestroyTimerDialog(GetLastCreatedTimerDialogBJ())
call DestroyTimerDialog(GetLastCreatedTimerDialogBJ())
call DestroyTimerDialog(GetLastCreatedTimerDialogBJ())
call DestroyTimerDialog(TestDialog)
call DestroyTimerDialog(TestDialog)
call DestroyTimerDialog(TestDialog)
1
13
1 год назад
Отредактирован Borodach
1
host_pi, Используй массив как уже и сказал. Дело в том что глобальная переменная перезаписивается. Для каждого окошка должна быть своя переменная
globals
timerdialog TestDialog array [3]
endglobals

set TestDialog[0]=CreateTimerDialogBJ(t,"Time")
set TestDialog[1]=CreateTimerDialogBJ(t,"Time")
set TestDialog[2]=CreateTimerDialogBJ(t,"Time")
// мы тут

call DestroyTimerDialog(TestDialog[0])
call DestroyTimerDialog(TestDialog[1])
call DestroyTimerDialog(TestDialog[2])
0
14
1 год назад
Отредактирован host_pi
0
Borodach:
всё, что выше строки "// мы тут" нельзя редактировать по условию вопроса
в вопросе 2-1 таймер и окно уже заданы как
timer t=CreateTimer()
timerdialog TestDialog=null
и не подлежит изменению
вообще говоря, почему-то варкрафт для окна TestDialog при повторном создании такого же - не заменяет его вместо ранее созданного, а добавляет новое. т.е. на одной переменной TestDialog висят много окон. в этом и суть вопроса
т.е. если перевести на числа и провести аналогию:
у нас есть integer i . мы пишем i = 1 , i = 2 , i = 3 . по нормальной логике - i заменяется с 1 на 2, потом i заменяется с 2 на 3 - и в итоге у нас i = 3 , а варкрафт вместо замены просто сам создает три независимых i = 1 i = 2 i = 3 , потом мы пишем i = 0 , он одну i из трёх обнуляет, а у двух псевдо-i старые значения остаются. и это у него как то всё хранится
надеюсь мне не предложат создать массив из a [i]?
1
13
1 год назад
1
host_pi, Ты хочешь приготовить яишницу не добавляя яйца. Добавлю еще вариант с добавлением в код выше "мы тут," не изменением.

globals
timer t = CreateTimer()
timerdialog TestDialog = null
timerdialog TestDialogArr array [3]
endglobals

TimerStart(t,60,false,null)
set TestDialog=CreateTimerDialogBJ(t,"Time")
set TestDialogArr[0] = TestDialog
set TestDialog=CreateTimerDialogBJ(t,"Time")
set TestDialogArr[1] = TestDialog
set TestDialog=CreateTimerDialogBJ(t,"Time")
set TestDialogArr[2] = TestDialog
// мы тут

call DestroyTimerDialog(TestDialogArr[0])
call DestroyTimerDialog(TestDialogArr[1])
call DestroyTimerDialog(TestDialogArr[2])
0
14
1 год назад
Отредактирован host_pi
0
Ты хочешь приготовить яишницу не добавляя яйца.
наоборот. я не хочу готовить яишницу (я ковыряюсь в яишнице, созданной вариком) и не хочу создавать 3 "умных" отдельных окна. я хочу разобраться как эти 3 окна создал варкрафт и что с ними можно сделать. именно разобраться - могу ли я что-то с этими уже созданными (не мной как я захотел, а варкрафтом через функцию -test3-test3-test3) окнами сделать или нет
версия выше с перехватом через
set TestDialogArr[0] = TestDialog
уже больше похоже на правду, она не меняет изначальную структуру создания окон
только все 3 новых строчки с перехватом выше фразы "мы тут", т.е. этакое компромиссное решение
из чего делаю вывод по вопросу 2-1
2-1:
что после создания подряд трёх окон (при условии что во время создания мы рядом не стояли и переменную не копировали себе в массив) - мы не можем к ним никак обратиться и что-то с ними сделать. а можем только с самым последним созданным



по поводу вопроса 3-1 :
выявлено опытным путём, что DestroyTimer(t) нежелательно пользоваться, т.к. после этой нативки надо заново создавать таймер, как мы это делали в инициализации глобалок через timer t=CreateTimer()
call DestroyTimer(t)
set t=CreateTimer()
TimerStart(t,60,false,null)
при этом же - конечно же если мы юзаем PauseTimer(t), то сама переменная не уничтожается, а остается таймером, с которым можно опять работать, т.е. через паузу результат примерно такой же но более щадящий.
call PauseTimer(t)
TimerStart(t,60,false,null)
в отличие от самого окна - после уничтожения нам уже не требуется заново назначать окно, как мы это делали при инициализации глобалок, а можно сразу создавать готовое окно
DestroyTimerDialog(GetLastCreatedTimerDialogBJ())
DestroyTimerDialog(TestDialog)
set TestDialog=CreateTimerDialogBJ(t,"Time")

и еще дополнение:
уничтожение таймерного окна не уничтожает и не останавливает сам таймер
т.е. окна не будет, а таймер продолжит тикать и будут срабатывать все привязанные к этому таймеру функции т.е. нужно уничтожать и окно и останавливать таймер
1
4
1 год назад
Отредактирован DazzleFirst
1
CreateTimerDialogBJ рассказываем и видим, что оно создаёт при вызове TimerDialog.
Если вызвать функцию дважды, то создаст 2 отдельных окна таймера привязанных к одному таймеру. Завершив таймер уничтожить можно будет только последнее окно, если первое небыло привязано к какой либо переменной, то оно (первое) утекает.
В чем загадка то?
0
14
1 год назад
Отредактирован host_pi
0
если первое небыло привязано к какой либо переменной, то оно (первое) утекает.
это и есть ответ, который нужен был на вопрос 2-1
В чем загадка то?
с таким вопросом можно весь раздел /qa закрыть, т.к. ответ на любой вопрос кому-нибудь да известен и не является загадкой для него, а вот для вопрошающего как раз наоборот
1
13
1 год назад
1
вообще говоря, почему-то варкрафт для окна TestDialog при повторном создании такого же - не заменяет его вместо ранее созданного, а добавляет новое. т.е. на одной переменной TestDialog висят много окон. в этом и суть вопроса
Систама внутри создает окно. Но тебе нужно сохранить окно в переменную(тумбочку), чтоб потом дать програме понять в какой переменной(тумбочке) хранится твое окно. А у тебя одна переменная(тумбочка) на все окна. И когда ты создаешь новое окно и кладешь в переменную(тумбочку) то програма выбросит старое окно потому чтот новое не поместится.
0
14
1 год назад
0
вот нашел инфу по вопросу в 1 ом сообщении
Игровые объекты
Мы рассмотрели переменные, и как их обнулять, переменная - это ссылка на определенный игровой объект, но обнуление переменной не значит, что удаляется и объект по ссылке из переменной, объект нужно удалять отдельно (ДО(!) обнуления переменой) с помощью специальной функции. т.к. иначе после обнуление переменной ссылка на объект потеряется, и его нельзя будет удалить.
0
26
1 год назад
Отредактирован Hate
0
по поводу 3-1, то так делают из-за якобы бага что таймер продолжает срабатывать после уничтожения. лично я никогда с этим не сталкивался/либо проблем не вызывало
а так, вам бы в логику банальную хотяб уметь, вы действительно хотите готовить яичницу без яиц
выявлено опытным путём, что DestroyTimer(t) нежелательно пользоваться, т.к. после этой нативки надо заново создавать таймер, как мы это делали в инициализации глобалок через timer t=CreateTimer()
кто бы мог подумать, что уничтожение таймера уничтожает таймер?..
Чтобы оставить комментарий, пожалуйста, войдите на сайт.