예제 #1
0
 public ISubscription subscribeWithoutEmit(
     IDisposableTracker tracker, Act <A> onEvent,
     string callerMemberName = "",
     string callerFilePath   = "",
     int callerLineNumber    = 0
     ) =>
 Subscription.empty;
예제 #2
0
 public void subscribe(
     IDisposableTracker tracker, Act <A> onEvent, out ISubscription subscription,
     string callerMemberName = "", string callerFilePath = "", int callerLineNumber = 0
     )
 {
     subscription = Subscription.empty;
     onEvent(value);
 }
예제 #3
0
        public static IObservable <Unit> registerDebugSequence(
            IDisposableTracker tracker,
            DebugSequenceMouseData mouseData = null,
            Option <DebugSequenceDirectionData> directionDataOpt = default,
            DebugConsoleBinding binding = null,
            [CallerMemberName] string callerMemberName = "",
            [CallerFilePath] string callerFilePath     = "",
            [CallerLineNumber] int callerLineNumber    = 0
            )
        {
            Option.ensureValue(ref directionDataOpt);

            binding   = binding ? binding : Resources.Load <DebugConsoleBinding>("Debug Console Prefab");
            mouseData = mouseData ?? DEFAULT_MOUSE_DATA;

            var mouseObs =
                new RegionClickObservable(mouseData.width, mouseData.height)
                .sequenceWithinTimeframe(
                    tracker, mouseData.sequence, 3,
                    // ReSharper disable ExplicitCallerInfoArgument
                    callerMemberName: callerMemberName,
                    callerFilePath: callerFilePath,
                    callerLineNumber: callerLineNumber
                    // ReSharper restore ExplicitCallerInfoArgument
                    );

            var directionObs = directionDataOpt.fold(
                Observable <Unit> .empty,
                directionData => {
                var directions = Observable.everyFrame.collect(_ => {
                    var horizontal = Input.GetAxisRaw(directionData.horizonalAxisName);
                    var vertical   = Input.GetAxisRaw(directionData.verticalAxisName);
                    // Both are equal, can't decide.
                    if (Math.Abs(horizontal - vertical) < 0.001f)
                    {
                        return(Option <Direction> .None);
                    }
                    return
                    (Math.Abs(horizontal) > Math.Abs(vertical)
              ? F.some(horizontal > 0 ? Direction.Right : Direction.Left)
              : F.some(vertical > 0 ? Direction.Up : Direction.Down));
                }).changedValues();

                return
                (directions
                 .withinTimeframe(directionData.sequence.Count, directionData.timeframe)
                 .filter(l => l.Select(t => t._1).SequenceEqual(directionData.sequence))
                 .discardValue());
            }
                );

            var editorShortcut = instance.editorShortcutObs.filter(_ => instance.current.isNone);
            var obs            = mouseObs.join(directionObs).join(editorShortcut);

            obs.subscribe(tracker, _ => instance.show(binding));
            return(obs);
        }
예제 #4
0
        public static Tpl <Ref <Option <A> >, ISubscription> pipeToRef <A>(
            this IObservable <A> obs, IDisposableTracker tracker
            )
        {
            var reference = Ref.a(Option <A> .None);
            var sub       = obs.subscribe(tracker, a => reference.value = a.some());

            return(F.t(reference, sub));
        }
예제 #5
0
        public static Tpl <Ref <uint>, ISubscription> countEvents <A>(
            this IObservable <A> obs, IDisposableTracker tracker
            )
        {
            var r   = Ref.a(0u);
            var sub = obs.subscribe(tracker, _ => r.value++);

            return(F.t(r, sub));
        }
예제 #6
0
        public static Tpl <List <A>, ISubscription> pipeToList <A>(
            this IObservable <A> obs, IDisposableTracker tracker
            )
        {
            var list = new List <A>();
            var sub  = obs.subscribe(tracker, list.Add);

            return(F.t(list, sub));
        }
예제 #7
0
 public ISubscription subscribe(
     IDisposableTracker tracker, Act <A> onEvent,
     string callerMemberName = "",
     string callerFilePath   = "",
     int callerLineNumber    = 0
     )
 {
     onEvent(value);
     return(Subscription.empty);
 }
예제 #8
0
        /// <summary>
        /// Emits event when a particular region index sequence is executed within X seconds.
        /// </summary>
        public IObservable <Unit> sequenceWithinTimeframe(
            IDisposableTracker tracker, IList <int> sequence, float timeS,
            [CallerMemberName] string callerMemberName = "",
            [CallerFilePath] string callerFilePath     = "",
            [CallerLineNumber] int callerLineNumber    = 0
            )
        {
            // Specific implementation to reduce garbage.
            var s       = new Subject <Unit>();
            var regions = new Queue <SeqEntry>(sequence.Count);

            bool isEqual()
            {
                var idx = 0;

                foreach (var entry in regions)
                {
                    if (sequence[idx] != entry.region)
                    {
                        return(false);
                    }
                    idx += 1;
                }
                return(true);
            }

            regionIndex.subscribe(
                tracker,
                // ReSharper disable ExplicitCallerInfoArgument
                callerMemberName: callerMemberName,
                callerFilePath: callerFilePath,
                callerLineNumber: callerLineNumber,
                // ReSharper restore ExplicitCallerInfoArgument
                onEvent: region => {
                // Clear up one item if the queue is full.
                if (regions.Count == sequence.Count)
                {
                    regions.Dequeue();
                }
                regions.Enqueue(new SeqEntry(Time.realtimeSinceStartup, region));
                // Emit event if the conditions check out
                if (
                    regions.Count == sequence.Count &&
                    Time.realtimeSinceStartup - regions.Peek().time <= timeS &&
                    isEqual()
                    )
                {
                    s.push(F.unit);
                }
            }
                );
            return(s);
        }
예제 #9
0
 public override void subscribe(
     IDisposableTracker tracker, Act <A> onEvent, out ISubscription subscription,
     [CallerMemberName] string callerMemberName = "",
     [CallerFilePath] string callerFilePath     = "",
     [CallerLineNumber] int callerLineNumber    = 0
     )
 {
     // ReSharper disable ExplicitCallerInfoArgument
     base.subscribe(tracker, onEvent, out subscription, callerMemberName, callerFilePath, callerLineNumber);
     // ReSharper restore ExplicitCallerInfoArgument
     foreach (var evt in events)
     {
         onEvent(evt);
     }
 }
예제 #10
0
        public void track(
            IDisposableTracker tracker, Act <A> runOnEnabled = null, Act <A> runOnDisabled = null
            )
        {
            if (runOnEnabled != null)
            {
                // Subscribe to onEnabled before running the code on already active objects, because
                // that code can then enable additional instances.
                _onEnabled.subscribe(tracker, runOnEnabled);
                forEach(runOnEnabled);
            }

            if (runOnDisabled != null)
            {
                _onDisabled.subscribe(tracker, runOnDisabled);
            }
        }
예제 #11
0
 [PublicAPI] public static ISubscription subscribe <A>(
     this IObservable <A> observable,
     IDisposableTracker tracker,
     Act <A> onEvent,
     [CallerMemberName] string callerMemberName = "",
     [CallerFilePath] string callerFilePath     = "",
     [CallerLineNumber] int callerLineNumber    = 0
     )
 {
     // ReSharper disable once AccessToModifiedClosure
     observable.subscribe(
         tracker: tracker, onEvent: onEvent, subscription: out var subscription,
         // ReSharper disable ExplicitCallerInfoArgument
         callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber
         // ReSharper restore ExplicitCallerInfoArgument
         );
     return(subscription);
 }
예제 #12
0
 public static ISubscription subscribeForOneEvent <A>(
     this IObservable <A> observable,
     IDisposableTracker tracker,
     Act <A> onEvent,
     [CallerMemberName] string callerMemberName = "",
     [CallerFilePath] string callerFilePath     = "",
     [CallerLineNumber] int callerLineNumber    = 0
     ) => observable.subscribe(
     tracker: tracker,
     onChange: (a, sub) => {
     sub.unsubscribe();
     onEvent(a);
 },
     // ReSharper disable ExplicitCallerInfoArgument
     callerMemberName: callerMemberName, callerFilePath: callerFilePath,
     callerLineNumber: callerLineNumber
     // ReSharper restore ExplicitCallerInfoArgument
     );
예제 #13
0
        /// <summary>
        /// Emits event when a particular region index sequence is executed within X seconds.
        /// </summary>
        public IObservable <Unit> sequenceWithinTimeframe(
            IDisposableTracker tracker, IList <int> sequence, float timeS
            )
        {
            // Specific implementation to reduce garbage.
            var s       = new Subject <Unit>();
            var regions = new Queue <SeqEntry>(sequence.Count);

            bool isEqual()
            {
                var idx = 0;

                foreach (var entry in regions)
                {
                    if (sequence[idx] != entry.region)
                    {
                        return(false);
                    }
                    idx += 1;
                }
                return(true);
            }

            regionIndex.subscribe(tracker, region => {
                // Clear up one item if the queue is full.
                if (regions.Count == sequence.Count)
                {
                    regions.Dequeue();
                }
                regions.Enqueue(new SeqEntry(Time.realtimeSinceStartup, region));
                // Emit event if the conditions check out
                if (
                    regions.Count == sequence.Count &&
                    Time.realtimeSinceStartup - regions.Peek().time <= timeS &&
                    isEqual()
                    )
                {
                    s.push(F.unit);
                }
            });
            return(s);
        }
예제 #14
0
파일: Unity.cs 프로젝트: yika-aixi/tlplib
        public static ISubscription bind <A>(
            this IObservable <A> observable, IDisposableTracker tracker, Fn <A, Coroutine> f
            )
        {
            var lastCoroutine = F.none <Coroutine>();

            void stopOpt()
            {
                foreach (var c in lastCoroutine)
                {
                    c.stop();
                }
            };
            var sub = observable.subscribe(
                NoOpDisposableTracker.instance,
                a => {
                stopOpt();
                lastCoroutine = f(a).some();
            }
                ).andThen(stopOpt);

            tracker.track(sub);
            return(sub);
        }
예제 #15
0
 /// <summary>
 /// Report warnings and errors from default logger and unity log messages.
 /// </summary>
 public static ISubscription registerDefault(
     this OnError onError, IDisposableTracker tracker, Log.Level logFrom
     ) =>
 defaultStream.strict
 .filter(e => e.level >= logFrom)
 .subscribe(tracker, e => onError(e));
예제 #16
0
 public static void onCompleteCancellable <A>(this Future <A> future, IDisposableTracker tracker, Act <A> action) =>
 tracker.track(onCompleteCancellable(future, action));