0

VSTGUI を使用して新しい vst-plugin を作成している間、私はライブラリの使用方法に本当に苦労しており、ほとんどの進歩は後で推測してデバッグすることから得られます (実際には 100 万行と ygrabit 以外にドキュメントがないため、明らかです)。

これまでのところうまくいっていますが、プロジェクトへの私の最後の貢献にはスレッドが含まれていたため、設計が少し問題になりました。具体的には、コンテナ内の一連のテキストラベルに取り組んでおり(非アトミック操作を行っています)、ユーザーがウィンドウを閉じると、知らないうちにこれらが破壊される可能性があります(明らかに破壊されます)。要素を変更する直前にチェックを追加しても、まだ問題になる可能性があります。したがって、これらのオブジェクトの有効期間を実際に制御する必要があります (これは問題ありません)。ただし、CViewContainer に表示されている場合を除き、自動的に所有権が想定されます。

エディターのバックボーンの書き方がわからないので、これには VSTGUIBuilder というプログラムを使用し、必要なものを追加 (および基本的に書き直しました) しました。ただし、操作できるすべての「ビュー」には親またはシステム ウィンドウが必要なため、ウィンドウがポップアップするたびに呼び出される AEffEditor::Open() 関数に到達する前にビュー/コントロールをインスタンス化することはできません。そして、ウィンドウが閉じられるたびに AEffEditor::close() メソッドが呼び出されます。今、vstguibuilder は

delete frame;

AEffEditor::close() メソッド内で、開いたり閉じたりするたびにすべてのリソースを再構築して分配することを提案します。これは本当に真実でしょうか?もしそうなら、コンテナのコンテンツ(詳細はベクトル< CTextLabel *>)が機能の途中で削除されないように保護する方法はありませんか?後で処分しても問題ありません。変更中のセグメンテーション違反が心配です。

ミューテックスなどを使用するのは本当に最後の手段です (呼び出しがホストからのものである場合)。コードに障害が発生して解放されない場合は、ホストをハングさせたくありません。

編集:私は、それほどエレガントではないが安全に動作するソリューションを見つけました。ワーカー関数のコードは次のとおりです。

        while(bLock) {
            Sleep(0);
        }
        bLock = true;

        if(msgs.empty())
            return;

        /*
            Prevent someone deletes our lines in close().
            we create a copy of the container to be 100% sure
            and increase the reference count, so we can safely
            work with our own container and we 'forget' them
            afterwards, so they will be deleted if needed.
            This ensures that close AND open can be called 
            meanwhile we are working with the lines
        */
        bDeleteLock = true;
        // also the copy constructor should work as expected here
        // since we are working with pointers, we still reference the same content.
        auto copy_lines = lines;

        for each(auto line in copy_lines) {
            line->remember();
        }
        bDeleteLock = false;

        ...

        for each(auto line in copy_lines) {
            line->forget();
        }
        cont->setDirty();

bLock は、この関数が出力するメッセージ キューを保護する別の「ミューテックス」です。bDeleteLock は、行コンテナーをコピーしてそれらを「記憶」するプロセスを保護し、後ですぐに解放します。どちらも volatile bool として宣言されていますが、それで十分ではないでしょうか? これが close() メソッドです。

    void CConsole::Close() {
        // locking lines while copying them over in a container we can work with
        while(bDeleteLock)
            Sleep(0);
        //waiting for bLock is not needed because it wont get deleted.
        if(!visible) //if we are not visible it's our responsibility to remove the view
            delete cont;

        lines.clear();

    }
4

1 に答える 1

0

ああ、VSTGUI、それは暗い記憶をよみがえらせます。;) しかし、真剣に、ホストがハングするのを防ぐためにミューテックスを使用する必要があるでしょう。ウィンドウが再度開いたときにすべてをインスタンス化する必要があるのはちょっとばかげているように思えますが、多くのプラグインがまさにそれを行っているのを見ることができます。

考えられる回避策の 1 つは、キャッシュされたビュー データに共有メモリ セグメントを使用し、その場所への参照をプラグインに戻すことです。

于 2013-05-29T06:57:32.770 に答える