Exemplo n.º 1
0
        public void Set(Container self, ref TrackableObjectMixIn <Container> mixIn, T value)
        {
            try
            {
                Tracker.OpenBatch();

                if (accessor.IsVariable())
                {
                    if (trackingData != null && !IsEqualToCached(value, null))
                    {
                        Tracker.logger?.Log(GetName(self), $"new and different value '{value}' set and we're a variable");

                        EnsureKnownAsStale(self);

                        // FIXME: to be optimized
                        accessor.Set(self, value);
                        trackingData.cachedValue = value;
                        EnsureKnownAsStable(self, isModified: true);
                    }
                    else
                    {
                        accessor.Set(self, value);
                    }
                }
                else
                {
                    // We don't care about non-variable settings.
                    accessor.Set(self, value);
                }
            }
            finally
            {
                Tracker.CloseBatch();
            }
        }
Exemplo n.º 2
0
        public T Get(Container self, ref TrackableObjectMixIn <Container> mixIn)
        {
            if (Tracker.AreEvaluating)
            {
                Tracker.NoteEvaluation(GetOurselvesAsDependency(self));

                if (trackingData == null)
                {
                    trackingData = new TrackingData <T>();
                    trackingData.haveModifiedDependencies = true;
                }
            }

            if (trackingData != null)
            {
                if (NeedsUpdate)
                {
                    using (Tracker.Batch())
                        Update(self, ref mixIn, "on value request during tracking evaluation");
                }

                return(GetCachedValue());
            }
            else
            {
                return(accessor.Get(self));
            }
        }
Exemplo n.º 3
0
        public void Update(Container self, ref TrackableObjectMixIn <Container> mixIn, String reason)
        {
            Tracker.EvaluationRecord record;

            var previousValue     = trackingData.cachedValue;
            var previousException = trackingData.cachedException;

            try
            {
                Tracker.OpenEvaluation(GetName(self), reason);

                trackingData.cachedValue = accessor.Get(self);

                trackingData.cachedException = null;

                Tracker.logger?.Log(GetName(self), $"evaluation completed with value '{trackingData.cachedValue}'");
            }
            catch (Exception ex)
            {
                trackingData.cachedException = ex;

                Tracker.logger?.Log(GetName(self), $"evaluation completed with exception '{trackingData.cachedException.Message}'");
            }
            finally
            {
                record = Tracker.CloseEvaluation();
            }

            RectifySubscriptions(self, record.dependencies);

            trackingData.haveModifiedDependencies = false;
        }
Exemplo n.º 4
0
        public void Subscribe(Container self, ref TrackableObjectMixIn <Container> mixIn, Subscriber subscriber)
        {
            if (trackingData == null)
            {
                trackingData = new TrackingData <T>();

                Update(self, ref mixIn, $"on alert due to subscription by {subscriber.ToString()}");
            }

            trackingData.subscribers.Add(subscriber);
        }
Exemplo n.º 5
0
        public void Unsubscribe(Container self, ref TrackableObjectMixIn <Container> mixIn, Subscriber subscriber)
        {
            // FIXME: This has to happen out-of-line, at the end of the omb.

            trackingData.subscribers.Remove(subscriber);

            if (trackingData.subscribers.Count == 0)
            {
                Tracker.logger?.Log(GetName(self), "scheduling for relaxation");

                Tracker.ScheduleForRelaxation(self, accessor.GetIndex());
            }
        }
Exemplo n.º 6
0
        public void Notify(Container self, ref TrackableObjectMixIn <Container> mixIn, TrackingNotification notification)
        {
            if (trackingData == null)
            {
                throw new Exception($"Expected {nameof(trackingData)} to be non-null.");
            }

            switch (notification)
            {
            case TrackingNotification.Stale:
                if (trackingData.staleDependencies++ == 0)
                {
                    EnsureKnownAsStale(self);
                }
                break;

            case TrackingNotification.ReadyUnmodified:
                if (--trackingData.staleDependencies == 0)
                {
                    HandleDependenciesStabilized(self);
                    EnsureKnownAsStable(self, false);
                }
                break;

            case TrackingNotification.ReadyModified:
                trackingData.haveModifiedDependencies = true;
                if (--trackingData.staleDependencies == 0)
                {
                    HandleDependenciesStabilized(self);
                    EnsureKnownAsStable(self, true);
                }
                break;

            case TrackingNotification.RelaxIfAppropriate:
                RelaxIfAppropriate(self);
                break;

            default:
                throw new Exception($"Unknown notification {notification}.");
            }
        }