Новости/News | | Туториалы/Tutorials | | Форум/Forum | | ЧаВо/FAQ | | Патчи/Patches | | Файлы/Downloads | | Ссылки/Links | | Авторы/About |

Указатели на функции (delegate)

Содержание

Введение

Делегат (delegate) представляет собой указатель на функцию у объекта. В этом туториале описано как использовать делегаты в UnrealScript. В основном их используют для обеспечения обратных вызовов, например, для создания системы оповещений в UI (User Interface).

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

Первое, что необходимо сделать - это объявить делегата. Его определение очень похоже на объявление event. Например:

сlass Button extends Window;
  ...
delegate OnClick( Button B, int MouseX, int MouseY );

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

Вызов делегата происходит также как вызов обычной функции:

сlass 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 );
}

Определение указателя на функцию

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

сlass MyDialogBox extends Window;

var Button OKButton, CancelButton;

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

function Create() {

  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;
}

Последние две строки в функции Create() создают для обеих кнопок OnClick делегата, ссылающегося на MyClick() функцию класса MyDialogBox. Когда в функции MouseUp() происходит вызов OnClick делегата, вместо него будет вызвана функция MyClick() класса MyDialogBox. Если Вы не воспользуетесь услугами делегата, то, для переопределения функциональности, Вам потребуется создание отдельного подкласса класса Button.

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

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

Если актер (actor), на который ссылается делегат, удален, то при вызове делегата, он будет просто ничего не делать, т.е. вести себя так, как будто он ссылается на None.

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

Дефолтное поведение делегата

При объявлении делегата, Вы можете, заодно, описать его поведение по умолчанию в теле делегата. Например:

сlass Button extends Window;

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

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

Вызов делегата из C++

При экспорте автоматически сгенерированного файла EngineClasses.h типа для пака, в котором находится нативный класс с делегатом, для делегата будет создана соответствующая C++ функция (наподобие функций для event), которая позволяет производить обращение к делегату из C++ кода. Для приведенных выше примеров, будет создана нативная функция delegateOnClick().

Автор

Jack 'Mek' Porter (EpicGames)
Last updated by Vito Miliano (UDN Staff)
Оригинал туториала: UnrealScript Delegates
Перевод сделан 32_Pistoleta

Хостинг от uCoz