SleddogSoftwareDevelopment / blink1

Interfacing for Blink(1)
BSD 3-Clause "New" or "Revised" License
13 stars 4 forks source link

IBlink has Dispose() but doesn't implement IDisposable #12

Open ImaginaryDevelopment opened 5 years ago

ImaginaryDevelopment commented 5 years ago

https://github.com/SleddogSoftwareDevelopment/blink1/blob/master/src/Sleddog.Blink1/IBlink1.cs

Sleddog.Blink1.Blink1Connector.Scan() used to return a type that implements IDisposable and the method is carried forward but it doesn't actually implement it.

ImaginaryDevelopment commented 5 years ago

resulting work around wrapper: https://github.com/ImaginaryDevelopment/LinqPad/blob/master/LINQPad%20Queries/ThingM/listen%20for%20Audio%20and%20blink.linq#L17-L30

ImaginaryDevelopment commented 5 years ago

c# sample work around

//references nuget packages hidlibrary and NAudio
using NAudio;
using System.Reactive.Linq;
using Sleddog.Blink1;
using System.Reactive;
using NAudio.Wave;
void Main()
{
    // by imaginarydevelopment.blogspot.com
    // twitter @maslowjax
    Listen(() => Util.ReadLine());
}

IBlink1 GetBlink()
{
    return Sleddog.Blink1.Blink1Connector.Scan().FirstOrDefault();
}

void Listen(Action fUntil)
{
    var captureCount = 0;
    using (var waveIn = new NAudio.Wave.WasapiLoopbackCapture())
    using (var blink = new WrapDisposable(GetBlink()))
    {
        var sampleThrottle = TimeSpan.FromSeconds(5.5);
        void OnAudio(NAudio.Wave.WaveInEventArgs evArgs)
        {
            captureCount++;
            blink.Item.Blink(System.Drawing.Color.Red, TimeSpan.FromSeconds(1.0), 2);
            (DateTime.Now, evArgs).Dump();
        }
        using (var sub =
            Observable.FromEventPattern<NAudio.Wave.WaveInEventArgs>(target: waveIn, eventName: nameof(waveIn.DataAvailable))
            .Where(evArgs => evArgs.EventArgs.Buffer.Any(b => b != 0)).Sample(sampleThrottle).Select(evArgs => evArgs.EventArgs).Subscribe<WaveInEventArgs>(onNext: OnAudio)
            )
            waveIn.WaveFormat.Dump()
        waveIn.StartRecording();
        fUntil()
        waveIn.StopRecording();
        captureCount.Dump();

    }
}
}

interface IDisposalWrapper<T> : IDisposable
{
    T Item { get; }
    bool IsDisposed { get; }
}

// IBlink has dispose method but doesn't implement IDisposable
class WrapDisposable : IDisposalWrapper<IBlink1>, IDisposable
{
    IBlink1 item;
    public IBlink1 Item
    {
        get
        {
            if (this.IsDisposed)
                throw new InvalidOperationException("Object is disposed");
            return item;
        }
    }
    public bool IsDisposed { get; private set; }
    public void Dispose()
    {
        if (!this.IsDisposed)
        {
            item.Dispose();
            this.IsDisposed = true;
            item = null;
        }
    }

    public WrapDisposable(IBlink1 item) { this.item = item; }
}