UDKСтатьи

Делегаты UnrealScript

Автор:

Введение
Обзор
  Объявление делегата
    Делегат как аргумент функции
  Вызов делегата
  Назначение делегату указателя на функцию
Расширенные возможности
  Делегаты и удаленные объекты
  Определение тела делегата

Введение

Делегат - это ссылка на функцию, связанную с объектом. Этот документ описывает их использование в языке UnrealScript. Их основное назначение заключается в обеспечении механизма обратного вызова, например, обеспечение оповещения о событиях в системе пользовательского интерфейса.

Обзор

Объявление делегата

Первое, что вам нужно сделать, это объявить делегат. Объявление делегата похоже на объявление события, например:

    Class Button extends Window;

    delegate OnClick( Button B, int MouseX, int MouseY );

Делегат как аргумент функции

В движке Unreal Engine 3 делегаты также могут использоваться в качестве аргументов функций. Сначала вы должны объявить делегат, как показано выше, а затем использовать его как параметр функции:

   function DoStuff(delegate<OnClick> ClickDelegate)
   {
   }

Теперь вышеуказанная функция может принимать делегат в качестве параметра, например:

   function MyOnClick( Button B, int MouseX, int MouseY )
   {
   }

   function CallFunction()
   {
       DoStuff(MyOnClick);
   }

Вызов делегата

Вызов делегата осуществляется так же, как и вызов обычной функции:

    Class Button extends Window;

    var int MouseDownX, MouseDownY;

    delegate OnClick( Button B, int MouseX, int MouseY );

    function MouseDown( int MouseX, int MouseY )
    {
        MouseDownX = MouseX;
        MouseDownY = MouseY;
    }

    function MouseUp( int MouseX, int MouseY )
    {
        if( MouseX == MouseDownX && MouseY == MouseDownY )
            OnClick( Self, MouseX, MouseY );
    }

Или в случае, когда делегат является аргументом функции:

   function DoStuff(delegate<OnClick> ClickDelegate)
   {
       ClickDelegate(Self, MouseX, MouseY);
   }

Назначение делегату указателя на функцию

Чтобы вы могли пользоваться делегатом, вам необходимо назначить ему функцию. Обычно эта функция находится в другом объекте. Для назначения ссылки на функцию делегату, объявление функции должно иметь те же типы параметров и тип возвращаемого значения (если таковые имеются), что и в объявлении делегата. Пример:

    Class MyDialogBox extends Window;

    var Button OKButton, CancelButton;

    function MyClick( Button B, int MouseX, int MouseY )
    {
        if( B == OKButton )
            SaveDetails();
        CloseWindow();
    }

    event Initialized()
    {
        OKButton = CreateWindow(class'Button', 40, 100, 64, 32 );
        CancelButton = CreateWindow(class'Button', 120, 100, 64, 32 );

        OKButton.Caption = "OK";
        CancelButton.Caption = "Cancel";

        OKButton.OnClick = MyClick;
        CancelButton.OnClick = MyClick;
    }

Последние две строки события Initialized назначают делегатам OnClick кнопок объекта MyDialogBox указатель на функцию MyClick. Когда функция MouseUp класса Button вызывает делегат OnClick, то осуществляется выполнение функции MyClick класса MyDialogBox. Без использования делегатов Вам пришлось бы для каждой кнопки создавать дочерний класс, наследующий класс Button.

Кроме того, вы можете назначать делегаты в блок defaultproperties{}, например:

    DefaultProperties
    {
        OKButton.OnClick=MyClick
        CancelButton.OnClick=MyClick
    }

Также вы можете каждому из делегатов присвоить значение None. В этом случае при вызове делегата ничего не произойдет.

Делегаты могут передаваться в качестве аргументов функций, что в свою очередь может быть использована для назначения делегата свойству класса.

   function DoStuff(delegate<OnClick> ClickDelegate)
   {
       OKButton.OnClick = ClickDelegate;
   }

Расширенные возможности

Делегаты и удаленные объекты

Если актор, на функцию которого ссылается делегат, удален, то при вызове делегата ничего не произойдет, как если бы делегату было присвоено значение None.

В случае же с объектами, не являющимися акторами, ссылка делегата подобна обычной ссылке на объект. Попытка вызова делегата, указывающего на функцию удаленного объекта, будет предотвращена сборщиком мусора. Если же вручную удалить объект, не являющийся актором, то последующий вызов делегата, указывающего на функцию удаленного объекта, приведет к аварийной ситуации.

Определение тела делегата

Вы можете определить тело делегата, например:

    Class Button extends Window;

    delegate OnClick( Button B, int MouseX, int MouseY )
    {
        Log("This is the default action");
    }

В этом случае, если вы вызовите делегат OnClick, указывающий на None, то будет выполнено его тело. Вы можете использовать этот механизм для назначения делегату действия по умолчанию.

Данный документ является переводом оригинального документа UnrealScript Delegates.

#UDK, #Unreal Development Kit

7 июня 2012