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

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

 
NETRAT

offline
Опыт: 83,762
Активность:
FellGuard не-а, все равно работать не будет, ибо функция будет вызываться не в конце а внутри =\

Dragoon другого выхода нет, разбивать таймером, скажем по 1000 итераций в каждом
Старый 03.05.2006, 13:23
FellGuard
Losyash
offline
Опыт: 39,547
Активность:
Цитата:
ибо функция будет вызываться не в конце а внутри =\
Ниасилил... Это же по идее две разные ф-ии?
Тоесть,
Код:
loop
            exitwhen j > 200
            call BitwiseXOR( 999999, 999999 )
            set j = j + 1
        endloop

разбивается на четыре ф-ии по j > 50
Как может это закупорить вар?
Единственный недостаток - лишний вызов ф-ии, но при нечастом и немассовом использовании конструкции его можно опустить..

FellGuard добавил:
А , все допер... =\

FellGuard добавил:
NETRAT, а если вот тут то и использовать ExecuteFunction()??? Или проще представить ф-ию в наборе триггеров (можно текстовых) и в конце периода в j=50 звать ConditionalTriggerExecute()?
Старый 03.05.2006, 13:58
Dragoon

offline
Опыт: 544
Активность:
А что можете сказать насчет моего предпоследнего поста, решение этого вопроса путем использования динамически создаваемых триггеров ? Какие у него недостатки ?

Dragoon добавил:
В общем данным методом я смог прогнать вот такой цикл и он не повис и не самозавершился.
Код:
loop
        exitwhen i > 1000
        call TriggerSleepAction(0)            
        set j = 0
        loop
            exitwhen j > 500
            
            set udg_Flag = false            
            call TriggerExecute(ttrigger)
            loop
                exitwhen (udg_Flag == true)
            endloop            
            set j = j + 1
        endloop                
        set i = i + 1

    endloop

Отредактировано Dragoon, 03.05.2006 в 14:34.
Старый 03.05.2006, 14:19
NETRAT

offline
Опыт: 83,762
Активность:
ExecuteFunction() вроде бы вызывает функцию в отдельном потоке - то есть если грамотно использовать то по идее должно помогать

Dragoon или я не понял, или это мало чем отличается от тех же таймеров с 0 интервалом - фактически это то же самое что и запустить новый поток - то есть основной принцип разрешения этой проблемы
Старый 03.05.2006, 14:54
Dragoon

offline
Опыт: 544
Активность:
Отличается. Здесь присутствует всего два потока - главный и побочный, причем побочный вызывается столько раз, сколько необходимо главному. Тут не используется ни одного таймера и нет необходимости использовать РБ и тому подобное, так как выглядит достаточно естественно с точки зрения человека, читающего код - просто выполняется вызов функции не напрямую. а через некоторую оболочку. Ну и выполняется ожидание, пока отработает эта функция. Т.е. никаких проблем синхронизации , перемешивания данных. И кстати, этот метод абсолютно не лагает, так как время тратится лишь на прямое вполнение кода. Дополнительно время тратится лишь на создание триггера в самом начале функции и уничтожение его в конце (кстати, я правильно уничтожаю его - TriggerClearActions ? ).

Dragoon добавил:
Вот ... http://xgm.guru/forum/showthread.php?p=88748#post88748
Старый 03.05.2006, 17:20
zibada

offline
Опыт: отключен
сорри, если что не в тему, я все внимательно не читал...

call TriggerSleepAction(0) паузит поток вовсе не на 0, а на вполне реальный промежуток времени в ~0.1с.
с таймерами таких эффектов нет.

длинные действия удобно разбивать на несколько этапов с помощью ExecuteFunc, которая сбрасывает счетчик, и отрабатывает моментально.

Цитата:
Дополнительно время тратится лишь на создание триггера в самом начале функции и уничтожение его в конце (кстати, я правильно уничтожаю его - TriggerClearActions ? ).

DestroyTrigger()
Старый 03.05.2006, 17:29
Dragoon

offline
Опыт: 544
Активность:
Хе, а я честно говоря думал, что там проверка стоит , если промежуток <= 0 , то return....
и спасиб за DestroyTrigger :)
Старый 03.05.2006, 18:29
NETRAT

offline
Опыт: 83,762
Активность:
DimonT честно, не уверен что ExecFunc помогает - каки образом нужно бить вложенность типа
Funct1
{
последовательность функций
}
Funct2
{
loop
Funct1(Looper)
}
то есть где использовать ExecFunc?
Dragoon не, в варе все так - минимальные интервалы проверяются через константу-трешхолд. В качестве яркого примера глянь триггерную функцию Wait в Blizzard.j (по ней часто встречается фразы типа "Вот какая Wait классная функция - жаль что интервал меньше чем 0.1 сек поставить нельзя..."
Старый 04.05.2006, 01:12
FellGuard
Losyash
offline
Опыт: 39,547
Активность:
NETRAT
Цитата:
"Вот какая Wait классная функция - жаль что интервал меньше чем 0.1 сек поставить нельзя..."
:lol: Действительно, вэйты работают некорректно, а если уж его запихать в цикл, то савсем плохо..
Вообще, мне нравится вариант Dragoonа. Наверно из-за своей простоты - таким макаром можно разложить сколь угодно великое количество повторов без мудростей с таймерами, лагов и автостопа.
NETRAT, приведи плиз пример того же кода только чрез таймер, сильно хочется взглянуть на альтернативу...
Старый 04.05.2006, 06:23
zibada

offline
Опыт: отключен
NETRAT
Код:
Funct1
{
последовательность функций
}
Funct2
{
loop
...
set udg_i = i
call ExecuteFunc("Funct1")
.....
}

ну или через кэш счетчик передавать...


то же через таймеры:
Код:
function Funct1 takes nothing returns nothing
   local timer tm = GetExpiredTimer()
   local integer i = GetStoredInteger(udg_cache, H2S(tm), "i")

   if (i > max_i) then
     // что делать по окончании цикла
     call DestroyTimer(tm)
     return
   endif

   .... // шаг цикла

   call StoreInteger(udg_cache, H2S(tm), "i", i + 1)
endfunction

function Funct1 takes nothing returns nothing
    local timer tm = CreateTimer()
    call StoreInteger(udg_cache, H2S(tm), "i", 0)
    call TimerStart(tm, 0.00, true, function Funct1)
endfunction
Старый 04.05.2006, 09:48
Sergey
Старейший
offline
Опыт: 43,563
Активность:
Наверное прочитал не очень внимательно, но совершенно не понял, щзачем вообще связываться со строками? war3 со строками вообще плохо работает. А тут полно операций вроде склеивания, перевода строки в число и наоборот.
Не проше ли так:
  1. При помощи цикла перевести число в двоичную систему, но результат записать в глобальный массив типа boolean.
Например так:
mas1[1]= false
mas1[2]= true
mas1[3]= true
mas1[4]= true
n1=4 - число задействованных разрядов
  • соответствует числу 14 (1110b)
  1. Аналогичную операцию проделать с другим числом.
mas2[1]= ...
mas2[2]= ...
mas2[3]= ...
...
n2=... - число задействованных разрядов
  1. берем цикл от 1 до max(n1,n2). В цикле производим нужную логическую операцию (and,or,xor и т.д. - по заданным правилам).
Результат помещаем в третий массив.
  1. Переводим число, записанное в итоговом массиве в integer.
Все операции делаются в рамках одной функции с несколькими циклами. Никаких рекурсий.
Замечу, что при желании можно обойтись 1 локальным массивом, в который определенным образом записывать все три числа. Кроме того, чтобы уменьшить (if then else), можно указать тип массиву не boolean, а integer. Получится довольно таки компактный алгоритм и быстрая функция.
Старый 04.05.2006, 09:54
NETRAT

offline
Опыт: 83,762
Активность:
DimonT ну да, я так и делал, но результат не отличался от того на котором обрыв происходит
Старый 04.05.2006, 10:05
Dragoon

offline
Опыт: 544
Активность:
Sergey, вот ты говоришь, что вар медленно работает со строками, а попробуй написать тестик, который какую либо операцию будет прогонятиь много-много раз. Например то же самое склеивание строки. Скорость ненамного ниже, чем на языках высокого уровня.

Далее, а как ты думаешь, человеку, который будет пытаться воспользоваться твоим вариантом системы будет вообще удобно делать ввод-вывод данных (не конечных типа integer, а промежуточных)? Т.е. ему придется писать еще пару функций для представления результатов операций в удобоваримом виде. Да и чем отличается строка от массива (массива символов) ?????? Опять же, протестируй. Увидишь весьма интересные результаты. Скорость работы просто одинаковая....

Dragoon добавил:
И кстати,
Цитата:
глобальный массив типа boolean

ммм, как универсально получится :) Своеобразная возможность - производить только 1 операцию максимум в единицу времени. В JASS ведь нельзя передавать массивы в качестве параметров функции ?

Dragoon добавил:
Хотя при некотором желании это возможно - RB рулит.

Отредактировано Dragoon, 04.05.2006 в 12:58.
Старый 04.05.2006, 12:46
Sergey
Старейший
offline
Опыт: 43,563
Активность:
Dragoon, я знаю о чем говорю. Работа со строками намного медленнее, чем с числами. Предлагаю тебе самому провести эксперимент: реализовать 2 способа: перегонять число в строку и в массив. Создай триггер, который будет проводить операцию первым и вторым способом N раз в секунду. Постепенно увеличивай число N, чтобы добиться торможения в игре. Сопоставь число N для первого и второго способа. Думаю, ты будешь удивлен результатом.

Кроме того, при работе со строками в jass возникают драцкие утечки - результат халтурного программирования blizzard. Чем меньше работаешь со строками - тем лучше. Если можно обойтись без строк - значит лучше сделать без них.

Функции для представления промежуточных результатов - не такая уж сложная вещь.

Что касается глобальности массива - ну замени глобальный массив типа boolean на локальный массив типа integer. Для каждого запуска функции будет создан свой массив. Тогда операцию можно будет производить сколько угодно раз одновременно.
Старый 04.05.2006, 13:04
Dragoon

offline
Опыт: 544
Активность:
А я и не говорил, что работа с числами медленнее, чем со строками... это изначально бредовое утверждение. Я сказал, что строка - это массив символов. Да и честно говоря, когда 1 функция XOR(999999,999999) выполняется быстрее, чем за 0,000 сек и после 6 часов работы в цикле не подтормаживает систему - чего то это да стоит. Нет смысла переписывать алгоритм, когда он оправдывает себя

Dragoon добавил:
а тестик я писал - забивал массив со ста ячейками цифрами 0 и строку символами "0". Далее засекал, сколько выполняется 1 перевод цифры 0 из числа в строку и в соответствии с этим делал вычисления скорости.
Старый 04.05.2006, 13:53
NETRAT

offline
Опыт: 83,762
Активность:
Цитата:
строка - это массив символов
В жассе-таки немного по-другому. Кстати говоря, тут символы двухбайтовые
Старый 04.05.2006, 14:01
zibada

offline
Опыт: отключен
тип string в джассе - это вовсе никакой не массив символов, а всего лишь номер в таблице строк =) прямого доступа к которой средствами джасса нет.
поэтому, например, сравнение строк через == выполняется не медленнее, чем сравнение 2-х интов =)
и не двухбайтовые, а utf-8, английские символы вполне себе однобайтовые.
Старый 04.05.2006, 16:57

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

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

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

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



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