Первый плагин

Узнайте, как создать свой первый плагин с помощью языкового модуля Rust, включая базовый синтаксис и настройку.

Добро пожаловать в руководство по разработке плагинов для языкового модуля Rust в Plugify. Это руководство проведёт вас через процесс создания вашего первого плагина на Rust в рамках фреймворка Plugify. Независимо от того, являетесь ли вы моддером игр, системным программистом или разработчиком плагинов, этот учебник поможет вам понять фундаментальные концепции и шаги, необходимые для создания полностью работающего плагина на Rust.

Что такое Plugify?

Plugify — это модульный фреймворк для плагинов, который позволяет разработчикам расширять приложения, динамически интегрируя внешние плагины. Он предоставляет структурированный подход к разработке плагинов с чёткими рекомендациями по структуре плагина, управлению зависимостями и предоставлению API.

Почему стоит использовать Rust?

Языковой модуль Rust позволяет разработчикам создавать высокопроизводительные и безопасные по памяти плагины на Rust. Используя динамические библиотеки (разделяемые объекты) и систему владения Rust, разработчики могут расширять приложения, сохраняя при этом как эффективность, так и безопасность. Plugify обеспечивает плавную интеграцию вашего плагина с основным фреймворком за счёт следования стандартизированной структуре плагина и API.

Что вы узнаете

В этом руководстве вы:

  1. Настроите структуру каталогов для вашего плагина.
  2. Определите манифест плагина (файл .pplugin) для регистрации плагина в экосистеме Plugify.
  3. Напишете код на Rust для вашего плагина с использованием предоставленного API.
  4. Настроите зависимости, чтобы обеспечить корректную инициализацию плагина.
  5. Скомпилируете и упакуете свой плагин с помощью Cargo.

К концу этого учебника у вас будет рабочий плагин на Rust, который можно загрузить во фреймворк Plugify. Приступим!

Структура каталогов

Чтобы обеспечить бесшовную интеграцию с фреймворком Plugify, ваш плагин должен следовать определенной структуре каталогов. Каждый плагин должен быть размещен в своей собственной папке внутри каталога extensions. Имя папки должно совпадать с именем плагина и следовать этим правилам:

  1. Должно начинаться с буквы (A-Z, a-z).
  2. Разрешённые символы: буквенно-цифровые (A-Z, a-z, 0-9), а также _
  3. Пробелы НЕ допускаются в имени папки.
  4. Файл конфигурации .pplugin должен иметь то же имя, что и папка плагина.

Пример структуры каталогов

Разбор структуры

  • res/extensions/ – Основной каталог, где хранятся все плагины.
  • plugin_name/ – У каждого плагина есть своя выделенная папка. Имя папки должно совпадать с именем файла .pplugin.
  • bin/ – Эта подпапка содержит скомпилированные бинарные файлы плагина (.dll для Windows, .so для Linux и т.д.).
  • plugin_name.pplugin – Файл конфигурации, который определяет метаданные о плагине.

Следуя этой структуре, Plugify может корректно обнаруживать, загружать и управлять плагинами на разных платформах.

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

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

Ключевые задачи файла манифеста:

  • Определяет версию плагина и сведения об авторе.
  • Указывает точку входа для выполнения.
  • Перечисляет зависимости, необходимые плагину.
  • Объявляет экспортируемые методы, доступные для внешнего взаимодействия.

Пример файла манифеста

plugin_name.pplugin
{
  "$schema": "https://raw.githubusercontent.com/untrustedmodders/plugify/refs/heads/main/schemas/plugin.schema.json",
  "version": "0.1.0",
  "name": "PluginRust",
  "description": "An example of a Rust plugin. This can be used as a starting point when creating your own plugin.",
  "author": "untrustedmodders",
  "website": "https://github.com/untrustedmodders/",
  "license": "MIT",
  "entry": "bin/example_plugin",
  "platforms": [],
  "language": "rust",
  "dependencies": [],
  "methods": [],
  "classes": []
}

Объяснение ключевых полей

  • entry: Указывает расположение скомпилированного бинарного файла плагина (без расширения).
  • language: Для плагинов на Rust должно быть установлено значение rust.
  • dependencies: Перечисляет другие необходимые плагины, обеспечивая правильный порядок загрузки.
  • methods: Функции, предоставляемые плагином для внешнего взаимодействия.
  • classes: Классы, экспортируемые плагином, которые могут быть созданы или использованы другими плагинами.

Почему файл манифеста важен?

  • Обеспечивает совместимость – Определяет поддерживаемые версии и платформы.
  • Обеспечивает модульность – Перечисляет зависимости для структурированной загрузки плагинов.
  • Упрощает интеграцию – Позволяет другим плагинам вызывать предоставленные методы.

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

Написание кода плагина

Создать плагин на Rust для Plugify несложно. Вы можете либо использовать готовый шаблон плагина на Rust, доступный в нашем репозитории, либо написать плагин с нуля.

Использование шаблона плагина

Самый простой способ начать — загрузить шаблон плагина на Rust из нашего репозитория. Он содержит все необходимые файлы, включая:

  • Преднастроенный проект Cargo
  • Пример реализации
  • Необходимые зависимости крейта Plugify

Просто клонируйте репозиторий, и ваша среда будет готова к разработке.

Написание плагина с нуля

Если вы предпочитаете создать плагин вручную, выполните следующие шаги:

Настройка проекта плагина

  1. Создайте новый проект библиотеки на Rust:
    cargo new --lib plugin_name
    cd plugin_name
    
  2. Обновите Cargo.toml, чтобы создать динамическую библиотеку:
    Cargo.toml
    [package]
    name = "plugin_name"
    version = "0.1.0"
    edition = "2021"
    
    [lib]
    crate-type = ["cdylib"]
    
    [dependencies]
    plugify = { git = "https://github.com/untrustedmodders/rust-plugify" }
    

Структура кода плагина

Вот базовый пример реализации плагина на Rust:

src/lib.rs
use plugify::register_plugin;

fn on_plugin_start() {
    println!("Rust: on_plugin_start");
}

fn on_plugin_update(_dt: f32) {
    println!("Rust: on_plugin_update");
}

fn on_plugin_end() {
    println!("Rust: on_plugin_end");
}

register_plugin!(
    start: on_plugin_start,
    update: on_plugin_update,
    end: on_plugin_end
);

Понимание методов жизненного цикла плагина

Каждый плагин может определять следующие методы жизненного цикла, которые Plugify будет вызывать в определённые моменты:

МетодОписаниеОбязателен?
on_plugin_startВызывается, когда плагин загружен и готов к работе.❌ Опционально
on_plugin_update(dt: f32)Вызывается каждый кадр, позволяя выполнять обновления.❌ Опционально
on_plugin_endВызывается при выгрузке или завершении работы плагина.❌ Опционально

Использование макроса регистрации

Чтобы зарегистрировать ваш плагин в Plugify, необходимо использовать макрос register_plugin!. Этот макрос:

  • Определяет точку входа плагина.
  • Связывает ваши функции жизненного цикла с системой Plugify.
  • Гарантирует, что методы жизненного цикла корректно экспортированы.

Вы можете зарегистрировать любую комбинацию функций жизненного цикла:

// Все три функции жизненного цикла
register_plugin!(
    start: on_plugin_start,
    update: on_plugin_update,
    end: on_plugin_end
);

// Только start и end
register_plugin!(
    start: on_plugin_start,
    end: on_plugin_end
);

// Только start
register_plugin!(
    start: on_plugin_start
);

Подключение крейта Plugify

Крейт Plugify предоставляет необходимые определения и утилиты для взаимодействия с Plugify. Добавьте его в ваш Cargo.toml:

[dependencies]
plugify = { git = "https://github.com/untrustedmodders/rust-plugify" }

Крейт включает:

  • Макрос register_plugin! для регистрации плагина.
  • Определения типов для межъязыковой совместимости.
  • Вспомогательные функции для доступа к возможностям Plugify.

Итоги

  • Используйте шаблон плагина на Rust, чтобы быстро начать.
  • Определите функции жизненного цикла (on_plugin_start, on_plugin_update, on_plugin_end) по мере необходимости.
  • Зарегистрируйте свой плагин с помощью макроса register_plugin!.
  • Используйте крейт Plugify для доступа к необходимым утилитам.

Следуя этим шагам, вы получите полностью работающий плагин Plugify, готовый к запуску!

Управление зависимостями

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

Как работают зависимости

Каждый плагин может объявить свои зависимости в поле dependencies своего манифеста плагина (файл .pplugin). Ядро Plugify будет:

  • Анализировать зависимости, перечисленные в манифесте каждого плагина.
  • Сортировать плагины с помощью топологической сортировки, гарантируя, что зависимости загружаются раньше зависящих от них плагинов.
  • Проверять совместимость платформ и запрошенные версии.

Представление зависимостей

Зависимости объявляются в следующем формате JSON внутри поля dependencies манифеста плагина:

plugin_name.pplugin (фрагмент)
"dependencies": [
    {
        "name": "core-plugin",
        "optional": false,
        "constraints": ">=1.0.0 <2.0.0"
    }
]

Объяснение полей

ПолеТипОбязательно?Описание
namestring✅ ДаУникальное имя плагина-зависимости.
optionalboolean❌ Нет (по умолч.: false)Если true, плагин сможет загрузиться даже при отсутствии зависимости.
constraintsstring❌ НетЗадаёт требуемую версию зависимости. Если не указано, допускается любая совместимая версия.

Пример плагина с зависимостями

Вот пример манифеста плагина (.pplugin), объявляющего несколько зависимостей:

plugin_name.pplugin
{
  "version": "1.0.0",
  "name": "MyRustPlugin",
  "entry": "bin/my_rust_plugin",
  "language": "rust",
  "dependencies": [
    {
      "name": "core-plugin",
      "optional": false,
      "constraints": "2.0.0"
    },
    {
      "name": "utils-plugin",
      "optional": true
    }
  ]
}

В этом примере:

  • core-plugin обязателен и должен быть версии 2.0.0.
  • utils-plugin опционален, то есть плагин загрузится, даже если его нет.

Ключевые выводы

  1. Убедитесь, что обязательные зависимости доступны перед загрузкой вашего плагина.
  2. Используйте optional: true для зависимостей, которые расширяют функциональность, но не критичны.
  3. Указывайте platforms, если зависимость не является кроссплатформенной.
  4. Определяйте constraints, если вашему плагину требуется конкретная версия зависимости.

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

Сборка плагина с помощью Cargo

Rust использует Cargo в качестве системы сборки и менеджера пакетов. Сборка вашего плагина выполняется просто:

Сборка в режиме release

Использование Cargo (командная строка)

cargo build --release

Скомпилированная библиотека будет находиться в target/release/:

  • В Windows: plugin_name.dll
  • В Linux: libplugin_name.so
  • В macOS: libplugin_name.dylib

Копирование в extensions Plugify

Скопируйте скомпилированную библиотеку в каталог extensions/plugin_name/bin/ вашей установки Plugify.

Проверка загрузки плагина

Запустите Plugify и убедитесь, что ваш плагин загружается корректно:

plg plugins

Конфигурация сборки

Вы можете настроить сборку в Cargo.toml:

Cargo.toml
[profile.release]
opt-level = 3          # Максимальная оптимизация
lto = true            # Оптимизация на этапе компоновки
codegen-units = 1     # Лучшая оптимизация
strip = true          # Удаление символов (меньший бинарник)
panic = "abort"       # Меньший бинарник, без раскрутки стека

Запуск и тестирование плагина

После того как вы собрали свой плагин, следующий шаг — запустить и протестировать его в системе Plugify.

Размещение плагина в правильном каталоге

Убедитесь, что ваш плагин правильно структурирован внутри папки extensions. Каталог плагина должен содержать:

  • Скомпилированный бинарный файл в каталоге bin/
  • Файл манифеста .pplugin

Проверка статуса загрузки плагина

Вы можете проверить, успешно ли загрузился ваш плагин, с помощью команд терминала, предоставляемых Plugify.

  • Вывести список всех загруженных плагинов:
plg plugins

Эта команда отобразит все текущие загруженные плагины.

  • Запросить информацию о конкретном плагине:
plg plugin example_plugin

Эта команда получает подробную информацию о конкретном плагине.

Обработка сбоев загрузки плагина

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

plg list

Отладка проблем

Если ваш плагин работает не так, как ожидалось:

  • Проверьте логи консоли на наличие подробных сообщений об ошибках.
  • Убедитесь, что все зависимости правильно установлены и совместимы.
  • Проверьте точку входа в манифесте .pplugin — она должна соответствовать фактическому расположению бинарного файла плагина.
  • Используйте сообщения об ошибках Rust для выявления проблем компиляции или выполнения.

Заключение

Это руководство охватило основные шаги по созданию плагина на Rust для Plugify, включая настройку проекта, написание кода плагина, настройку манифеста и сборку плагина с помощью Cargo. Соблюдение этих рекомендаций обеспечивает гладкую интеграцию в экосистему Plugify вместе с преимуществами Rust в области безопасности и производительности.