2013-05-28 2 views
0

Tout en écrivant un nouveau vst-plugin en utilisant VSTGUI Je suis vraiment aux prises avec la façon d'utiliser la bibliothèque, et la plupart des progrès sont réalisés à partir de deviner et de débogage après (parce qu'il il n'y a vraiment pas de documentation en dehors des millions de lignes et de ygrabit, ce qui n'indique guère plus que l'évidence).VSTGUI: Conventions pour éditeur :: open et éditeur :: close

Jusqu'à présent, il va bien, mais ma dernière contribution au projet en cause les discussions qui ont fait la conception un peu plus problématique. Plus précisément, je travaille sur un ensemble de textlabels dans un récipient (faire des opérations non atomiques) et ils peuvent (et ne peut évidemment) me destructed à mon insu, lorsqu'un utilisateur ferme la fenêtre. Même l'ajout de vérifications juste avant le changement d'éléments peut toujours poser problème. J'ai donc besoin de contrôler la durée de vie de ces objets (ce qui est bien), sauf quand ils sont affichés dans un CViewContainer, il assume automatiquement la propriété. Je n'ai aucune idée de comment écrire le backbone de l'éditeur, j'ai donc utilisé un programme appelé VSTGUIBuilder pour cela, et ajouté (et fondamentalement réécrit) ce dont j'avais besoin. Cependant, étant donné que tous les affichages vous pouvez travailler avec nécessite soit un parent ou d'un systemwindow, vous ne pouvez pas instancier des vues/contrôles avant d'atteindre la fonction AEffEditor :: Open(), qui est appelée chaque fois que la fenêtre est relevé. Et la méthode AEffEditor :: close() est appelée à chaque fois que la fenêtre est fermée. Maintenant, le vstguibuilder a mis un

delete frame; 

dans la méthode AEffEditor :: close() qui vous propose de reconstruire et distribuer toutes les ressources à chaque ouverture et de fermeture. Est-ce que cela peut être vrai? Et si elle est, est-il pas moyen que je peux protéger le contenu de mon conteneur (pour plus de détails qui est un vecteur < CTextLabel *>) d'obtenir supprimé mi-fonction? Il n'y a pas de problème pour s'en débarrasser par la suite, je suis juste en train de m'inquiéter de segfaults en le changeant.

L'utilisation de mutex et de tel est vraiment le dernier recours (si l'appel vient de l'hôte), je ne veux pas bloquer l'hôte dans tous les cas si mon code est défectueux et ne se libère jamais.

Edit: J'ai fini par trouver une solution qui est pas si élégante, mais fonctionne de façon sécuritaire. Voici le code dans la fonction de travailleur:

 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 est un autre « mutex » qui protège une file d'attente de messages, qui cette fonction imprimera. bDeleteLock protège le processus de copie du conteneur de ligne et de les «mémoriser», et les libère instantanément si par la suite. Les deux sont déclarés comme des boolés volatiles, cela ne devrait-il pas suffire? Voici la méthode close() btw.

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(); 

    } 

Répondre

0

Ahh, VSTGUI, qui ramène quelques souvenirs sombres. ;) Mais sérieusement, oui, vous devrez probablement utiliser un mutex pour empêcher l'hôte de pendre. Avoir à instancier tout quand la fenêtre rouvre semble un peu idiot, mais vous pouvez voir de nombreux plugins faire juste cela.

Une solution de contournement potentiel est d'utiliser un segment de mémoire partagée pour les données mises en cache vue, puis passer une référence à l'emplacement à votre plug-in

+0

Oui .. Je parie qu'il fait. Oui, j'ai fini par verrouiller les données dans un mutex de base, vous pouvez voir la solution affichée. Je trouve vraiment l'instanciation bizarre, mais je suppose que c'est une façon d'épargner de la mémoire alors que la fenêtre n'est pas ouverte (au prix de la puissance de traitement lors de l'ouverture). – Shaggi