Jump to content


Photo

Обработчик событий. Где подвох?


Best Answer vlad333000 , 21 February 2018 - 23:29

sharkman, в области видимости обработчика события нету никакой переменной "_x", нормальный код для этого будет выглядеть так:

// Наши юниты
myUnits = [pat1, pat2, pat3, pat4, ch1, ch2];

// Код нашего обработчика события
myEventHandler = {
	// Выводит какой-нибудь текст
	systemChat "Hello World!";
	systemChat str _this;

	// Удаляем ТОЛЬКО НАШ обработчик события
	// Не забывайте что по мимо вашего могут
	// быть обработчики событий и других аддонов/скриптов
	{
		_x removeEventHandler ["Fired", _x getVariable "myEventHandlerIndex"];
	} forEach myUnits;
};

// Вешаем обработчики события на юниты
{
	_x setVariable ["myEventHandlerIndex", _x addEventHandler ["Fired", myEventHandler]];
} forEach myUnits;
Go to the full post


  • Please log in to reply
16 replies to this topic

#1 OFFLINE   sharkman

sharkman

    Ефрейтор

  • Пользователи
  • 68 posts
  • Откуда:Хабаровск

Posted 21 February 2018 - 18:01

Здравствуйте, уважаемые специалисты! В целях совершенствования навыков в скриптовании, прошу разъяснить алгоритм работы обработчика событий.

 

Для перечисленного в квадратных скобках юнитов добавил EH на выстрел.

Как я понял, что после выстрела одного из указанных ботов должно происходить отключение всех EH "fired"? 

Команда removeAllEventHandlers не отключает у всех ботов это событие?

 

Хотелось достигнуть следующей цели: любой из ботов, кто первый выстрелил - тот поднял тревогу и соответственно остальным уже нет смысла при стрельбе поднимать кипишь, так как тревога уже есть.

 

Ниже, подготовленный мной кусок кода не дает такого эффекта. Обработчик событий продолжает отрабатывать "fired" для всех юнитов постоянно. Где совершена ошибка?

{_x addEventHandler  ["fired", 

{
_x removeAllEventHandlers "fired";
Hint "Тревога!";
}
];

} forEach [pat1, pat2, pat3, pat4, ch1, ch2]; 

Заранее благодарен!

 


  • 0

#2 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 posts
  • Откуда:SPB

Posted 21 February 2018 - 19:31


_x removeAllEventHandlers "fired";

А как ты думаешь - что есть _x внутри данного вызываемого скрипта, при срабатывании EH?

 

Учитывая то, что согласно обработчику, тебе доступен массив с данными -

Passed array: [unit, weapon, muzzle, mode, ammo]

ни о каком абстрактном(в данном контексте кода) _x речи не идет.

 

А если уж и делать нечто подобное, то как то так -

*При условии, что - pat1, pat2, pat3, pat4, ch1, ch2 - глобальные переменные - указатели на юнитов.
 

{_x addEventHandler  ["fired",    {    Hint "Тревога!"; {_x removeAllEventHandlers "fired";} forEach [pat1, pat2, pat3, pat4, ch1, ch2];    };];} forEach [pat1, pat2, pat3, pat4, ch1, ch2];

Для большего понимания - раздели EH и процедуру
 

TEST    =
    {
        Hint "Тревога!";
        {
            _x removeAllEventHandlers "fired";
        } forEach [pat1, pat2, pat3, pat4, ch1, ch2];
    };

{
    _x addEventHandler  ["fired", {[] call TEST;};];
} forEach [pat1, pat2, pat3, pat4, ch1, ch2];

  • 1

#3 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 21 February 2018 - 23:29   Best Answer

sharkman, в области видимости обработчика события нету никакой переменной "_x", нормальный код для этого будет выглядеть так:

// Наши юниты
myUnits = [pat1, pat2, pat3, pat4, ch1, ch2];

// Код нашего обработчика события
myEventHandler = {
	// Выводит какой-нибудь текст
	systemChat "Hello World!";
	systemChat str _this;

	// Удаляем ТОЛЬКО НАШ обработчик события
	// Не забывайте что по мимо вашего могут
	// быть обработчики событий и других аддонов/скриптов
	{
		_x removeEventHandler ["Fired", _x getVariable "myEventHandlerIndex"];
	} forEach myUnits;
};

// Вешаем обработчики события на юниты
{
	_x setVariable ["myEventHandlerIndex", _x addEventHandler ["Fired", myEventHandler]];
} forEach myUnits;

Edited by vlad333000, 22 February 2018 - 13:12.

  • 1

#4 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 posts
  • Откуда:SPB

Posted 22 February 2018 - 03:41

vlad333000,

Еще проверку на Null надо для указателей)))


  • 0

#5 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 22 February 2018 - 11:16

vlad333000,
Еще проверку на Null надо для указателей)))

Это излишне в данной ситуации
  • 0

#6 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 posts
  • Откуда:SPB

Posted 22 February 2018 - 12:30

vlad333000,

Ну от чего же? А вдруг ботов накроет взрывной волной_) и они сдохнут быстро и одновременно?)

Да к тому же - а зачем флаг тогда? - разумнее просто напросто проверить объект - и банально и просто, и без флагов.


  • 0

#7 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 22 February 2018 - 13:11

NoNameUltima, смерть юнита != обнуление переменной
Причина по которой я добавил флаг я описал в комментариях в коде... хотя вот протестировал на одновременное срабатывание... арма "собирает" обработчики событий для каждого события отдельно перед его вызовом, так что если изменить их во время выполнения другого обработчика, то арма нормально среагирует на это и флаг или какая-либо другая проверка тут вообще не нужны

Edited by vlad333000, 22 February 2018 - 13:12.

  • 0

#8 OFFLINE   ReXcOr

ReXcOr

    Ст.сержант

  • Пользователи
  • 264 posts
  • Откуда:Moscow

Posted 22 February 2018 - 13:17

А по моему лучше повесить один хэндлер “firedNear”
И после того как он сработает, удалить его
  • 0

#9 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 posts
  • Откуда:SPB

Posted 22 February 2018 - 13:18


обнуление переменной

Да как раз таки равно, и не переменной, а указателю на объект - ObjNull вернет в лучшем случае. Хотя я не в курсе, вызовет ли ошибку удаления хендлера при таком раскладе.

P.S. Указатели хранить вообще не рекомендуется, а уж тем более в глобальных переменных. - Не гарантированный доступ.


  • 0

#10 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 22 February 2018 - 13:23

А по моему лучше повесить один хэндлер “firedNear”

FiredNear срабатывает только в радиусе ~60 метров, как вы понимаете 99% оружия слышно на больших расстояниях :)
  • 0

#11 OFFLINE   ReXcOr

ReXcOr

    Ст.сержант

  • Пользователи
  • 264 posts
  • Откуда:Moscow

Posted 22 February 2018 - 13:26

А по моему лучше повесить один хэндлер “firedNear”

FiredNear срабатывает только в радиусе ~60 метров, как вы понимаете 99% оружия слышно на больших расстояниях :)

Ну да, есть такое дело))))

Но может автору поста и этого хватит, я с таким расчетом)))
  • 0

#12 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 22 February 2018 - 13:33

Да как раз таки равно, и не переменной, а указателю на объект - ObjNull вернет в лучшем случае. Хотя я не в курсе, вызовет ли ошибку удаления хендлера при таком раскладе. P.S. Указатели хранить вообще не рекомендуется, а уж тем более в глобальных переменных. - Не гарантированный доступ.

Знакомьтесь, мертвый bob:
Картинка

В хинте каждый кадр выводится:
[diag_frameno, bob, vehicleVarName bob, alive bob, position bob, bob == bob]
В чате из обработчика Killed вывелось:
[diag_frameno, _this]

Хотя я не в курсе, вызовет ли ошибку удаления хендлера при таком раскладе.

Нет, а если nil, то команда скорее всего вообще не выполнится (Движок армы любит скипать команды если в них есть nil)

Edited by vlad333000, 22 February 2018 - 13:32.

  • 0

#13 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 posts
  • Откуда:SPB

Posted 22 February 2018 - 14:41


Знакомьтесь, мертвый bob:

Так вроде трупы удаляются... со временем....) а когда уж удалятся то...


  • 0

#14 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 22 February 2018 - 15:50

NoNameUltima, во-первых, это отключается
Во-вторых, это настраивается
В-тертьих, можно добавить обработчик Killed и удалить из массива этого юнита или изменить getVariable на getVariable с значением по-умолчанию
  • 0

#15 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 posts
  • Откуда:SPB

Posted 22 February 2018 - 16:35


во-первых, это отключается Во-вторых, это настраивается

Так никто не спорит. Я это к тому - что раз уж ты ему так все разжевал, то зачем гадать - вкл\выкл там у него удаление трупов, если в жвачку можно просто добавить 1 проверку для полной картины.


  • 0

#16 OFFLINE   sharkman

sharkman

    Ефрейтор

  • Пользователи
  • 68 posts
  • Откуда:Хабаровск

Posted 22 February 2018 - 17:20

sharkman, в области видимости обработчика события нету никакой переменной "_x", нормальный код для этого будет выглядеть так:
 

// Наши юниты
myUnits = [pat1, pat2, pat3, pat4, ch1, ch2];

// Код нашего обработчика события
myEventHandler = {
	// Выводит какой-нибудь текст
	systemChat "Hello World!";
	systemChat str _this;

	// Удаляем ТОЛЬКО НАШ обработчик события
	// Не забывайте что по мимо вашего могут
	// быть обработчики событий и других аддонов/скриптов
	{
		_x removeEventHandler ["Fired", _x getVariable "myEventHandlerIndex"];
	} forEach myUnits;
};

// Вешаем обработчики события на юниты
{
	_x setVariable ["myEventHandlerIndex", _x addEventHandler ["Fired", myEventHandler]];
} forEach myUnits;

Огромное спасибо за разъяснения! Всем спасибо! Очень помогли!

Ну, и еще маленький вопрос, а почему Ваш скрипт не работает с приватными переменными? Уж простите за такой вопрос...


  • 0

#17 OFFLINE   sharkman

sharkman

    Ефрейтор

  • Пользователи
  • 68 posts
  • Откуда:Хабаровск

Posted 22 February 2018 - 17:27

 


_x removeAllEventHandlers "fired";

А как ты думаешь - что есть _x внутри данного вызываемого скрипта, при срабатывании EH?

 

Учитывая то, что согласно обработчику, тебе доступен массив с данными -

Passed array: [unit, weapon, muzzle, mode, ammo]

ни о каком абстрактном(в данном контексте кода) _x речи не идет.

 

А если уж и делать нечто подобное, то как то так -

*При условии, что - pat1, pat2, pat3, pat4, ch1, ch2 - глобальные переменные - указатели на юнитов.
 

{_x addEventHandler  ["fired",    {    Hint "Тревога!"; {_x removeAllEventHandlers "fired";} forEach [pat1, pat2, pat3, pat4, ch1, ch2];    };];} forEach [pat1, pat2, pat3, pat4, ch1, ch2];

Для большего понимания - раздели EH и процедуру
 

TEST    =
    {
        Hint "Тревога!";
        {
            _x removeAllEventHandlers "fired";
        } forEach [pat1, pat2, pat3, pat4, ch1, ch2];
    };

{
    _x addEventHandler  ["fired", {[] call TEST;};];
} forEach [pat1, pat2, pat3, pat4, ch1, ch2];

Огромное спасибо! Там правда точка с запятой лишняя попалась - ошибку выдала. Все равно, спасибо за помощь!


  • 0




Яндекс.Метрика