RPC (Remote Procedure Call)

Для упрощения работы с RPC библиотека предоставляет свою обёртку механизма RPC игры. Обёртка состоит из двух компонентов: компонент вызова и обработчик.

Реализованная обёртка позволяет выполнять RPC, идентифицируемые сразу по 3 атрибутам: название модификации (пространство имён), название функции в модификации, типы аргументов функции. Таким образом, обёртка поддерживает перегрузку функций (т.е. создание двух функций с одинаковыми названиями, но разными аргументами).

Компонент вызова - это объект, который создаётся на вызывающей процедуру стороне, и используется для строго типизированного вызова процедуры. В библиотеке этот компонент представлен семейством классов MBSL_RPC. При использовании компонента на клиенте параметр recipient можно игнорировать. При использовании на сервере он указывает получателя RPC (NULL = все игроки).

//N - число аргументов (от 0 до 7)
class MBSL_RPCN<Class Arg1, ..., Class ArgN> : Managed
{
    //Конструктор. Требует передать название модификации (пространство имён)
    //А также название функции в этой модификации (пространстве имён).
    void MBSL_RPCN(string modname, string functionname);
    //Вызвать удалённую процедуру с указанными аргументами
    void Invoke(Arg1 arg1, ..., ArgN argN, PlayerIdentity recipient = NULL);
}

//Вариант без аргументов
class MBSL_RPC0 : Managed
{
    //Конструктор. Требует передать название модификации (пространство имён)
    //А также название функции в этой модификации (пространстве имён).
    void MBSL_RPC0(string modname, string functionname);
    //Вызвать удалённую процедуру с указанными аргументами
    void Invoke(PlayerIdentity recipient = NULL);
}

//Особый вариант. Позволяет передать любое число аргументов в виде массива
class MBSL_RPCRaw : Managed
{
    //Конструктор. Требует передать название модификации (пространство имён)
    //А также название функции в этой модификации (пространстве имён).
    void MBSL_RPCRaw (string modname, string functionname);
    //Вызвать удалённую процедуру с указанными аргументами
    void Invoke(array<ref Param> params, PlayerIdentity recipient = null)
}

Обработчик - это вызываемая строго типизированная функция на другой стороне, которая получает аргументы, а также информацию о вызвавшем функцию игроке (если обработчик на сервере). В библиотеке этот компонент представлен семейством классов MBSL_RPC_Handler.

//N - число аргументов (от 0 до 7)
class MBSL_RPC_HandlerN<Class Arg1, ..., Class ArgN> : Managed
{
    //Добавить обработчик
    //Требует передать:
    //название модификации (пространство имён)
    //название функции в этой модификации (пространстве имён)
    //Функцию-обработчик
    static MBSL_RPC_HandlerBase Register(string modname, string funcname, MBSL_TypedAction(N+1)<Arg1, ..., ArgN, PlayerIdentity> handler);
}

//Вариант без аргументов
class MBSL_RPC_Handler0 : Managed
{
    //Добавить обработчик
    //Требует передать:
    //название модификации (пространство имён)
    //название функции в этой модификации (пространстве имён)
    //Функцию-обработчик
    static MBSL_RPC_HandlerBase Register(string modname, string funcname, MBSL_TypedAction1<PlayerIdentity> handler);
}

//Особый вариант. Получаем любое число аргументов
class MBSL_RPC_HandlerRaw : Managed
{
    //Добавить обработчик
    //Требует передать:
    //название модификации (пространство имён)
    //название функции в этой модификации (пространстве имён)
    //Функцию-обработчик
    static MBSL_RPC_HandlerBase Register(string modname, string funcname, MBSL_TypedAction2<ParamsReadContext, PlayerIdentity> handler);
}

Пример использования RPC:

//Клиент
MBSL_RPC1<string> sendMessage = new MBSL_RPC1<string>("ExampleMod", "SendMessage");
sendMessage.Invoke("Hello");

//Сервер
class Example : Managed
{
    void Example()
    {
        MBSL_RPC_Handler1<string>.Register("ExampleMod", "SendMessage", _SendMessage.AsStrong());
    }
    
    protected ref MBSL_TypedAction2<string, PlayerIdentity> _SendMessage = MBSL_TypedAction2<string, PlayerIdentity>.Weak(this, "SendMessage");
    protected void SendMessage(string message, PlayerIdentity sender)
    {
        Print(sender.GetPlainId() + " says: " + message);
    }
}

Last updated