Перейти к содержимому


Фотография

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


Лучший Ответ 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;
Перейти к сообщению


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 16

#1 OFFLINE   sharkman

sharkman

    Ефрейтор

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

Отправлено 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 сообщений
  • Откуда:SPB

Отправлено 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 сообщений
  • Откуда:Кострома

Отправлено 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;

Сообщение отредактировал vlad333000: 22 February 2018 - 13:12

  • 1

#4 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 22 February 2018 - 03:41

vlad333000,

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


  • 0

#5 OFFLINE   vlad333000

vlad333000

    Полковник

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

Отправлено 22 February 2018 - 11:16

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

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

#6 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 22 February 2018 - 12:30

vlad333000,

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

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


  • 0

#7 OFFLINE   vlad333000

vlad333000

    Полковник

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

Отправлено 22 February 2018 - 13:11

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

Сообщение отредактировал vlad333000: 22 February 2018 - 13:12

  • 0

#8 OFFLINE   ReXcOr

ReXcOr

    Ст.сержант

  • Пользователи
  • 264 сообщений
  • Откуда:Moscow

Отправлено 22 February 2018 - 13:17

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

#9 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 22 February 2018 - 13:18


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

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

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


  • 0

#10 OFFLINE   vlad333000

vlad333000

    Полковник

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

Отправлено 22 February 2018 - 13:23

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

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

#11 OFFLINE   ReXcOr

ReXcOr

    Ст.сержант

  • Пользователи
  • 264 сообщений
  • Откуда:Moscow

Отправлено 22 February 2018 - 13:26

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

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

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

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

#12 OFFLINE   vlad333000

vlad333000

    Полковник

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

Отправлено 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)

Сообщение отредактировал vlad333000: 22 February 2018 - 13:32

  • 0

#13 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 22 February 2018 - 14:41


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

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


  • 0

#14 OFFLINE   vlad333000

vlad333000

    Полковник

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

Отправлено 22 February 2018 - 15:50

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

#15 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 22 February 2018 - 16:35


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

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


  • 0

#16 OFFLINE   sharkman

sharkman

    Ефрейтор

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

Отправлено 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 сообщений
  • Откуда:Хабаровск

Отправлено 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




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