繁體中文
English 简体中文 繁體中文
Methodox 首頁

外掛開發

最簡單的外掛形式就是一個普通的 C# 類。如果你只想公開一些簡單的函式,請使用靜態類:

public static class MyPlugin
{
	public static int GetValue() => 15;
}

1. 外掛功能標誌

宿主通過 PluginFeature 標誌公開一組能力。在嘗試使用某個子系統之前,外掛應呼叫 GetFeatureSet() 並檢查相關標誌。可用的功能如下:

  • Menus (1) 宿主可以建立新的頂級選單和巢狀子選單。
  • DynamicPackages (2) 宿主可以在執行時向 Divooka 的工具箱中新增新的節點型別(通常稱為“包”)。
  • EditorQuery (4) 宿主允許查詢和修改圖的執行時狀態(例如讀取節點值、連線/斷開引腳)。
  • ConnectorVisualCustomizations (8) 宿主允許自訂節點引腳連線的外觀(形狀 + 顏色)。
  • CustomNodeSurface (16) [已過時] 已計劃但尚未實現:完全自訂節點表面(超出內建的引腳/聯結器渲染範圍)。
  • PreviewProcessor (32) 宿主支援註冊例程,將任意資料轉換為 Divooka 可以原生預覽的型別(例如影像、文字、圖)。
  • CustomPreviewControl (64) [已過時] 已計劃但尚未實現:嵌入自訂預覽控制元件(例如自訂的 WPF 或 Godot 控制元件)。
  • CustomPreviewHandler (128) 宿主支援為任何節點型別提供完全自訂的“彈出式”預覽處理程式(外掛完全控制預覽在單獨視窗中的渲染方式)。

外掛應通過按位運算組合這些標誌(例如 if ((features & PluginFeature.Menus) != 0) { … }),以確定在執行時要註冊或啟用哪些內容。

外掛確認 PluginFeature.Menus 可用後,就可以向 Divooka 的主選單欄新增選單項並註冊巢狀子選單。每個選單項在被按一下時呼叫一個回撥。

// Add or remove a top‑level menu item:
void RegisterMenu(
    string menu,                  // unique identifier (e.g. "MyPlugin/Tools")
    string title,                 // user‑facing text
    string? tooltip,              // optional hover text
    Action<IDivookaEngineHostEnvironment> clickCallback,
    bool autoUnregister           // if true, host will remove it on plugin unload
);

void UnregisterMenu(string menu, string title);

// Add or remove a submenu under an existing menu:
void RegisterSubmenu(
    string menu,                  // same “menu” key as above
    string submenu,               // unique identifier for the submenu entry
    string title,
    string? tooltip,
    Action<IDivookaEngineHostEnvironment> clickCallback,
    bool autoUnregister
);

void UnregisterSubMenu(string menu, string submenu, string title);
  • 要點
    • menu 和 submenu 是識別符號(不一定是顯示的文字)。
    • title 是終端使用者看到的內容。
    • autoUnregister 讓宿主在外掛解除安裝時進行清理。

3. 節點聯結器外觀

如果支援 ConnectorVisualCustomizations,外掛就可以為任意給定的資料型別自訂引腳(輸入/輸出埠)和連線的外觀。

void RegisterTypeConnectionAppearance(
    Type type,                    // the .NET type to style (e.g., typeof(MyCustomData))
    BuiltinConnectorShape shape,  // one of: HollowCircle, SolidSquare, etc.
    Color color                   // base color for the connector (e.g., System.Drawing.Color.Red)
);
  • BuiltinConnectorShape 一個包含內建形狀的小型列舉(HollowCircle、HollowRectangle、HollowTriangle、HollowArrow、HollowSquare,以及對應的“Solid”形狀)。
  • 用法 儘早註冊(例如在外掛初始化期間)。之後,Divooka 會使用你選擇的形狀 + 顏色來渲染所有承載該 CLR 型別的引腳。

4. 預覽處理

Divooka 允許節點為其資料提供一個小型預覽(例如顯示影像、文字片段或圖)。有兩種不同的擴充點:

  1. Preview Processor(需要 PreviewProcessor 標誌)

    void RegisterPreviewProcessor(
        Type type,                     // the data type your plugin wants to handle
        Func<object, object> processor // a function that converts “type” into a built‑in previewable type (e.g., Bitmap, string, List<float>, etc.)
    );
    
    • 何時使用: 如果你的外掛的節點輸出 Divooka 無法原生渲染的自訂資料型別,請實現一個處理器,把它轉換為宿主已經知道如何顯示的型別。
    • 示例: 將 MyImageData 例項轉換為 System.Drawing.Bitmap。
  2. Custom Preview Handler(需要 CustomPreviewHandler 標誌)

    void RegisterCustomPreviewHandler(
        Type instanceType,                 // the .NET type for which you supply full control
        Action<ProcessorNode, object> previewHandler
    );
    
    • 何時使用: 如果你需要一個宿主無法處理的完全自訂的彈出式預覽(例如互動式圖表或 3D 檢視)。
    • 行為: 每當使用者請求預覽時,Divooka 都會呼叫你的 previewHandler,並將節點例項以及原始資料物件傳給你。你的程式碼負責顯示視窗或控制元件、渲染內容、掛接關閉事件等。注意:這隻能以單獨的彈出視窗形式工作,不能內嵌在畫布上。

5. 動態型別 / 工具箱註冊

如果啟用了 DynamicPackages,外掛就可以向 Divooka 告知新的節點型別——既包括後端功能(節點做什麼),也包括前端工具箱條目(它在介面中出現在哪裡)。RegisterPackages 呼叫統一處理以下幾類定義集合:

void RegisterPackages(
    IEnumerable<ToolboxIndexer.AssemblyToolboxDefinition>? assemblyToolboxes,
    IEnumerable<ToolboxIndexer.FrontendToolboxDefinition>? frontendToolboxes,
    IEnumerable<ToolboxIndexer.TypeToolboxDefinition>? typedToolboxes,
    IEnumerable<ToolboxIndexer.SpecificToolboxEndPointDefinition>? specificEndpoints,
    IEnumerable<ToolboxIndexer.ProceduralContextBaseTypeDefinition>? proceduralContextTypes,
    bool autoUnregister = true
);
  • AssemblyToolboxDefinition 定義整個程式集的節點——Divooka 可以在執行時掃描程式集,找到被註解為節點的類,然後自動填充工具箱。
  • FrontendToolboxDefinition 描述你希望如何在 Divooka 的介面中對節點進行分組和標註(例如資料夾圖示、類別)。
  • TypeToolboxDefinition 將單個 .NET 型別顯式註冊為節點——如果你希望精細控制其名稱、圖示和出現位置,這會很有用。
  • SpecificToolboxEndPointDefinition 讓你可以把一個節點放在多個位置,或放在專門的上下文選單下。
  • ProceduralContextBaseTypeDefinition 如果你的外掛提供了一個“過程式上下文”(一種以自訂方式執行一組節點的有狀態環境),就在這裡註冊其基型別,讓 Divooka 瞭解你的執行時執行模型。

註冊完成後,Divooka 的介面會在工具箱中顯示這些新的節點型別;使用者可以像使用內建節點一樣,將它們拖放到畫布上。

6. 過程式上下文執行執行器

對於引入自訂過程式執行上下文的外掛,請使用:

void RegisterProceduralContextExecutionRunner(
    Type baseType,            // the abstract base for all of your procedural contexts
    Type instantiatorType     // a factory/runner class that knows how to execute that context
);
  • 用途 告訴 Divooka:“每當一個以派生自 baseType 的型別為根的節點圖需要執行時,就使用這個 instantiatorType 來執行它。”
  • 行為 Divooka 會在執行時例項化你的執行器並把節點圖交給它;你的執行器負責遍歷節點、按正確的順序對它們求值併產生輸出。

7. 總結

  1. 啟動時
    • 查詢 GetFeatureSet()。
    • 如果支援選單,則按條件呼叫 RegisterMenu/RegisterSubmenu。
    • 如果你有自訂資料型別,呼叫 RegisterTypeConnectionAppearance 為它們設定獨特的引腳形狀/顏色。
    • 如果你想新增新節點,請準備好工具箱定義(程式集掃描、型別描述符等)並呼叫 RegisterPackages。
  2. 外掛初始化期間
    • 如果需要為預覽轉換節點輸出,請使用 RegisterPreviewProcessor 註冊一個處理器。
    • 如果需要完全控制預覽(例如在浮動視窗中顯示 3D 模型),請使用 RegisterCustomPreviewHandler 註冊一個處理程式。
    • 如果你的節點需要特殊的執行環境,請註冊一個 ProceduralContextExecutionRunner。
  3. 關閉(或解除安裝)時
    • 如果你設定了 autoUnregister = true,那麼當 Divooka 解除安裝外掛時,大多數註冊內容(選單、包、預覽處理程式)都會被自動清理。否則,請顯式呼叫 UnregisterMenu、UnregisterSubMenu 以及所需的任何自訂清理操作。

外掛作者檢查清單

  • 功能檢測

    var features = host.GetFeatureSet();
    if ((features & PluginFeature.Menus) != 0)
        RegisterMenus();
    if ((features & PluginFeature.DynamicPackages) != 0)
        RegisterPackages(...);
    // etc.
    
  • 選單

    • 使用 RegisterMenu/RegisterSubmenu 新增按一下即執行的操作。
    • 始終提供唯一的鍵(例如 "MyPlugin/Tools/DoSomething")。
  • 節點外觀

    • 使用 RegisterTypeConnectionAppearance(typeof(MyType), BuiltinConnectorShape.SolidCircle, Color.Blue) 為 MyType 的節點設定藍色圓形引腳。
  • 預覽支援

    • 如果你的節點輸出自訂資料型別,請實現 Func<object, object>,將其轉換為現有的可預覽物件(字串、Bitmap、陣列等)。
    • 如果你需要彈出式編輯器,或者需要 Divooka 無法原生預覽的內容,請實現自訂預覽處理程式。
  • 動態型別(工具箱)

    • 在 RegisterPackages 中提供一個或多個工具箱定義。
    • 如果只想掃描整個程式集,請使用 AssemblyToolboxDefinition。如果想嚴格控制單個節點的後設資料,請使用 TypeToolboxDefinition。
  • 執行

    • 如果你的外掛包含必須在專門上下文中執行的節點,請註冊一個 ProceduralContextExecutionRunner,將你的圖的基型別對映到某個執行器/工廠。

上述各部分就緒後,Divooka 會自動顯示你的選單、渲染你的節點引腳、讓使用者把你的自訂節點型別拖入圖中,並且在使用者按一下“Run”或請求預覽時,在底層呼叫你的轉換器或自訂預覽程式碼。

通過把功能歸入這六個方面(功能標誌、選單、節點外觀、預覽、動態型別註冊和執行執行器),你可以確保外掛與 Divooka 的宿主環境順暢整合,並遵循預期的擴充點。

另請參閱

更多 C# 技巧。