internal static Stream <T> FilterMaybeImpl <T, TMaybe>(this Stream <TMaybe> s, Action <TMaybe, Action <T> > matchSome) { Stream <T> @out = new Stream <T>(s.KeepListenersAlive); IListener l = s.Listen( @out.Node, (trans2, a) => matchSome(a, v => @out.Send(trans2, v))); return(@out.UnsafeAttachListener(l)); }
internal static Stream <T> SplitImpl <T, TCollection>(Stream <TCollection> s) where TCollection : IEnumerable <T> { Stream <T> @out = new Stream <T>(s.KeepListenersAlive); IListener l1 = s.Listen( new Node <T>(), (trans, aa) => { int childIx = 0; foreach (T a in aa) { trans.Split(childIx, trans1 => @out.Send(trans1, a)); childIx++; } }); return(@out.UnsafeAttachListener(l1)); }
private static TResult ListenOnceAsyncInternal <T, TResult>( this Stream <T> s, Func <Task <T>, IStrongListener, TResult> generateResult, CancellationToken token) { TaskCompletionSource <T> tcs = new TaskCompletionSource <T>(); IStrongListener listener = null; bool unlistenEarly = false; listener = s.Listen( a => { // ReSharper disable once AccessToModifiedClosure if (listener == null) { unlistenEarly = true; } else { // ReSharper disable once AccessToModifiedClosure listener.Unlisten(); listener = null; } tcs.TrySetResult(a); }); if (unlistenEarly) { listener.Unlisten(); listener = null; } token.Register( () => { listener?.Unlisten(); tcs.TrySetCanceled(); }); return(generateResult(tcs.Task, listener)); }
internal void Loop(TransactionInternal trans, Stream <T> stream) { lock (this.isAssignedLock) { if (this.isAssigned) { throw new InvalidOperationException("Loop was looped more than once."); } this.isAssigned = true; } this.AttachListenerImpl(stream.Listen(this.Node, this.Send)); lock (stream.KeepListenersAlive) { stream.KeepListenersAlive.Use(this.KeepListenersAlive); } }
private Stream <T> Merge(TransactionInternal trans, Stream <T> s) { Stream <T> @out = new Stream <T>(this.KeepListenersAlive); Node <T> left = new Node <T>(); Node <T> right = @out.Node; (bool changed, Node <T> .Target nodeTarget) = left.Link(trans, (t, v) => { }, right); if (changed) { trans.SetNeedsRegenerating(); } Action <TransactionInternal, T> h = @out.Send; IListener l1 = this.Listen(left, h); IListener l2 = s.Listen(right, h); return(@out.UnsafeAttachListener(l1) .UnsafeAttachListener(l2) .UnsafeAttachListener(ListenerInternal.CreateFromNodeAndTarget(left, nodeTarget))); }
public static Stream <Maybe <string> > Lookup(Stream <string> sWord) { StreamSink <Maybe <string> > sDefinition = Stream.CreateSink <Maybe <string> >(); IListener listener = sWord.Listen(wrd => { Task.Run(() => { //System.out.println("look up " + wrd); Maybe <string> def = Maybe.None; try { Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s.Connect("dict.org", 2628); NetworkStream ns = new NetworkStream(s); StreamReader r = new StreamReader(ns); StreamWriter w = new StreamWriter(ns); try { r.ReadLine(); w.WriteLine("DEFINE ! " + wrd); w.Flush(); string result = r.ReadLine(); if (result != null && result.StartsWith("150")) { result = r.ReadLine(); } if (result != null && result.StartsWith("151")) { StringBuilder b = new StringBuilder(); while (true) { string l = r.ReadLine(); if (l == ".") { break; } b.AppendLine(l); } def = Maybe.Some(b.ToString()); } else { MessageBox.Show("ERROR: " + result); } } finally { try { s.Close(); s.Dispose(); } catch { // ignored } } } catch (Exception e) { MessageBox.Show("ERROR: " + e); } finally { sDefinition.Send(def); } }); }); return(sDefinition.AttachListener(listener)); }
public Implementation(PetrolPumpWindow petrolPump) { SComboBox <IPump> logic = new SComboBox <IPump>( new IPump[] { new LifeCyclePump(), new AccumulatePulsesPump(), new ShowDollarsPump(), new ClearSalePump(), new KeypadPump(), new PresetAmountPump() }, p => p.GetType().FullName); petrolPump.LogicComboBoxPlaceholder.Children.Add(logic); STextField textPrice1 = new STextField("2.149") { Width = 100 }; petrolPump.Price1Placeholder.Children.Add(textPrice1); STextField textPrice2 = new STextField("2.341") { Width = 100 }; petrolPump.Price2Placeholder.Children.Add(textPrice2); STextField textPrice3 = new STextField("1.499") { Width = 100 }; petrolPump.Price3Placeholder.Children.Add(textPrice3); double ParseDoubleSafe(string s) { double n; if (double.TryParse(s, out n)) { return(n); } return(0.0); } StreamSink <Key> sKey = Stream.CreateSink <Key>(); Dictionary <Key, FrameworkElement> containersByKey = new Dictionary <Key, FrameworkElement> { { Key.One, petrolPump.Keypad1Button }, { Key.Two, petrolPump.Keypad2Button }, { Key.Three, petrolPump.Keypad3Button }, { Key.Four, petrolPump.Keypad4Button }, { Key.Five, petrolPump.Keypad5Button }, { Key.Six, petrolPump.Keypad6Button }, { Key.Seven, petrolPump.Keypad7Button }, { Key.Eight, petrolPump.Keypad8Button }, { Key.Nine, petrolPump.Keypad9Button }, { Key.Zero, petrolPump.Keypad0Button }, { Key.Clear, petrolPump.KeypadClearButton } }; foreach (KeyValuePair <Key, FrameworkElement> containerAndKey in containersByKey) { containerAndKey.Value.MouseDown += async(sender, args) => { if (args.LeftButton == MouseButtonState.Pressed) { await Task.Run(() => sKey.Send(containerAndKey.Key)); } }; } CellLoop <UpDown> nozzle1 = new CellLoop <UpDown>(); CellLoop <UpDown> nozzle2 = new CellLoop <UpDown>(); CellLoop <UpDown> nozzle3 = new CellLoop <UpDown>(); Cell <double> calibration = Cell.Constant(0.001); Cell <double> price2 = textPrice2.Text.Map(ParseDoubleSafe); Cell <double> price3 = textPrice3.Text.Map(ParseDoubleSafe); Cell <double> price1 = textPrice1.Text.Map(ParseDoubleSafe); CellSink <Stream <Unit> > csClearSale = Cell.CreateSink(Stream.Never <Unit>()); Stream <Unit> sClearSale = csClearSale.SwitchS(); StreamSink <int> sFuelPulses = Stream.CreateSink <int>(); Cell <Outputs> outputs = logic.SelectedItem.Map( pump => pump.Create(new Inputs( nozzle1.Updates(), nozzle2.Updates(), nozzle3.Updates(), sKey, sFuelPulses, calibration, price1, price2, price3, sClearSale))); Cell <Delivery> delivery = outputs.Map(o => o.Delivery).SwitchC(); Cell <string> presetLcd = outputs.Map(o => o.PresetLcd).SwitchC(); Cell <string> saleCostLcd = outputs.Map(o => o.SaleCostLcd).SwitchC(); Cell <string> saleQuantityLcd = outputs.Map(o => o.SaleQuantityLcd).SwitchC(); Cell <string> priceLcd1 = outputs.Map(o => o.PriceLcd1).SwitchC(); Cell <string> priceLcd2 = outputs.Map(o => o.PriceLcd2).SwitchC(); Cell <string> priceLcd3 = outputs.Map(o => o.PriceLcd3).SwitchC(); Stream <Unit> sBeep = outputs.Map(o => o.SBeep).SwitchS(); Stream <Sale> sSaleComplete = outputs.Map(o => o.SSaleComplete).SwitchS(); SoundPlayer beepPlayer = new SoundPlayer(GetResourceStream(@"sounds\beep.wav")); this.listeners.Add(sBeep.Listen(_ => new Thread(() => beepPlayer.PlaySync()) { IsBackground = true }.Start())); SoundPlayer fastRumblePlayer = new SoundPlayer(GetResourceStream(@"sounds\fast.wav")); Action stopFast = () => { }; void PlayFast() { ManualResetEvent mre = new ManualResetEvent(false); new Thread(() => { fastRumblePlayer.PlayLooping(); mre.WaitOne(); fastRumblePlayer.Stop(); }) { IsBackground = true }.Start(); stopFast = () => { mre.Set(); stopFast = () => { }; }; } SoundPlayer slowRumblePlayer = new SoundPlayer(GetResourceStream(@"sounds\slow.wav")); Action stopSlow = () => { }; void PlaySlow() { ManualResetEvent mre = new ManualResetEvent(false); new Thread(() => { slowRumblePlayer.PlayLooping(); mre.WaitOne(); slowRumblePlayer.Stop(); }) { IsBackground = true }.Start(); stopSlow = () => { mre.Set(); stopSlow = () => { }; }; } this.listeners.Add(delivery.Changes().Listen(d => { petrolPump.Dispatcher.InvokeAsync(() => { if (d == Delivery.Fast1 || d == Delivery.Fast2 || d == Delivery.Fast3) { PlayFast(); } else { stopFast(); } if (d == Delivery.Slow1 || d == Delivery.Slow2 || d == Delivery.Slow3) { PlaySlow(); } else { stopSlow(); } }); })); StackPanel presetLcdStackPanel = new StackPanel { Orientation = Orientation.Horizontal }; petrolPump.PresetPlaceholder.Children.Add(presetLcdStackPanel); this.listeners.Add(presetLcd.Listen(t => petrolPump.Dispatcher.InvokeAsync(() => petrolPump.SetLcdDigits(presetLcdStackPanel, t, 5, true)))); StackPanel saleCostStackPanel = new StackPanel { Orientation = Orientation.Horizontal }; petrolPump.DollarsPlaceholder.Children.Add(saleCostStackPanel); this.listeners.Add(saleCostLcd.Listen(t => petrolPump.Dispatcher.InvokeAsync(() => petrolPump.SetLcdDigits(saleCostStackPanel, t, 5, true)))); StackPanel saleQuantityLcdStackPanel = new StackPanel { Orientation = Orientation.Horizontal }; petrolPump.LitersPlaceholder.Children.Add(saleQuantityLcdStackPanel); this.listeners.Add(saleQuantityLcd.Listen(t => petrolPump.Dispatcher.InvokeAsync(() => petrolPump.SetLcdDigits(saleQuantityLcdStackPanel, t, 5, true)))); StackPanel priceLcd1StackPanel = new StackPanel { Orientation = Orientation.Horizontal }; petrolPump.Fuel1Placeholder.Children.Add(priceLcd1StackPanel); this.listeners.Add(priceLcd1.Listen(t => petrolPump.Dispatcher.InvokeAsync(() => petrolPump.SetLcdDigits(priceLcd1StackPanel, t, 5, false)))); StackPanel priceLcd2StackPanel = new StackPanel { Orientation = Orientation.Horizontal }; petrolPump.Fuel2Placeholder.Children.Add(priceLcd2StackPanel); this.listeners.Add(priceLcd2.Listen(t => petrolPump.Dispatcher.InvokeAsync(() => petrolPump.SetLcdDigits(priceLcd2StackPanel, t, 5, false)))); StackPanel priceLcd3StackPanel = new StackPanel { Orientation = Orientation.Horizontal }; petrolPump.Fuel3Placeholder.Children.Add(priceLcd3StackPanel); this.listeners.Add(priceLcd3.Listen(t => petrolPump.Dispatcher.InvokeAsync(() => petrolPump.SetLcdDigits(priceLcd3StackPanel, t, 5, false)))); Dictionary <CellLoop <UpDown>, Image> nozzles = new Dictionary <CellLoop <UpDown>, Image> { { nozzle1, petrolPump.Nozzle1Image }, { nozzle2, petrolPump.Nozzle2Image }, { nozzle3, petrolPump.Nozzle3Image } }; this.listeners.AddRange(nozzles.Select(nozzle => nozzle.Key.Listen(p => petrolPump.Dispatcher.InvokeAsync(() => nozzle.Value.Margin = p == UpDown.Up ? new Thickness(0, 0, 0, 0) : new Thickness(0, 30, 0, 0))))); foreach (KeyValuePair <CellLoop <UpDown>, Image> nozzle in nozzles) { StreamSink <Unit> nozzleClicks = Stream.CreateSink <Unit>(); nozzle.Value.MouseDown += async(sender, args) => { if (args.LeftButton == MouseButtonState.Pressed) { await Task.Run(() => nozzleClicks.Send(Unit.Value)); } }; nozzle.Key.Loop(nozzleClicks .Snapshot(nozzle.Key, (_, n) => n == UpDown.Down ? UpDown.Up : UpDown.Down).Hold(UpDown.Down)); } this.listeners.Add(sSaleComplete.Listen(sale => { petrolPump.Dispatcher.InvokeAsync(() => { SaleCompleteDialog dialog = new SaleCompleteDialog( sale.Fuel.ToString(), Formatters.FormatPrice(sale.Price, null), Formatters.FormatSaleCost(sale.Cost), Formatters.FormatSaleQuantity(sale.Quantity)); dialog.Owner = petrolPump; csClearSale.Send(dialog.SOkClicked); dialog.Show(); IListener l = null; // ReSharper disable once RedundantAssignment l = dialog.SOkClicked.Listen(_ => { petrolPump.Dispatcher.InvokeAsync(() => dialog.Close()); // ReSharper disable once AccessToModifiedClosure l?.Unlisten(); }); }); })); Task.Run(async() => { while (true) { Transaction.RunVoid(() => { switch (delivery.Sample()) { case Delivery.Fast1: case Delivery.Fast2: case Delivery.Fast3: sFuelPulses.Send(40); break; case Delivery.Slow1: case Delivery.Slow2: case Delivery.Slow3: sFuelPulses.Send(2); break; } }); await Task.Delay(200).ConfigureAwait(false); } // ReSharper disable once FunctionNeverReturns }); }