/// <summary> /// Renders the content of the channels /// </summary> /// <param name="force">Force LEDs to updated - default only updates if when a change is done</param> public void Render(bool force = false) { bool shouldRender = false; if (_controllers.ContainsKey(0) && (force || _controllers[0].IsDirty)) { var data = _controllers[0].GetColors(true); Marshal.Copy(data, 0, _ws2811.channel_0.leds, data.Length); shouldRender = true; } if (_controllers.ContainsKey(1) && (force || _controllers[1].IsDirty)) { var data = _controllers[1].GetColors(true); Marshal.Copy(data, 0, _ws2811.channel_1.leds, data.Length); shouldRender = true; } if (shouldRender) { var result = PInvoke.ws2811_render(ref _ws2811); if (result != ws2811_return_t.WS2811_SUCCESS) { throw WS281xException.Create(result, "rendering"); } } }
/// <summary> /// Renders the content of the channels /// </summary> /// <param name="force">Force LEDs to updated - default only updates if when a change is done</param> public async Task RenderAsync(bool force = false) { var shouldRender = false; if (_controllers.ContainsKey(0) && (force || _controllers[0].IsDirty)) { var data = _controllers[0].GetColors(true); var handle = GCHandle.Alloc(data, GCHandleType.Pinned); try { var pointer = handle.AddrOfPinnedObject(); _ws2811.channel_0.leds = pointer; shouldRender = true; } finally { if (handle.IsAllocated) { handle.Free(); } } } if (_controllers.ContainsKey(1) && (force || _controllers[1].IsDirty)) { var data = _controllers[1].GetColors(true); var handle = GCHandle.Alloc(data, GCHandleType.Pinned); try { var pointer = handle.AddrOfPinnedObject(); _ws2811.channel_1.leds = pointer; shouldRender = true; } finally { if (handle.IsAllocated) { handle.Free(); } } } if (shouldRender) { var result = PInvoke.ws2811_render(ref _ws2811); if (result != ws2811_return_t.WS2811_SUCCESS) { throw WS281xException.Create(result, "rendering"); } } await Task.FromResult(true); }
/// <summary> /// Renders the content of the channels /// </summary> public void Render() { if (Settings.Controllers.ContainsKey(0)) { var ledColor = Settings.Controllers[0].GetColors(); Marshal.Copy(ledColor, 0, _ws2811.channel_0.leds, ledColor.Length); } if (Settings.Controllers.ContainsKey(1)) { var ledColor = Settings.Controllers[1].GetColors(); Marshal.Copy(ledColor, 0, _ws2811.channel_1.leds, ledColor.Length); } var result = PInvoke.ws2811_render(ref _ws2811); if (result != ws2811_return_t.WS2811_SUCCESS) { throw WS281xException.Create(result, "rendering"); } }
/// <summary> /// Initialize the wrapper /// </summary> /// <param name="settings">Settings used for initialization</param> public WS281x(Settings settings) { settings.IsInitialized = true; _ws2811 = new ws2811_t { dmanum = settings.DMAChannel, freq = settings.Frequency, channel_0 = InitChannel(0, settings), channel_1 = InitChannel(1, settings) }; //Pin the object in memory. Otherwies GC will probably move the object to another memory location. //This would cause errors because the native library has a pointer on the memory location of the object. _ws2811Handle = GCHandle.Alloc(_ws2811, GCHandleType.Pinned); var initResult = PInvoke.ws2811_init(ref _ws2811); if (initResult != ws2811_return_t.WS2811_SUCCESS) { throw WS281xException.Create(initResult, "initializing"); } this.Settings = settings; if (settings.GammaCorrection != null) { if (settings.Controllers.ContainsKey(0)) { Marshal.Copy(this.Settings.GammaCorrection.ToArray(), 0, _ws2811.channel_0.gamma, this.Settings.GammaCorrection.Count); } if (settings.Controllers.ContainsKey(1)) { Marshal.Copy(this.Settings.GammaCorrection.ToArray(), 0, _ws2811.channel_1.gamma, this.Settings.GammaCorrection.Count); } } //Disposing is only allowed if the init was successfull. //Otherwise the native cleanup function throws an error. _isDisposingAllowed = true; }