Exemplo n.º 1
0
        private ScriptRunner()
        {
            _scheduleTrigger    = new ScheduleTrigger(); //this needs to be above
            _enabled            = false;
            _maxAge             = null;
            _triggerHandlers    = new Dictionary <Trigger, EventHandler <Tuple <Datum, Datum> > >();
            _scriptRunCallbacks = new List <ScheduledCallback>();
            Script          = new Script(this);
            Triggers        = new ConcurrentObservableCollection <Trigger>(new LockConcurrent());
            RunTimes        = new List <DateTime>();
            CompletionTimes = new List <DateTime>();
            AllowCancel     = true;
            OneShot         = false;
            RunOnStart      = false;
            DisplayProgress = true;
            RunMode         = RunMode.SingleKeepNewest;
            IncompleteSubmissionConfirmation = "You have not completed all required fields. Do you want to continue?";
            ShuffleInputGroups = false;

            Triggers.CollectionChanged += (o, e) =>
            {
                if (e.Action == NotifyCollectionChangedAction.Add)
                {
                    foreach (Trigger trigger in e.NewItems)
                    {
                        // ignore duplicate triggers -- the user should delete and re-add them instead.
                        if (_triggerHandlers.ContainsKey(trigger))
                        {
                            return;
                        }

                        // create a handler to be called each time the triggering probe stores a datum
                        EventHandler <Tuple <Datum, Datum> > handler = async(oo, previousCurrentDatum) =>
                        {
                            // must be running and must have a current datum
                            lock (_locker)
                            {
                                if (!Probe.Running || !_enabled || previousCurrentDatum.Item2 == null)
                                {
                                    trigger.FireValueConditionMetOnPreviousCall = false;  // this covers the case when the current datum is null. for some probes, the null datum is meaningful and is emitted in order for their state to be tracked appropriately (e.g., POI probe).
                                    return;
                                }
                            }

                            Datum previousDatum = previousCurrentDatum.Item1;
                            Datum currentDatum  = previousCurrentDatum.Item2;

                            // get the value that might trigger the script -- it might be null in the case where the property is nullable and is not set (e.g., facebook fields, input locations, etc.)
                            object currentDatumValue = trigger.DatumProperty.GetValue(currentDatum);
                            if (currentDatumValue == null)
                            {
                                return;
                            }

                            // if we're triggering based on datum value changes/differences instead of absolute values, calculate the change now.
                            if (trigger.Change)
                            {
                                // don't need to set ConditionSatisfiedLastTime = false here, since it cannot be the case that it's true and prevDatum == null (we must have had a currDatum last time in order to set ConditionSatisfiedLastTime = true).
                                if (previousDatum == null)
                                {
                                    return;
                                }

                                try
                                {
                                    currentDatumValue = Convert.ToDouble(currentDatumValue) - Convert.ToDouble(trigger.DatumProperty.GetValue(previousDatum));
                                }
                                catch (Exception ex)
                                {
                                    SensusServiceHelper.Get().Logger.Log("Trigger error:  Failed to convert datum values to doubles for change calculation:  " + ex.Message, LoggingLevel.Normal, GetType());
                                    return;
                                }
                            }

                            // run the script if the current datum's value satisfies the trigger
                            if (trigger.FireFor(currentDatumValue))
                            {
                                await RunAsync(previousDatum, currentDatum);
                            }
                        };

                        trigger.Probe.MostRecentDatumChanged += handler;

                        _triggerHandlers.Add(trigger, handler);
                    }
                }
                else if (e.Action == NotifyCollectionChangedAction.Remove)
                {
                    foreach (Trigger trigger in e.OldItems)
                    {
                        if (_triggerHandlers.ContainsKey(trigger))
                        {
                            trigger.Probe.MostRecentDatumChanged -= _triggerHandlers[trigger];

                            _triggerHandlers.Remove(trigger);
                        }
                    }
                }
            };
        }