Добавлен
Недавно узнал, что у "TriggerSleepAction" есть минимальное кол-во времени, решил сделать что-то похожее при помощи таймера, т.к. везде только про него и пишут. Внутри "PolledWait" использовался TimerGetRemaining(), но у меня не получилось его реализовать, т.к. значение даже при истечении таймера у TimerGetRemaining() выходит всегда одно, условие для выхода из цикла не выполняется. Не мог бы кто подсказать, что я делаю не так.
function Trig_TESTWAIT_Actions takes nothing returns nothing
local real i = 1
local timer t
set t = CreateTimer()
call TimerStart(t, 1, false, null)
loop
exitwhen i <= 0
set i = TimerGetRemaining(t)
endloop
call RemoveUnit(gg_unit_Hpal_0000)
call DestroyTimer(t)
set t = null
set real i = 0
endfunction

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

KalaKoltes, обычная функция TriggerSleepAction работает в циклах. Здесь изобретение велосипеда не нужно, но когда нужно выполнить какое действие через промежуток времени без обрывания потока, то тут понадобятся ухищрения с таймером и передача аргументов в функцию таймера через хэш-таблицу, структуру, TimerExploit или глобалки.
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
19
6 лет назад
0
Похожие вопросы:

ответ
Impertus:
quq_CCCP:
Без локейшенов, набери
	GetRandomReal( GetRectMinX( bj_mapInitialPlayableArea ), GetRectMaxX( bj_mapInitialPlayableArea )  )
Для Y думаю догадаешся как найти...
Размер карты-то изначально известен, можно обойтись и рандомом между статичными цифирями. Думал над этим вариантом тоже, значит будем пользовать его.
nvc123:
к слову этот вообще не рабочий ибо количество итераций циклов может превысить лимит потока и тогда триггер просто обрубится
Ставить таймеры по 0.5 сек? Такого вида?
loop
        exitwhen  IsUnitDeadBJ(BET) or BECo > 20
        if (TimerGetRemaining(t) <= 0) then
            call MoveLocation( p, GetRandomReal ( X1, X2), GetRandomReal (Y1, Y2))
            call SetUnitMoveSpeed( BET, 500.00 )
            call IssuePointOrderLocBJ( BET, "move", p )
            set BECo = BECo + 0.5
            call TimerStart(t, 0.5, false, null)
        endif     
endloop
Таймер не вейт, он запустить новый Поток когда истечет, в функции старта таймера 4 параметра, таймер, время, периодичный буль и ссылка на код .
вместо null нужно вписать function Имя функции
functiom Timer_UnitMove_Expires takes nothing returns nothing
    // эта функция будет вызыватся каждые 0.50 сек. пока не остановить таймер
endfunction


function A takes nothing returns nothing
local timer t = CreateTimer( )

call TimerStart( t, 0.50, true, function Timer_UnitMove_Expires )

set t = null
endfunction
Чтобы передавать информацию между функциями нужны так называемые Аттачи, нужно прикрепить данные к триггеру или таймеру, потому что мы можем получить ссылку на них в запущенных ими потоками.
Про хештаблицу куча данных на сайте, SaveUnitHandle( хештаблица, ключ 1, ключ 2, сам юнит )
ответ
call UnitAddAbility(unit, abilcode)
local timer t = CreateTimer()
call StartTimer(t, 4, false, null)
loop
call TriggerSleepAction(0.1)
exitwhen TimerGetRemaining == 0
endloop
call UnitRemoveAbility(unit, abilcode)
за подобное положена смертная казнь
вейт плох тем что он не точен (погрешность в 0,1 секунды и работает во время паузы игры)
и тем что всякие вырезано используют его там где надо использовать таймеры
почитай про то как правильно использовать таймеры
чтобы понимать где нужен вейт а где таймер
вот две статьи
можешь посмотреть ещё статьи про связку таймер+хэш/рб но её юзать не советую т.к. стэк намного удобнее и быстрее
ответ
Sacar777, выведи после MultiboardGetItem(udg_JC_Board, i-1, 1)
на экран следующий текст
I2S(GetHandleId(q1))
I2S(GetHandleId(q2))
если q2 по каким то причинам не создаётся то это скажет об этом
стоп
а какой у тебя размер столбца стоит?
мб просто ячейка q1 перекрывает собой ячейку q2
и размер 10 это очень много
ведь в отличие от гуи тут размер в сотых указывается
то есть если в гуи размер 10 то тут должен быть 0.1
поставь в MultiboardSetItemWidth(q1, 10.00)
вместо 10.00 0.1 и проверь
если 0.1 не сработает то поставь 0.02
если и это не сработает то отпиши сюда
я тогда раскапаю свой старый мультибоард и сравню с твоим

0
13
6 лет назад
0
В оригинальном PolledWait присутствует TriggerSleepAction, чтобы избежать зависание цикла. В твоем примере цикл постоянно сверяется с таймером и зависает от превышения количества допустимых итераций, как бесконечный. Они в варе недопустимы. Если интереса данная конструкция, то можешь изучить структуру стандартного PolledWait.
Код функции
function PolledWait takes real duration returns nothing
    local timer t
    local real  timeRemaining

    if (duration > 0) then
        set t = CreateTimer()
        call TimerStart(t, duration, false, null)
        loop
            set timeRemaining = TimerGetRemaining(t)
            exitwhen timeRemaining <= 0

            // If we have a bit of time left, skip past 10% of the remaining
            // duration instead of checking every interval, to minimize the
            // polling on long waits.
            if (timeRemaining > bj_POLLED_WAIT_SKIP_THRESHOLD) then
                call TriggerSleepAction(0.1 * timeRemaining)
            else
                call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
            endif
        endloop
        call DestroyTimer(t)
    endif
endfunction
0
2
6 лет назад
0
Можно ли тогда остановить триггер на определенном моменте и возобновить при выполнении конкретного условия?
Не знал, что цикл может зависать. Пытался с его помощью "отсрочить" выполнение остатка функции, пока остаток таймера не станет равен нулю.
0
30
6 лет назад
0
Таймеры запускают привязанную функцию по своему истечению, в этой функции и нужно совершать все действия после ожидания. Да, пробрасывать локальные переменные туда нельзя.
0
13
6 лет назад
0
Clamp:
Таймеры запускают привязанную функцию по своему истечению, в этой функции и нужно совершать все действия после ожидания. Да, пробрасывать локальные переменные туда нельзя.
Если это необходимо, то нужно организовать работу с хэш-таблицей или структурой (или глобалками на крайний случай).
0
2
6 лет назад
0
Получается, просто искусственный "Wait", но с ожиданием примерно в 0.1 секунды, для того, чтобы использовать его в циклах, нельзя?
0
13
6 лет назад
0
KalaKoltes, обычная функция TriggerSleepAction работает в циклах. Здесь изобретение велосипеда не нужно, но когда нужно выполнить какое действие через промежуток времени без обрывания потока, то тут понадобятся ухищрения с таймером и передача аргументов в функцию таймера через хэш-таблицу, структуру, TimerExploit или глобалки.
Принятый ответ
0
28
6 лет назад
0
KalaKoltes, "ожидание" и "сделать через некоторое время" разные вещи
для первого есть вейт и он прекрасно справляется
для второго юзают таймеры
в твоём случае именно 2 вариант
0
2
6 лет назад
0
Понятно, спасибо
Чтобы оставить комментарий, пожалуйста, войдите на сайт.