KROYSDOCS
HomeWhat's newv0.1.0
C/C++ SDK

C/C++ plugin SDK

Native plugins build against the Plugin SDK only: a plain C ABI with versioned function tables and a header-only C++ layer, with any compiler, C runtime and configuration.

Headerskroys/kroys_plugin.h, kroys/plugin.hpp
SDK2.2.0
C types63
C++ types25
C ABI

The C ABI

Kroys Plugin SDK - C ABI (version 2.2).

The only header a native plugin needs. Plain C: fixed-width integers, floats, UTF-8 strings, plain structs, opaque handles and C function pointers. No STL, Dear ImGui or CRT objects cross the boundary, so a plugin builds with any compiler, C runtime and configuration (Docs/Architecture/PluginSDK.md).

A module exports two functions (KROYS_PLUGIN_EXPORT, C linkage):

int32_t     KroysPlugin_GetModuleInfo(KroysModuleInfo* info);
KroysResult KroysPlugin_Start(const KroysHost* host, KroysPluginCallbacks* callbacks);

The host calls Start once per target the module serves (editor, runtime). Start registers extensions through the host tables and fills callbacks.

Versioning: minor versions only append members to tables and structs. Every table and struct that crosses the boundary starts with structSize; KROYS_API_HAS checks an optional member. Memory: the host copies every input during the call; host strings stay valid until the next host call on the same thread; nothing is freed across the boundary. Threads: main thread unless a function or callback says otherwise. Errors: functions return KroysResult (0 = success) and set core->LastError. Never let an exception leave a callback.

HelloPlugin.c
static const KroysHost* gHost = 0;

static void KROYS_CALL Greet(void* userData)
{
    (void)userData;
    gHost->core->Log(gHost->context, KROYS_SEVERITY_INFO, "Hello from C.");
}

KROYS_PLUGIN_EXPORT int32_t KROYS_CALL KroysPlugin_GetModuleInfo(KroysModuleInfo* info)
{
    if (info == 0) return 0;
    info->structSize = (uint32_t)sizeof(KroysModuleInfo);
    info->targets = KROYS_TARGET_EDITOR;
    info->sdkVersion.major = KROYS_SDK_VERSION_MAJOR;
    info->sdkVersion.minor = KROYS_SDK_VERSION_MINOR;
    info->sdkVersion.patch = KROYS_SDK_VERSION_PATCH;
    info->pluginId = "HelloC";
    info->pluginVersion = "1.0.0";
    return 1;
}

KROYS_PLUGIN_EXPORT KroysResult KROYS_CALL KroysPlugin_Start(const KroysHost* host, KroysPluginCallbacks* callbacks)
{
    KroysCommandDesc command;
    KroysCommandCallbacks commandCallbacks;
    KroysHandle handle = 0u;
    (void)callbacks;
    if (host == 0 || host->editor == 0) return KROYS_E_UNSUPPORTED;
    gHost = host;

    memset(&command, 0, sizeof(command));
    command.structSize = (uint32_t)sizeof(command);   /* lets newer engines read older plugins */
    command.id = "Greet";
    command.label = "Say Hello (C)";
    memset(&commandCallbacks, 0, sizeof(commandCallbacks));
    commandCallbacks.structSize = (uint32_t)sizeof(commandCallbacks);
    commandCallbacks.Execute = &Greet;
    return host->editor->RegisterCommand(host->context, &command, &commandCallbacks, &handle);
}
RULES

Conventions

MemberMeaning
structSizeSize of this struct as the writer compiled it (sizeof); the reader uses it to detect members appended by later minor versions.
reservedPadding reserved for later use; leave it 0.
userDataPlugin-owned pointer passed back unchanged to every callback of this table; the host never dereferences it.
jobContextHost-owned job pointer; pass it unchanged to the job's functions.
sinkContextHost-owned sink pointer; pass it unchanged to Write.

Members marked since 2.1 were appended in that minor version: check them with KROYS_API_HAS(Type, pointer, Member) when the plugin may run on an older engine.

C++

The C++ layer

Kroys Plugin SDK - C++ convenience layer (header-only, C++17 or newer).

Compiled into the plugin, so it may use the standard library freely; it only calls the C ABI tables of kroys_plugin.h and never changes the ABI. It offers:

kroys::Plugin      base class (OnLoad / OnUnload / OnWorldStarted / OnWorldStopping)
kroys::Host        typed registration with lambdas, std::string results, kroys::Result
kroys::Ui          the editor UI API with RAII scopes (Section, Table, Tree, Id, Disabled)
kroys::World       scene access on a world (editor document or a running game)
KROYS_PLUGIN(Class, "id", "version", targets)   the two module exports

Every callback trampoline catches exceptions and reports them to the host (core->ReportFailure), which disables the plugin for the session: exceptions never cross the boundary. Closures registered through a Host live until that Host (one per plugin instance and target) is destroyed, after the host has removed every registration and called OnUnload.

KROYS_PLUGIN

Declares the module exports for a kroys::Plugin subclass with a default constructor:

KROYS_PLUGIN(MyPlugin, "MyCompany.MyPlugin", "1.0.0", KROYS_TARGET_EDITOR)

targets: KROYS_TARGET_EDITOR, KROYS_TARGET_RUNTIME or both (|).

HelloPlugin.cpp
class Hello final : public kroys::Plugin
{
public:
    bool OnLoad(kroys::Host& host) override
    {
        host_ = &host;
        kroys::CommandOptions greet{ "Greet", "Say Hello" };
        greet.toolbar = true;
        kroys::PanelOptions panel{ "Panel", "Hello" };
        return host.AddCommand(greet, [this] { host_->Notify(KROYS_SEVERITY_INFO, "Hello", text_); }) != 0u &&
               host.AddPanel(panel, [this](const kroys::Ui& ui, const KroysDrawArgs&)
               {
                   if (kroys::Ui::Section section{ ui, "Greeting" })
                   {
                       ui.InputText("Text", text_);
                       if (ui.Button("Say Hello", KROYS_UI_BUTTON_PRIMARY)) host_->Execute("Hello.Greet");
                   }
               }) != 0u;
    }

private:
    kroys::Host* host_ = nullptr;
    std::string text_ = "Hello!";
};

KROYS_PLUGIN(Hello, "Hello", "1.0.0", KROYS_TARGET_EDITOR | KROYS_TARGET_RUNTIME)
04

C: Basics

05

C: Basic types

06

C: Values

07

C: Module entry

08

C: Core (all targets)

09

C: Scene (all targets; permission scene.read / scene.write)

10

C: Tasks (editor)

11

C: UI (editor; valid only inside draw callbacks)

12

C: Editor

Constants and typesDefines, handles and callback types.KroysCommandDescA command (editor->RegisterCommand): command palette, Tools > Plugins menu, optional toolbar button and shortcut.KroysCommandCallbacksWhat a command runs (main thread).KroysPanelDescA dockable panel (editor->RegisterPanel), listed under Window.KroysDrawArgsPassed to every draw callback (panels, settings pages, viewport tools).KroysDrawCallbacksA draw callback (panels and settings pages).KroysSettingsPageDescA page in Settings > PLUGINS (editor->RegisterSettingsPage).KroysFileJobA file conversion running on a worker thread (import or export).KroysImporterDescAn importer (editor->RegisterImporter): File > Import and content drops of its extensions.KroysExporterDescAn exporter (editor->RegisterExporter): File > Export with Plugin.KroysFileJobCallbacksWhat an importer or exporter runs.KroysByteSinkReceives bytes: the plugin writes into it (asset hooks), the host writes into it (assets->ReadContentFile).KroysAssetTypeDescA plugin asset type (editor->RegisterAssetType): files with its extension in the Content Browser.KroysAssetTypeCallbacksThe hooks of a plugin asset type (all optional; main thread).KroysServiceCallbacksA per-frame editor service (editor->RegisterService).KroysAutomationJobContext of an automation step run by a capture script.KroysAutomationCallbacksAn automation step (editor->RegisterAutomationStep): capture scripts run it as `plugin-step [argument]`.KroysOperationCallbacksProgress and result of a long-running editor operation (editor->StartOperation, 2.2).KroysEditorApiThe editor: registrations, commands, notifications, the document scene, selection and undo transactions.
13

C: Viewport (editor, 2.1; capability viewport-tools)

14

C: Runtime (system graph)

15

C: Assets

16

C: Loopback networking (editor; permission network.loopback)

17

C: Host

18

C++ classes

Functions and aliasesFree functions and type aliases.kroys::EntityAn entity of a world (0: none); converts to true when set.kroys::Vec3A 3D vector (positions, directions).kroys::UiThe editor's immediate-mode UI (valid inside panel, settings page and tool draw callbacks).kroys::Ui::SectionRAII scopes.kroys::Ui::TableA table scope (BeginTable / EndTable); true when visible.kroys::Ui::TreeA tree node scope (TreeNode / TreePop, also for leaves); true when open.kroys::Ui::IdAn id scope (PushId / PopId) for repeated widgets.kroys::Ui::DisabledA block drawn disabled (BeginDisabled / EndDisabled).kroys::WorldScene access on a world: the editor document (Host::Document) or a running game (system ticks).kroys::ComponentTypeBuilderBuilds a component type description (fields keep their strings alive).kroys::FileJobAn import or export job (worker thread).kroys::TaskJobA running editor task (worker thread).kroys::AutomationJobAn automation step's context.kroys::CommandOptionsOptions of Host::AddCommand (KroysCommandDesc).kroys::PanelOptionsOptions of Host::AddPanel (KroysPanelDesc).kroys::SettingsPageOptionsOptions of Host::AddSettingsPage (KroysSettingsPageDesc).kroys::FileConverterOptionsOptions of Host::AddImporter and Host::AddExporter (KroysImporterDesc, KroysExporterDesc).kroys::AssetTypeOptionsOptions of Host::AddAssetType (KroysAssetTypeDesc).kroys::AssetTypeHooksHooks of Host::AddAssetType (KroysAssetTypeCallbacks); empty hooks are not registered.kroys::ViewportToolOptionsOptions of Host::AddViewportTool (KroysViewportToolDesc).kroys::ViewportToolHooksHooks of Host::AddViewportTool (KroysViewportToolCallbacks).kroys::SystemOptionsOptions of Host::AddSystem (KroysSystemDesc).kroys::HostThe plugin's host for one target: typed registrations with lambdas, the document scene, selection, tasks, settings and logging.kroys::Host::TransactionOne undo step for every document edit made while it lives.kroys::PluginOne object per target the module serves (a module for both targets gets two: check host.IsEditor() / host.IsRuntime()).

Generated from the comments of kroys/kroys_plugin.h and kroys/plugin.hpp by Tools/BuildDocsSite.py. Every struct member, function pointer, enum value and public C++ member is documented.