protected override IDisposable StartListenAndRefill() { return(cell.Bind(coll => { if (coll == null) { buffer.Reset(); return; } // TODO make smarter algorithm later buffer.Reset(coll); // This algorithm does not work on simple types and same items in collection // var newItems = coll as T[] ?? coll.ToArray(); // for (var index = 0; index < newItems.Length; index++) // { // var item = newItems[index]; // if (buffer.Contains(item)) continue; // buffer.Add(item); // } // // for (var index = buffer.Count - 1; index >= 0; index--) // { // var oldItem = buffer[index]; // if (newItems.Contains(oldItem)) continue; // buffer.RemoveAt(index); // } })); }
public static IDisposable ListenWhile <T>(this IEventReader <T> reader, ICell <bool> listenCondition, Action <T> act) { var disp = new DoubleDisposable(); disp.first = listenCondition.Bind(val => { if (val) { if (disp.disposed) { return; } if (disp.second != null) { throw new ZergRushException(); } disp.second = reader.Subscribe(act); } else if (disp.second != null) { disp.second.Dispose(); disp.second = null; } }); return(disp); }
public IDisposable ListenUpdates(Action <T2> reaction) { var group = new CellJoinDisposable <T2>(); group.lastValue = value; Action <T> func = iVal => { if (group.disposed) { return; } var innerCell = map(iVal); if (@group.Second != null) { var innerVal = innerCell.value; if (!EqualityComparer <T2> .Default.Equals(group.lastValue, innerVal)) { reaction(innerVal); group.lastValue = innerVal; } @group.Second.Dispose(); } @group.Second = innerCell.ListenUpdates(val => { reaction(val); group.lastValue = val; }); }; @group.First = cell.Bind(func); return(group); }
public static IEventStream Join(this ICell <IEventStream> cell) { return(new AnonymousEventStream(reaction => { var group = new DoubleDisposable(); Action <IEventStream> func = (IEventStream innerStream) => { if (group.disposed) { return; } if (@group.Second != null) { @group.Second.Dispose(); } if (innerStream != null) { @group.Second = innerStream.Subscribe(reaction); } }; @group.First = cell.Bind(func); return group; })); }
public DebugLayout Label(ICell <string> textCell, DebugLayoutOptions opts) { var t = InstantiateInLayout(factory.labelPrefab, opts).GetComponentInChildren <Text>(); connections += textCell.Bind(text => t.text = text); return(this); }
public static void TestCalculation() { Cell <int> count = new Cell <int>(50); List <Cell <float> > cells = new List <Cell <float> >(); for (int i = 0; i < 50; ++i) { cells.Add(new Cell <float>(i)); } ICell <string> result = Transaction.Calculate(() => { string message = "count: " + count.ToString() + "list: "; foreach (var item in cells) { message += item.value.ToString() + " "; } return(message); }); result.Bind(message => Debug.Log(message)); for (int i = 0; i < count.value; ++i) { cells[UnityEngine.Random.Range(0, count.value)].value = 0; } count.value = 20; Debug.Log("test 2 finished"); }
public void Show(string name, ICell <bool> selected = null, Action <IDisposable> connectionSink = null) { text.text = name; if (selected == null) { selected = StaticCell <bool> .Default(); } if (connectionSink == null) { connectionSink = _ => { } } ; connectionSink(selected.Bind(sel => text.color = sel ? selectedTextColor : normalTextColor)); connectionSink(selected.Bind(sel => bg.color = sel ? selectedColor : normalColor)); } }
public void SetInputCell(ICell <T> cell) { if (inputStreamConnection != null) { inputStreamConnection.Dispose(); } inputStreamConnection = cell.Bind(Set); }
public static IDisposable SetFill(this Image obj, ICell <double> fill) { if (!Check(obj)) { return(new EmptyDisposable()); } return(fill.Bind(val => obj.fillAmount = (float)val)); }
public static IDisposable SetContent <T>(this Text text, string format, ICell <T> cell, params Func <T, object>[] parameters) { if (!Check(text)) { return(new EmptyDisposable()); } return(cell.Bind(obj => text.text = string.Format(format, parameters.Select(func => func(obj))))); }
public static IDisposable SetContent <T>(this Text text, ICell <T> cell) { if (!Check(text)) { return(new EmptyDisposable()); } return(cell.Bind(obj => text.text = obj.ToString())); }
public static IDisposable SetContent <T>(this Text text, string format, ICell <T> cell) { if (!Check(text)) { return(new EmptyDisposable()); } return(cell.Bind(obj => text.text = string.Format(format, obj))); }
public static IDisposable SetSprite(this Image obj, ICell <Sprite> sprite) { if (!Check(obj)) { return(new EmptyDisposable()); } return(sprite.Bind(val => obj.sprite = val)); }
public static IDisposable SetActive(this GameObject obj, ICell <bool> active) { if (!Check(obj)) { return(new EmptyDisposable()); } return(active.Bind(obj.SetActiveSafe)); }
public static IDisposable SetInteractable(this Button button, ICell <bool> enabled) { if (!Check(button)) { return(new EmptyDisposable()); } return(enabled.Bind(val => button.interactable = val)); }
public static IDisposable SetOpacity(this Image image, ICell <float> val) { return(val.Bind(v => { var c = image.color; c.a = v; image.color = c; })); }
public DebugLayout Label(ICell <string> name, int fontSize = 40) { var t = InstantiateInLayout(factory.titlePrefab, DebugLayoutOptions.Fixed(fontSize + 6)).GetComponentInChildren <Text>(); t.resizeTextForBestFit = true; t.resizeTextMaxSize = (int)fontSize; connections += name.Bind(n => t.text = n); return(this); }
public DebugLayout DisableIf(ICell <bool> val) { var group = gameObject.GetOrAddComponent <CanvasGroup>(); connections += val.Bind(disabled => { group.alpha = disabled ? 0.5f : 1f; group.interactable = !disabled; }); return(this); }
// Value is difference bhetween current and next value. public static IDisposable BindDiff(this ICell <float> cell, Action <float> action) { // Implicit lambda boxing used as a prev val storage here float prevVal = cell.value; return(cell.Bind(v => { action(v - prevVal); prevVal = v; })); }
// With this function you receive previous cell value as second argument, first time its the same value. public static IDisposable BufferBind <T>(this ICell <T> cell, Action <T, T> action) { // Implicit lambda boxing used as a prev val storage here T prevVal = cell.value; return(cell.Bind(v => { action(v, prevVal); prevVal = v; })); }
public static IDisposable SetVisible(this CanvasGroup image, ICell <bool> val, float fadeDuration = 0, float targetOpacity = 1.0f) { if (fadeDuration != 0) { image.SetActiveSafe(val.value); return(val.ListenUpdates(v => { image.SetVisibility(v, fadeDuration, targetOpacity); })); } else { return(val.Bind(image.SetActiveSafe)); } }
public static IDisposable SetVisible(this Image image, ICell <bool> val, float fadeDuration = 0) { if (fadeDuration != 0) { image.SetVisible(val.value); return(val.ListenUpdates(v => { image.SetVisibility(v, fadeDuration, image.color.a); })); } else { return(val.Bind(image.SetVisible)); } }
public static IEventReader <float> TimeAccumulator(this ICell <float> val, float interval, Action <IDisposable> connectionSink) { var accum = 0f; connectionSink(val.Bind(v => accum += v)); return(UnityExecutor.instance.TickStream(interval).Map(() => { var currAcc = accum; accum = 0; return currAcc; })); }
// First argument will be previous value public static IDisposable BindHistoric <T>(this ICell <T> cell, Action <T, T> reaction, Priority p = Priority.Normal) { var disp = new Carrier <T> { val = cell.value }; return(cell.Bind(val => { reaction(disp.val, val); disp.val = val; }, p)); }
public static IStream <T> EachNotNull <T>(this ICell <T> cell) where T : class { return(new AnonymousStream <T>((act, p) => { return cell.Bind(val => { if (val != null) { act(val); } }, p); })); }
public static IEventStream <float> TimeAccumulator(this ICell <float> val, float interval, IConnectionSink connectionSink) { var accum = 0f; connectionSink.AddConnection(val.Bind(v => accum += v)); return(UnityExecutor.Instance.TickStream(interval).Map(() => { var currAcc = accum; accum = 0; return currAcc; })); }
// Value is difference bhetween current and next value. public static ICell <float> Diff(this ICell <float> cell) { // Implicit lambda boxing used as a prev val storage here float prevVal = cell.value; return(new AnonymousCell <float>(action => { return cell.Bind(v => { action(v - prevVal); prevVal = v; }); }, () => cell.value - prevVal)); }
public static IOnceStream <T> When <T>(this ICell <T> cell, Func <T, bool> filter) { return(new AnonymousStream <T>((Action <T> reaction, Priority p) => { return cell.Bind(val => { if (!filter(val)) { return; } reaction(val); }, p); })); }
public static IDisposable WhateverBind <T>(this ICell <T> cell, Action <T, ConnectionCollector> action, Priority p = Priority.Normal) { var collector = new ConnectionCollector(); var disps = new ListDisposable { collector, cell.Bind(val => { collector.DisconnectAll(); action(val, collector); }, p) }; return(disps); }
public static IDisposable RunCoroutineWhile(this MonoBehaviour self, Func <IEnumerator> coro, ICell <bool> condition) { Coroutine currentCoro = null; return(condition.Bind(val => { if (val) { currentCoro = self.StartCoroutine(coro()); } else if (currentCoro != null) { self.StopCoroutine(currentCoro); currentCoro = null; } })); }