using SimpleCore.Library; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace StandardScene { public class LadderLogic { /// below defines some useful functions... private static ConcurrentDictionary pressedDT = new ConcurrentDictionary(); // if active for millis, trigger once. public static void TriggerOnce(bool active, int millis, Action trigger,int index=0, [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { var id = $"{sourceFilePath}:{sourceLineNumber+ index}"; if (!active) { if (pressedDT.TryGetValue(id, out var pair1) && pair1.state != 1) pressedDT.TryRemove(id, out _); return; } if (pressedDT.TryGetValue(id, out var pair)) { if (pair.state != 0) return; if ((DateTime.Now - pair.dt).TotalMilliseconds > millis) { pressedDT[id] = (pair.dt, 1); Task.Run(() => { try { trigger(); } catch (Exception ex) { Diagnosis.Post($"Ex={ExceptionFormatter.FormatEx(ex)}", $"timed_trigger-{id}"); pressedDT.TryRemove(id, out _); } pressedDT[id] = (pair.dt, 2); }); } } else pressedDT[id] = (DateTime.Now, 0); } private static ConcurrentDictionary isochronous = new ConcurrentDictionary(); public static object lockobj = new object(); public static void IsochronousFork(Action action, [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { var id = $"{sourceFilePath}:{sourceLineNumber}"; lock (lockobj) { if (isochronous.TryGetValue(id, out var calling) && calling) return; isochronous[id] = true; } Task.Run(() => { try { action(); } catch (Exception ex) { Diagnosis.Post($"Ex={ExceptionFormatter.FormatEx(ex)}", $"isochrounous_fork-{id}"); } isochronous[id] = false; }); } private static Dictionary keepTrack = new Dictionary(); /// /// including first call. /// /// /// /// action(T1 old) public static void TriggerIfChanged(Func getter, Action action) { var id = getter.Method; var val = getter.Invoke(); if (keepTrack.TryGetValue(id, out var t) && t is T1 old) { if (val.Equals(old)) return; action(old); } else action(default); keepTrack[id] = val; } public static void FlipFlop(ref T1 target, int millis, params T1[] vs) { target = vs[(((long)DateTime.Now.TimeOfDay.TotalMilliseconds) / millis) % vs.Length]; } } }