2009-11-24 5 views
0

J'écris des liaisons C# pour la bibliothèque C contrôlant le serveur de sons pulseaudio, et je ne sais pas comment lier idiomatiquement certains objets potentiellement passifs exposés: en particulier les puits. Pulseaudio a le concept d'un évier audio - le matériel auquel un flux audio donné est joué. Cela se mapperait naturellement à une classe Sink, avec des propriétés évidentes - volume et autres. Le problème est hotplug - le matériel audio peut aller et venir pendant l'exécution, et donc de tels objets Sink peuvent finir comme des zombies faisant référence à du matériel inexistant, et toutes les opérations effectuées sur eux échoueront. Pire encore, la bibliothèque C n'offre pas de poignées uniques aux récepteurs, donc une séquence d'événements hotplug pourrait changer le matériel qu'une instance Sink donnée contrôle réellement sans que le code ne s'en aperçoive.Une façon idiomatique d'envelopper un objet potentiellement transitoire

Ces deux problèmes sentent. Je veux fournir une abstraction de Sink, mais je ne sais pas comment éviter ces problèmes.

Comment d'autres personnes dans une situation similaire ont-elles géré ce genre de problème? Dans la bibliothèque C, il semble que vous n'espérez aucun événement hotplug entre l'interrogation des récepteurs et la modification de leurs propriétés. Les puits sont identifiés dans l'API par un index, mais ce n'est pas stable. Chaque puits a aussi une chaîne d'identifiant qui est, je pense, unique, au moins pour chaque cycle.

Il existe une API pour obtenir des rappels sur divers événements intéressants, tels que hotplug, de sorte qu'il serait possible de connecter chaque Sink à cela et au moins être averti quand il s'en ira.

+0

Comment c gère-t-il cette situation? Est-ce que vous simplement requery pour l'évier chaque fois que vous en avez besoin? – JeffreyABecker

+0

Cela ressemble à un problème vraiment délicat. Je ne peux que penser (hors de ma tête) de sondage. Certainement pas une solution élégante. –

Répondre

1

Je pense que vous devriez essayer de communiquer ce comportement de la bibliothèque C à l'utilisateur de votre bibliothèque C#.

Je ne suis pas familier avec PulseAudio, mais se basant sur les informations sur les identificateurs uniques que vous avez données, une conception possible pour une classe Sink pourrait ressembler à ceci:

/// <summary> 
/// Represents a sink. May refer to different hardware. 
/// </summary> 
public class Sink 
{ 
    public static IEnumerable<string> GetCurrentIdentifiers() { ... } 

    public static Sink GetSinkForIdentifier(string identifier) { ... } 

    private Sink() { ... } 
} 

lecture intéressante: The Law of Leaky Abstractions

Donc, ma recommandation serait de ne pas essayer de créer une abstraction (qui fuit) mais simplement d'exposer les concepts de pulseaudio.

+0

Je pense que je finirai par faire les deux; essayez une abstraction encore plus élevée pour les puits, mais exposer également les concepts PulseAudio sous-jacents pour attraper les gouttes. – RAOF

0

Vous ne pouviez pas simplement écouter l'événement HotPlug, puis l'envoyer à l'application à l'aide de votre bibliothèque? Le modèle C# normal consiste à implémenter INotifyPropertyChanged pour votre classe Sink.

0

Si PulseAudio ne vous informe pas des événements matériels, la gestion de cette situation est fondamentalement indéfendable. Vous devez écrire quelques patchs dans la bibliothèque C de PA pour gérer cela avec élégance, même si je suis assez surpris que PA ne soit pas du tout exposé aux périphériques hotplug.

+0

J'ai ajouté quelques informations supplémentaires au message original. PA fournit plusieurs rappels, y compris des événements hotplug. Cela permet au moins de faire face au deuxième problème (au prix d'un peu de frais généraux), mais me laisse toujours avec un Sink zombie. Les consommateurs de la bibliothèque se retrouveront avec un objet Sink pour lequel toutes les opérations échouent, ce qui semble laid. – RAOF

Questions connexes