Экспорт функций

Руководство по экспорту функций из вашего плагина для использования другими языковыми модулями в Plugify.

В экосистеме Plugify плагины на JavaScript могут экспортировать функции, чтобы сделать их доступными для других плагинов. Это руководство объясняет, как определять и экспортировать функции в JavaScript и предоставляет примеры, которые помогут вам беспрепятственно интегрировать ваши плагины.

Базовое сопоставление типов

В следующей таблице перечислены способы представления типов в JavaScript API:

Тип C++Тип JSПсевдоним PlugifyПоддержка Ref?
voidundefinedvoid
boolbooleanbool
charstringchar8
char16_tstringchar16
int8_tnumberint8
int16_tnumberint16
int32_tnumberint32
int64_tBigIntint64
uint8_tnumberuint8
uint16_tnumberuint16
uint32_tnumberuint32
uint64_tBigIntuint64
uintptr_tnumberptr64
uintptr_tnumberptr32
floatnumberfloat
doublenumberdouble
void*Functionfunction
plg::stringstringstring
plg::anyanyany
plg::vector<bool>boolean[]bool[]
plg::vector<char>string[]char8[]
plg::vector<char16_t>string[]char16[]
plg::vector<int8_t>number[]int8[]
plg::vector<int16_t>number[]int16[]
plg::vector<int32_t>number[]int32[]
plg::vector<int64_t>BigInt[]int64[]
plg::vector<uint8_t>number[]uint8[]
plg::vector<uint16_t>number[]uint16[]
plg::vector<uint32_t>number[]uint32[]
plg::vector<uint64_t>BigInt[]uint64[]
plg::vector<uintptr_t>number[]ptr64[]
plg::vector<uintptr_t>number[]ptr32[]
plg::vector<float>number[]float[]
plg::vector<double>number[]double[]
plg::vector<plg::string>string[]string[]
plg::vector<plg::any>any[]any[]
plg::vector<plg::vec2>Vector2[]vec2[]
plg::vector<plg::vec3>Vector3[]vec3[]
plg::vector<plg::vec4>Vector4[]vec4[]
plg::vector<plg::mat4x4>Matrix4x4[]mat4x4[]
plg::vec2Vector2vec2
plg::vec3Vector3vec3
plg::vec4Vector4vec4
plg::mat4x4Matrix4x4mat4x4

Экспорт функций в JavaScript

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

Простой пример

Вот простой пример экспорта функции в плагине на JavaScript:

Определение функции

plugin.mjs
export function addNumbers_exported(a, b) {
    /**
     * Складывает два целых числа.
     *
     * @param {number} a - Первое целое число.
     * @param {number} b - Второе целое число.
     * @returns {number} Сумма a и b.
     */
    return a + b;
}

Манифест плагина

Чтобы экспортировать функцию, опишите ее в манифесте плагина в разделе methods:

plugin_name.pplugin
{
  "name": "ExampleJavaScriptPlugin",
  "version": "1.0.0",
  "methods": [
    {
      "name": "addNumbers",
      "funcName": "addNumbers_exported",
      "paramTypes": [
        {
          "type": "int32",
          "name": "a"
        },
        {
          "type": "int32",
          "name": "b"
        }
      ],
      "retType": {
        "type": "int32"
      }
    }
  ]
}

Сложный пример: Экспорт сложных функций

Вот пример экспорта функции со сложными типами параметров и возвращаемого значения:

Определение функции

plugin.mjs
export function processData_exported(data, prefix) {
    /**
     * Обрабатывает массив чисел и возвращает массив строк.
     *
     * @param {Array<number>} data - Массив чисел.
     * @param {string} prefix - Префикс для добавления к каждому значению.
     * @returns {Array<string>} Массив отформатированных строк.
     */
    return data.map(value => `${prefix}${value}`);
}

Манифест плагина

plugin_name.pplugin
{
  "name": "ExampleJavaScriptPlugin",
  "version": "1.0.0",
  "methods": [
    {
      "name": "processData",
      "funcName": "processData_exported",
      "paramTypes": [
        {
          "type": "float[]",
          "name": "data"
        },
        {
          "type": "string",
          "name": "prefix"
        }
      ],
      "retType": {
        "type": "string[]"
      }
    }
  ]
}

Экспорт функций с параметрами по ссылке

Plugify поддерживает ссылочные параметры в динамически типизированных языках, таких как JavaScript, но они работают иначе, чем в статически типизированных языках. В JavaScript вы не можете напрямую изменять параметры, переданные по ссылке. Вместо этого вы должны вернуть массив, где:

  1. Первый элемент: Возвращаемое значение функции (используйте undefined, если функция возвращает void)
  2. Остальные элементы: Измененные значения для всех ссылочных параметров в порядке их объявления

Определение функции с параметрами по ссылке

plugin.mjs
export function incrementValue_exported(value) {
    /**
     * Увеличивает целочисленное значение на 1.
     *
     * @param {number} value - Значение для увеличения.
     * @returns {Array} Массив из [undefined, измененное_значение].
     */
    return [undefined, value + 1];
}

export function calculate_exported(a, b, sum, product) {
    /**
     * Вычисляет сумму и произведение двух чисел, возвращая оба значения через ссылки.
     *
     * @param {number} a - Первое число.
     * @param {number} b - Второе число.
     * @param {number} sum - Выходной параметр для суммы (передается по ссылке).
     * @param {number} product - Выходной параметр для произведения (передается по ссылке).
     * @returns {Array} Массив из [undefined, sum, product].
     */
    const calculatedSum = a + b;
    const calculatedProduct = a * b;
    return [undefined, calculatedSum, calculatedProduct];
}

export function processAndCount_exported(data, prefix, count) {
    /**
     * Обрабатывает данные и возвращает как результат, так и количество.
     *
     * @param {Array<number>} data - Массив чисел.
     * @param {string} prefix - Префикс для добавления к каждому значению.
     * @param {number} count - Выходной параметр для количества (передается по ссылке).
     * @returns {Array} Массив из [result, count].
     */
    const result = data.map(value => `${prefix}${value}`);
    return [result, data.length];
}

Манифест плагина с параметрами по ссылке

В манифесте отметьте параметры, которые должны обрабатываться как ссылки, используя "ref": true:

plugin_name.pplugin
{
  "name": "ExampleJavaScriptPlugin",
  "version": "1.0.0",
  "methods": [
    {
      "name": "incrementValue",
      "funcName": "incrementValue_exported",
      "paramTypes": [
        {
          "type": "int32",
          "name": "value",
          "ref": true
        }
      ],
      "retType": {
        "type": "void"
      }
    },
    {
      "name": "calculate",
      "funcName": "calculate_exported",
      "paramTypes": [
        {
          "type": "int32",
          "name": "a"
        },
        {
          "type": "int32",
          "name": "b"
        },
        {
          "type": "int32",
          "name": "sum",
          "ref": true
        },
        {
          "type": "int32",
          "name": "product",
          "ref": true
        }
      ],
      "retType": {
        "type": "void"
      }
    },
    {
      "name": "processAndCount",
      "funcName": "processAndCount_exported",
      "paramTypes": [
        {
          "type": "float[]",
          "name": "data"
        },
        {
          "type": "string",
          "name": "prefix"
        },
        {
          "type": "int32",
          "name": "count",
          "ref": true
        }
      ],
      "retType": {
        "type": "string[]"
      }
    }
  ]
}

Как это работает

  1. Порядок возврата: Первое возвращаемое значение - это фактическое возвращаемое значение функции. Последующие значения соответствуют ссылочным параметрам в порядке их объявления.
  2. Функции с void: Если функция возвращает void, первый элемент массива должен быть undefined.
  3. Смешанные возвраты: Если функция имеет как возвращаемое значение, так и ссылочные параметры, возвращаемое значение идет первым, за ним следуют все ссылочные параметры.
  4. Деструктуризация массива: Вызывающие функции могут использовать деструктуризацию массива для удобного доступа к возвращаемым значениям.

Поддержка параметров по ссылке

Параметры по ссылке работают с большинством типов Plugify, как показано в столбце "Поддержка ссылок" таблицы сопоставления типов. Следующие типы не поддерживают ссылки:

  • void/undefined (не может быть передан по ссылке)
  • function (типы обратных вызовов)

Все остальные типы, включая примитивы, строки и массивы, поддерживают параметры по ссылке через паттерн возврата массива.

Обработка обратных вызовов (Callbacks)

Plugify позволяет экспортировать функции, которые принимают обратные вызовы в качестве параметров. Вот пример:

Определение функции

plugin.mjs
export function executeWithCallback_exported(value, inputStr, callback) {
    /**
     * Выполняет функцию обратного вызова с предоставленными параметрами.
     *
     * @param {number} value - Целочисленное значение.
     * @param {string} inputStr - Входная строка.
     * @param {Function} callback - Функция обратного вызова для выполнения.
     */
    const result = callback(value, inputStr);
    console.log(`Результат обратного вызова: ${result}`);
}

Манифест плагина

plugin_name.pplugin
{
  "name": "ExampleJavaScriptPlugin",
  "version": "1.0.0",
  "methods": [
    {
      "name": "executeWithCallback",
      "funcName": "executeWithCallback_exported",
      "paramTypes": [
        {
          "type": "int32",
          "name": "value"
        },
        {
          "type": "string",
          "name": "inputStr"
        },
        {
          "type": "function",
          "name": "callback",
          "prototype": {
            "name": "exampleCallback",
            "funcName": "exampleCallback_exported",
            "paramTypes": [
              {
                "type": "int32",
                "name": "value"
              },
              {
                "type": "string",
                "name": "inputStr"
              }
            ],
            "retType": {
              "type": "string"
            }
          }
        }
      ],
      "retType": {
        "type": "void"
      }
    }
  ]
}

Лучшие практики

  1. Определяйте функции четко: Убедитесь, что ваши функции хорошо документированы и просты для понимания.
  2. Соблюдайте соглашения о типах: Придерживайтесь соглашений о типах Plugify для параметров и возвращаемых значений.
  3. Тестируйте тщательно: Тестируйте ваши экспортированные функции, чтобы убедиться, что они работают так, как ожидается, при вызове из других плагинов.
  4. Обновляйте манифест: Всегда описывайте экспортированные функции в манифесте плагина в разделе methods.

Заключение

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