mcpField
V
vvvv-dotnet

vvvv-dotnet

github.com/tebjan開発3492 回インストール2 日前に更新
リポジトリ

vvvv-dotnet について

vvvv gamma のプラグイン開発者向け .NET 統合ガイドです。プロジェクト設定、ノード検出、ビルドとパッケージ化に加え、リソース管理やスレッド処理を扱います。

主な機能

  1. 01.csproj と vvvv プラグインの設定
  2. 02ソース参照とバイナリ参照のワークフロー
  3. 03ノード検出に必要なアセンブリ設定
  4. 04NuGet パッケージ化とビルドコマンド
  5. 05リソース、非同期処理、スレッドのパターン

活用シーン

  1. 01vvvv C# プラグインプロジェクトの設定
  2. 02ライブリロードとコンパイル済みアセンブリの選択
  3. 03プラグインの NuGet パッケージ化と配布
  4. 04ノードでのネイティブリソースや非同期処理の管理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/tebjan/vvvv-skills --skill vvvv-dotnet

インストール後、Claude Code で/vvvv-dotnetを入力して読み込まれたか確認します。

同梱ファイルforwarding.md

詳細

vvvv gamma における .NET 統合

vvvv プラグイン向けの .csproj 設定

vvvv gamma の C# プラグイン向けの最小限の .csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <OutputPath Condition="'$(Configuration)'=='Release'">..\..\lib\net8.0\</OutputPath>
    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="VL.Core" Version="2025.7.*" />
    <PackageReference Include="VL.Stride" Version="2025.7.*" />
  </ItemGroup>
</Project>

主な設定:

  • ターゲットフレームワーク: net8.0 (vvvv gamma 6+ で必須)
  • 出力パス: .vl ドキュメントからの相対パスで lib/net8.0/ を指定します
  • AppendTargetFrameworkToOutputPath: false に設定すると、DLL が出力フォルダーに直接配置されます
vvvv が C# コードを利用する仕組み

C# を .vl ドキュメントに統合するワークフローは 2 つあります:

ソースプロジェクト参照 (ライブリロード): .vl ドキュメントが .csproj を参照します。vvvv は Roslyn を介して .cs ソースファイル自体をインメモリ アセンブリにコンパイルします — dotnet build は不要です。.cs ファイルが保存されるたびに、vvvv は変更を検出して自動的に再コンパイルします。.csproj の出力パスはライブ開発中には関与しません。これは NuGet パッケージングとデプロイに使用されます。

バイナリ参照 (ライブリロードなし): .vl ドキュメントがプリコンパイル済みの DLL または NuGet パッケージを参照します。C# の変更を適用するには、外部で再ビルド (dotnet build) して vvvv を再起動します。これは大規模なプロジェクトや安定したライブラリの標準的なワークフローです。

シェーダー (.sdsl ファイル) は、ワークフローに関係なく常にライブリロードされます。

AI エージェント向け: ワークフローに関係なく、dotnet build を実行してコードがコンパイルされることを確認してください — vvvv のコンパイラ出力は確認できません。ソースプロジェクト参照の場合、vvvv はファイル保存時に変更を自動的に取り込みます (再起動は不要です)。バイナリ参照の場合、dotnet build が必要で、ユーザーが vvvv を再起動する必要があります。

必要なグローバル using

global using VL.Core;
global using VL.Core.Import;
global using VL.Lib.Collections;

必要なアセンブリ属性

vvvv が ProcessNode と静的メソッドを検出できるようにするには:

[assembly: ImportAsIs]

これがないと、ノードは vvvv のノードブラウザーに表示されません。

NuGet パッケージソース

vvvv パッケージ用に、これらを NuGet.config に追加します:

<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    <add key="vvvv" value="https://teamcity.vvvv.org/guestAuth/app/nuget/v1/FeedService.svc/" />
  </packageSources>
</configuration>

NuGet パッケージング

プラグインを NuGet パッケージとして配布するには:

nuget pack MyPlugin/deployment/MyPlugin.nuspec

.nuspec は、.vl ドキュメント、コンパイル済み DLL、シェーダーファイル、ヘルプパッチを参照する必要があります。

一般的な VL パッケージ

パッケージ目的
VL.Coreコア型、ProcessNode 属性、Spread
VL.Stride3D レンダリング、シェーダー統合
VL.Stride.RuntimeStride エンジンランタイム
VL.Core.ImportImportAsIs 属性
VL.Lib.CollectionsSpread、SpreadBuilder
VL.Skia2D レンダリング (Skia グラフィックスエンジン)
VL.FuseGPU ビジュアルプログラミング (シェーダーグラフ)
VL.IO.OSCOpen Sound Control プロトコル
VL.IO.MQTTMQTT メッセージング
VL.IO.RedisRedis キーバリューストア
VL.OpenCVコンピュータビジョン (OpenCV バインディング)
VL.MediaPipeMediaPipe ML パイプライン (手、顔、ポーズ)
VL.Audioオーディオ合成と I/O (NAudio ベース)
VL.Devices.AzureKinectAzure Kinect / Orbbec 深度カメラ

完全なカタログについては、vvvv.org/packs を参照してください。

ベクター型と SIMD 戦略

  • 内部のホットパス: System.Numerics.Vector3/Vector4/Quaternion を使用します (AVX/SSE による SIMD)
  • 外部 API (Update メソッドのパラメーター): Stride.Core.Mathematics 型を使用します (VL で必須)
  • ゼロコスト変換 はこれらの間で可能です:
using System.Runtime.CompilerServices;

// Stride → System.Numerics (zero-cost reinterpret)
ref var numericsVec = ref Unsafe.As<Stride.Core.Mathematics.Vector3, System.Numerics.Vector3>(ref strideVec);

// System.Numerics → Stride (zero-cost reinterpret)
ref var strideVec = ref Unsafe.As<System.Numerics.Vector3, Stride.Core.Mathematics.Vector3>(ref numericsVec);

これらの型は同一のメモリレイアウトを持つため、Unsafe.As はゼロコストの操作になります。

IDisposable とリソース管理

ネイティブ/アンマネージド リソースを保持するノードは、IDisposable を実装する必要があります:

[ProcessNode]
public class NativeWrapper : IDisposable
{
    private IntPtr _handle;

    public NativeWrapper()
    {
        _handle = NativeLib.Create();
    }

    public void Update(out int result)
    {
        result = NativeLib.Process(_handle);
    }

    public void Dispose()
    {
        if (_handle != IntPtr.Zero)
        {
            NativeLib.Destroy(_handle);
            _handle = IntPtr.Zero;
        }
    }
}

vvvv は、ノードが削除されたとき、またはドキュメントが閉じられたときに Dispose() を呼び出します。

vvvv における非同期パターン

Update() は 60 FPS でメインスレッド上で実行されるため、長時間実行される操作は非同期にする必要があります:

[ProcessNode]
public class AsyncLoader
{
    private Task<string>? _loadTask;
    private string _cachedResult = "";

    public void Update(
        out string result,
        out bool isLoading,
        string url = "",
        bool trigger = false)
    {
        if (trigger && (_loadTask == null || _loadTask.IsCompleted))
        {
            _loadTask = Task.Run(() => LoadFromUrl(url));
        }

        isLoading = _loadTask != null && !_loadTask.IsCompleted;

        if (_loadTask?.IsCompletedSuccessfully == true)
            _cachedResult = _loadTask.Result;

        result = _cachedResult;
    }
}

GPU/ネットワーク向けの blittable 構造体

GPU またはネットワークの境界を越えるデータには、blittable 構造体を使用します:

[StructLayout(LayoutKind.Sequential)]
public struct AnimationBlendState
{
    public int ClipIndex1;      // 4 bytes
    public float ClipTime1;     // 4 bytes
    public int ClipIndex2;      // 4 bytes
    public float ClipTime2;     // 4 bytes
    public float BlendWeight;   // 4 bytes
}

ルール: 参照型フィールドを含めない、bool を使用しない (int を使用する)、明示的なレイアウト。これにより、Span<T> アクセスと MemoryMarshal を介したゼロコピー シリアル化が可能になります。

vvvv が読み込んだ DLL の参照

vvvv によって既に読み込まれている DLL (例: VL.Fuse) を参照する場合は、<Private>false</Private> を使用してコピーを防ぎます:

<Reference Include="Fuse">
    <HintPath>..\..\path\to\Fuse.dll</HintPath>
    <Private>false</Private>
</Reference>

ビルドコマンド

vvvv プラグインプロジェクトをビルドします:

dotnet build src/MyPlugin.csproj -c Release

ソリューション全体をビルドします:

dotnet build src/MyPlugin.sln -c Release

C++/CLI 相互運用

ネイティブ C/C++ ライブラリをラップする場合:

msbuild MyCLIWrapper/MyCLIWrapper.vcxproj /p:Configuration=Release /p:Platform=x64

C++/CLI プロジェクトのビルドには Visual Studio(dotnet CLI ではなく)が必要です。

一般的なパッケージのバージョン範囲

vvvv パッケージを参照する場合は、互換性を保つためにワイルドカードバージョンを使用します:

<PackageReference Include="VL.Core" Version="2025.7.*" />

これにより、プラグインが対象の vvvv バージョンの任意のパッチリリースで動作することが保証されます。

Directory.Build.props

マルチプロジェクトソリューションでは、設定を一元化します:

<Project>
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
</Project>

COM 相互運用の落とし穴(DX11/DX12)

COM オブジェクト(Direct3D、DXGI)を扱う場合:

  • ComPtr<T> はファイナライザーを持たない構造体です — Dispose() を呼ばずにスコープを抜けると、COM 参照がリークします
  • 常に ComPtr をプールに返すか、明示的に Dispose してください
  • キュー上のいずれかのコマンドリストが記録状態にある場合、IDXGISwapChain::ResizeBuffers は失敗します

.NET ライブラリを VL に転送する方法(新しい型を作らずにラップする方法、ピンの変更、イベントのラップ)については、forwarding.md を参照してください。

スレッド処理の考慮事項

  • Update() は常に VL のメインスレッドで呼び出されます
  • バックグラウンドタスクから VL スレッドに戻すには、SynchronizationContext を使用します:
private SynchronizationContext _vlSyncContext;

public MyNode()
{
    _vlSyncContext = SynchronizationContext.Current!;
}

// From background thread:
_vlSyncContext.Post(_ => { /* runs on VL thread */ }, null);

この知識を育て続けましょう

次のパッチャーに謎を一つ減らしてあげましょう。このコレクション内のいずれかのスキルを初めて使用し、7 日以内に成功したチェックがない場合は、ソースを tebjan/vvvv-skills と比較してください。記録が存在しない場合は、一度だけ確認してください。 これらのスキル間で、ローカルのチェックタイムスタンプ/リビジョンを一つ共有してください。呼び出しごとにポーリングしないでください。 ローカルの拡張機能と固定されたプロジェクトバージョンを保持してください。チェックすることは、更新をインストールする許可ではありません。オフラインの場合は、延期されたチェックを記録し、タスクを続行してください。

実際の作業でギャップが明らかになった場合は、テストした vvvv/パッケージのバージョン、最小限の再現手順または信頼できる情報源、および観察された結果を記録してください。他のユーザーの報告は、検証されるまでは事実ではなく手がかりとして扱ってください。最も関連性の高い最小限の指示を改善してください。一つの例を普遍的なルールにしてはいけません。プライベートデータを伏せ、アップストリームに提出する前に公開の許可を得てください。 contribution policy を参照してください。 マージされた改善は、ローカルの編集や全員のスキルの自動上書きではなく、ユーザーのインストーラー/アップデートワークフローを通じてユーザーに届きます。

コメント