Documentation

Plugin Api

API ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² Wudgine прСдоставляСт Π½Π°Π±ΠΎΡ€ интСрфСйсов ΠΈ Ρ…ΡƒΠΊΠΎΠ² для взаимодСйствия с ядром Π΄Π²ΠΈΠΆΠΊΠ°.

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ интСрфСйсы

БистСма ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² Wudgine построСна Π²ΠΎΠΊΡ€ΡƒΠ³ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… интСрфСйсов:

IPlugin

Π‘Π°Π·ΠΎΠ²Ρ‹ΠΉ интСрфСйс для всСх ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ²:

namespace Wudgine::Plugin {

class IPlugin {
public:
    virtual ~IPlugin() = default;

    // Π–ΠΈΠ·Π½Π΅Π½Π½Ρ‹ΠΉ Ρ†ΠΈΠΊΠ»
    virtual bool Initialize() = 0;
    virtual void Shutdown() = 0;
    
    // ΠœΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅
    virtual const char* GetName() const = 0;
    virtual const char* GetVersion() const = 0;
    virtual const char* GetAuthor() const = 0;
    virtual const char* GetDescription() const = 0;
    
    // Настройки (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ)
    virtual void RenderSettings() {}
    
    // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° совмСстимости
    virtual bool IsCompatibleWithEngineVersion(const char* version) const;
};

} // namespace Wudgine::Plugin

PluginManager

ΠœΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ, ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ»Π°Π³ΠΈΠ½Π°ΠΌΠΈ:

namespace Wudgine::Core {

class PluginManager {
public:
    static PluginManager& GetInstance();
    
    // Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ²
    bool LoadPlugin(const std::string& name);
    bool LoadPluginFromPath(const std::string& path);
    bool LoadAllPlugins();
    
    // Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ»Π°Π³ΠΈΠ½Π°ΠΌΠΈ
    bool InitializePlugin(const std::string& name);
    void ShutdownPlugin(const std::string& name);
    void ShutdownAllPlugins();
    
    // Доступ ΠΊ ΠΏΠ»Π°Π³ΠΈΠ½Π°ΠΌ
    Plugin::IPlugin* GetPlugin(const std::string& name);
    bool IsPluginLoaded(const std::string& name) const;
    std::vector<Plugin::IPlugin*> GetAllPlugins() const;
    
    // Зависимости
    bool ResolveDependencies(const std::string& name);
};

} // namespace Wudgine::Core

Π₯ΡƒΠΊΠΈ ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ²

Π₯ΡƒΠΊΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΏΠ»Π°Π³ΠΈΠ½Π°ΠΌ Π²ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒΡΡ Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ части Π΄Π²ΠΈΠΆΠΊΠ°:

Π₯ΡƒΠΊΠΈ ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠ³ΠΎ Ρ†ΠΈΠΊΠ»Π°

// Π’ вашСм ΠΏΠ»Π°Π³ΠΈΠ½Π΅
bool MyPlugin::Initialize() {
    // РСгистрация Ρ…ΡƒΠΊΠΎΠ²
    Wudgine::Core::HookSystem::GetInstance().RegisterHook<Wudgine::Core::Hooks::OnSceneLoad>(
        [this](Wudgine::Core::Scene* scene) {
            // Код, выполняСмый ΠΏΡ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ сцСны
            return true; // ΠŸΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ…ΡƒΠΊΠΎΠ²
        }
    );
    
    return true;
}

ДоступныС Ρ…ΡƒΠΊΠΈ

  • OnEngineInitialize β€” вызываСтся ΠΏΡ€ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π΄Π²ΠΈΠΆΠΊΠ°
  • OnEngineShutdown β€” вызываСтся ΠΏΡ€ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π΄Π²ΠΈΠΆΠΊΠ°
  • OnSceneLoad β€” вызываСтся ΠΏΡ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ сцСны
  • OnSceneSave β€” вызываСтся ΠΏΡ€ΠΈ сохранСнии сцСны
  • OnSceneUnload β€” вызываСтся ΠΏΡ€ΠΈ Π²Ρ‹Π³Ρ€ΡƒΠ·ΠΊΠ΅ сцСны
  • OnUpdate β€” вызываСтся ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΊΠ°Π΄Ρ€
  • OnFixedUpdate β€” вызываСтся с фиксированной частотой
  • OnRender β€” вызываСтся ΠΏΡ€ΠΈ отрисовкС
  • OnGUI β€” вызываСтся ΠΏΡ€ΠΈ отрисовкС GUI

Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π°

API ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² позволяСт Ρ€Π°ΡΡˆΠΈΡ€ΡΡ‚ΡŒ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ Wudgine:

Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π°

// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ инструмСнта Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π°
class MyEditorTool : public Wudgine::Editor::EditorTool {
public:
    const char* GetName() const override { return "Мой инструмСнт"; }
    const char* GetIcon() const override { return "path/to/icon.png"; }
    
    void Initialize() override {
        // Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ инструмСнта
    }
    
    void Render() override {
        // ΠžΡ‚Ρ€ΠΈΡΠΎΠ²ΠΊΠ° интСрфСйса инструмСнта
        ImGui::Begin(GetName());
        ImGui::Text("Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΠΌΠΎΠ΅ инструмСнта");
        ImGui::End();
    }
};

// РСгистрация инструмСнта Π² ΠΏΠ»Π°Π³ΠΈΠ½Π΅
bool MyPlugin::Initialize() {
    if (Wudgine::Core::IsEditor()) {
        auto* tool = new MyEditorTool();
        Wudgine::Editor::EditorToolManager::GetInstance().RegisterTool(tool);
    }
    
    return true;
}

Π˜Π½ΡΠΏΠ΅ΠΊΡ‚ΠΎΡ€Ρ‹ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²

// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ инспСктора для ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°
class MyComponentInspector : public Wudgine::Editor::ComponentInspector {
public:
    bool CanInspect(Wudgine::ECS::Component* component) override {
        return dynamic_cast<MyPluginComponent*>(component) != nullptr;
    }
    
    void Render(Wudgine::ECS::Component* component) override {
        auto* myComponent = static_cast<MyPluginComponent*>(component);
        
        // ΠžΡ‚Ρ€ΠΈΡΠΎΠ²ΠΊΠ° ΠΏΠΎΠ»Π΅ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°
        float value = myComponent->GetValue();
        if (ImGui::DragFloat("Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅", &value)) {
            myComponent->SetValue(value);
            MarkDirty();
        }
    }
};

// РСгистрация инспСктора Π² ΠΏΠ»Π°Π³ΠΈΠ½Π΅
bool MyPlugin::Initialize() {
    if (Wudgine::Core::IsEditor()) {
        auto* inspector = new MyComponentInspector();
        Wudgine::Editor::InspectorManager::GetInstance().RegisterInspector(inspector);
    }
    
    return true;
}

ΠŸΡƒΠ½ΠΊΡ‚Ρ‹ мСню

// Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΡƒΠ½ΠΊΡ‚Π° мСню
bool MyPlugin::Initialize() {
    if (Wudgine::Core::IsEditor()) {
        Wudgine::Editor::EditorMenuManager::GetInstance().AddMenuItem(
            "Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹/Мой ΠΏΠ»Π°Π³ΠΈΠ½/ДСйствиС",
            [this]() {
                // ДСйствиС ΠΏΡ€ΠΈ Π²Ρ‹Π±ΠΎΡ€Π΅ ΠΏΡƒΠ½ΠΊΡ‚Π° мСню
                WG_LOG_INFO("Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ дСйствиС ΠΈΠ· мСню");
            }
        );
    }
    
    return true;
}

Π Π°Π±ΠΎΡ‚Π° с рСсурсами

API ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² прСдоставляСт доступ ΠΊ систСмС рСсурсов:

// Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° рСсурса
bool MyPlugin::Initialize() {
    // Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° тСкстуры
    auto* texture = Wudgine::Resource::ResourceManager::GetInstance().LoadTexture("path/to/texture.png");
    if (texture) {
        // ИспользованиС тСкстуры
    }
    
    // Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ
    auto* model = Wudgine::Resource::ResourceManager::GetInstance().LoadModel("path/to/model.fbx");
    if (model) {
        // ИспользованиС модСли
    }
    
    return true;
}

Π Π°Π±ΠΎΡ‚Π° с настройками

API ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² позволяСт ΡΠΎΡ…Ρ€Π°Π½ΡΡ‚ΡŒ ΠΈ Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ настройки:

// ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ структуры настроСк
struct MyPluginSettings {
    bool enableFeature = true;
    int quality = 5;
    std::string outputPath = "output";
    
    // БСриализация настроСк
    template<typename Archive>
    void serialize(Archive& ar) {
        ar & enableFeature;
        ar & quality;
        ar & outputPath;
    }
};

// Π’ вашСм ΠΏΠ»Π°Π³ΠΈΠ½Π΅
class MyPlugin : public Wudgine::Plugin::IPlugin {
private:
    MyPluginSettings m_settings;
    
public:
    bool Initialize() override {
        // Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° настроСк
        if (Wudgine::Core::SettingsManager::GetInstance().HasPluginSettings(GetName())) {
            m_settings = Wudgine::Core::SettingsManager::GetInstance().LoadPluginSettings<MyPluginSettings>(GetName());
        }
        
        return true;
    }
    
    void RenderSettings() override {
        // ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ настроСк Π² Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π΅
        ImGui::Checkbox("Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ", &m_settings.enableFeature);
        ImGui::SliderInt("ΠšΠ°Ρ‡Π΅ΡΡ‚Π²ΠΎ", &m_settings.quality, 1, 10);
        
        // Π‘ΠΎΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ настроСк ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ
        Wudgine::Core::SettingsManager::GetInstance().SavePluginSettings(
            GetName(), m_settings
        );
    }
};

ВзаимодСйствиС ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠ»Π°Π³ΠΈΠ½Π°ΠΌΠΈ

ΠŸΠ»Π°Π³ΠΈΠ½Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ с Π΄Ρ€ΡƒΠ³ΠΎΠΌ:

// ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΏΠ»Π°Π³ΠΈΠ½Π°
bool MyPlugin::Initialize() {
    // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° наличия Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΏΠ»Π°Π³ΠΈΠ½Π°
    if (Wudgine::Core::PluginManager::GetInstance().IsPluginLoaded("OtherPlugin")) {
        // ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΏΠ»Π°Π³ΠΈΠ½Π°
        auto* otherPlugin = static_cast<OtherPlugin*>(
            Wudgine::Core::PluginManager::GetInstance().GetPlugin("OtherPlugin")
        );
        
        // ВзаимодСйствиС с Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠΌ
        otherPlugin->DoSomething();
    }
    
    return true;
}

БСрвисы ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ²

ΠŸΠ»Π°Π³ΠΈΠ½Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ сСрвисы для Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ²:

// ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ интСрфСйса сСрвиса
class IMyService {
public:
    virtual ~IMyService() = default;
    virtual void DoSomething() = 0;
};

// РСализация сСрвиса
class MyService : public IMyService {
public:
    void DoSomething() override {
        // РСализация
    }
};

// РСгистрация сСрвиса Π² ΠΏΠ»Π°Π³ΠΈΠ½Π΅
bool MyPlugin::Initialize() {
    // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈ рСгистрация сСрвиса
    auto* service = new MyService();
    Wudgine::Core::ServiceLocator::GetInstance().RegisterService<IMyService>(service);
    
    return true;
}

// ИспользованиС сСрвиса Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ ΠΏΠ»Π°Π³ΠΈΠ½Π΅
bool OtherPlugin::Initialize() {
    // ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ сСрвиса
    auto* service = Wudgine::Core::ServiceLocator::GetInstance().GetService<IMyService>();
    if (service) {
        // ИспользованиС сСрвиса
        service->DoSomething();
    }
    
    return true;
}

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° событий

API ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² позволяСт Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с систСмой событий:

// ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ события
struct MyEvent {
    int value;
    std::string message;
};

// Подписка Π½Π° событиС
bool MyPlugin::Initialize() {
    // Подписка Π½Π° событиС
    Wudgine::Core::EventSystem::GetInstance().Subscribe<MyEvent>(
        [this](const MyEvent& event) {
            WG_LOG_INFO("ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ событиС: {} - {}", event.value, event.message);
        }
    );
    
    return true;
}

// ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° события
void MyPlugin::DoSomething() {
    // ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° события
    MyEvent event;
    event.value = 42;
    event.message = "ΠŸΡ€ΠΈΠ²Π΅Ρ‚, ΠΌΠΈΡ€!";
    
    Wudgine::Core::EventSystem::GetInstance().Publish(event);
}

ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ

API ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² прСдоставляСт инструмСнты для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒΡŽ:

// ИспользованиС ΠΏΡƒΠ»Π° ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
bool MyPlugin::Initialize() {
    // ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Π·Π°Π΄Π°Ρ‡ΠΈ Π² ΠΏΡƒΠ» ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
    Wudgine::Core::ThreadPool::GetInstance().Enqueue(
        []() {
            // Код, выполняСмый Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅
            WG_LOG_INFO("Π—Π°Π΄Π°Ρ‡Π° выполняСтся Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅");
        }
    );
    
    return true;
}

Π§Ρ‚ΠΎ дальшС?

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ Π·Π½Π°ΠΊΠΎΠΌΡ‹ с API ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ², Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅:

API ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² Wudgine прСдоставляСт ΡˆΠΈΡ€ΠΎΠΊΠΈΠ΅ возмоТности для Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π΄Π²ΠΈΠΆΠΊΠ°. ЭкспСримСнтируйтС ΠΈ создавайтС ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ для своих ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ²!

Wudgine β€’ Β© 2025