编辑器::open和编辑器::close的约定

VSTGUI: Conventions for editor::open and editor::close

本文关键字:编辑器 约定 open close      更新时间:2023-10-16

在使用VSTGUI编写新的vst插件时,我真的很纠结于如何使用该库,大部分进展都是在猜测和调试之后取得的(因为除了百万行和ygrabit之外,真的没有文档,它所陈述的只是显而易见的)。

到目前为止,一切都很顺利,但是我对项目的最后贡献涉及线程,这使得设计更有问题。具体来说,我正在处理容器中的一组textlabel(执行非原子操作),当用户关闭窗口时,这些textlabel可能(显然确实)在我不知情的情况下被销毁。即使在更改元素之前添加检查也可能存在问题。所以我实际上需要控制这些对象的生命周期(这很好),除非它们显示在CViewContainer中,它会自动假定所有权。

我不知道如何编写编辑器的主干,所以我使用了一个名为VSTGUIBuilder的程序,并添加(基本上重写)了我需要的内容。然而,因为所有的"视图",你可以工作需要父或系统窗口,你不能实例化任何视图/控件之前达到AEffEditor::Open()函数,这是调用每当你的窗口弹出。当窗口关闭时,AEffEditor::close()方法被调用。现在,vstguibuilder添加了一个

delete frame;

在AEffEditor::close()方法中,建议您在每次打开和关闭时重建和分配所有资源。这真的是真的吗?如果是,有没有办法我可以保护我的容器的内容(具体来说是一个矢量)从中删除功能?之后处理它没有问题,我只是担心在更改它时出现分段错误。

使用互斥锁等是最后的手段(如果调用来自主机),我不想在任何情况下挂起主机,如果我的代码出错,永远不会释放。

编辑:我最终找到了一个解决方案,它不是那么优雅,但工作安全。下面是worker函数中的代码:

        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保护复制行容器和"记住"它们的过程,并在之后立即释放它。两者都被声明为易失性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();
    }

啊,VSTGUI,这让我想起了一些黑暗的记忆。,)但是说真的,是的,您可能必须使用互斥锁来防止宿主挂起。必须在窗口重新打开时实例化所有内容似乎有点愚蠢,但您可以看到许多插件就是这样做的。

一个潜在的解决方案是使用共享内存段缓存视图数据,然后将对该位置的引用传递回您的插件