Exemple #1
0
        public static void StartSession(IReadOnlyList <SessionConfig.Experiment> experimentParts, IDictionary <string, DeviceParams> devicePart, bool monitor = false,
                                        ISessionListener sessionListener = null)
        {
            /* Constructs experiment instances. */
            var experiments = new IExperiment[experimentParts.Count];
            var formattedSessionDescriptors = new string[experimentParts.Count];

            for (var i = 0; i < experimentParts.Count; i++)
            {
                var expConf = experimentParts[i];
                if (!App.Instance.Registries.Registry <PluginExperiment>().LookUp(expConf.Params.Id, out var pluginExperiment))
                {
                    throw new ArgumentException($"Cannot find specific experiment by id: {expConf.Params.Id}");
                }
                if (!TryInitiateExperiment(pluginExperiment, pluginExperiment.DeserializeParams(expConf.Params.Params), out var experiment))
                {
                    return;
                }
                experiments[i] = experiment;
                formattedSessionDescriptors[i] = expConf.GetFormattedSessionDescriptor();
            }

            /* Parse consumer configurations. */
            var deviceConsumerLists = new Dictionary <DeviceType, IList <Tuple <PluginStreamConsumer, IReadonlyContext> > >();

            foreach (var deviceType in App.Instance.Registries.Registry <PluginDeviceType>().Registered)
            {
                if (!devicePart.TryGetValue(deviceType.DeviceType.Name, out var deviceParams) || deviceParams.Device.Id == null)
                {
                    continue;
                }
                var list = new List <Tuple <PluginStreamConsumer, IReadonlyContext> >();
                deviceConsumerLists[deviceType.DeviceType] = list;
                foreach (var consumerConf in deviceParams.Consumers)
                {
                    if (!App.Instance.Registries.Registry <PluginStreamConsumer>().LookUp(consumerConf.Id, out var pluginStreamConsumer))
                    {
                        throw new ArgumentException($"Cannot find specific consumer by id: {consumerConf.Params}");
                    }
                    list.Add(new Tuple <PluginStreamConsumer, IReadonlyContext>(pluginStreamConsumer, pluginStreamConsumer.DeserializeParams(consumerConf.Params)));
                }
            }

            /* IMPORTANT: ALL EXPERIMENT RELATED CONFIG SHOULD BE CHECKED BEFORE STEAMERS WERE INITIALIZED */

            var monitorWindow = monitor ? MonitorWindow.Show() : null;

            var sessions  = new Session[experimentParts.Count];
            var baseClock = Clock.SystemMillisClock;
            var streamers = CreateStreamerCollection(devicePart, baseClock, out var deviceStreamers);

            using (var disposablePool = new DisposablePool())
            {
                try
                {
                    streamers.Start();
                    monitorWindow?.Bind(streamers);

                    for (var i = 0; i < experimentParts.Count; i++)
                    {
                        var experimentPart = experimentParts[i];
                        var experiment     = experiments[i];
                        var sessionName    = formattedSessionDescriptors[i];
                        var session        = sessions[i] = new Session(App.Instance.Dispatcher, experimentPart.Subject, sessionName, baseClock, experiment, streamers, App.DataDir);

                        new SessionConfig {
                            ExperimentPart = experimentPart, DevicePart = devicePart
                        }
                        .JsonSerializeToFile(session.GetDataFileName(SessionConfig.FileSuffix), JsonUtils.PrettyFormat, Encoding.UTF8);

                        var writerBaseTime = session.CreateTimestamp;

                        if (ExperimentProperties.RecordMarkers.Get(experiment.Metadata) && streamers.TryFindFirst <MarkerStreamer>(out var markerStreamer))
                        {
                            var markerFileWriter = new MarkerFileWriter(session.GetDataFileName(MarkerFileWriter.FileSuffix), writerBaseTime);
                            disposablePool.Add(markerFileWriter);
                            markerStreamer.Attach(markerFileWriter);
                            disposablePool.Add(new DelegatedDisposable(() => markerStreamer.Detach(markerFileWriter)));
                        }

                        foreach (var entry in deviceConsumerLists)
                        {
                            if (deviceStreamers.TryGetValue(entry.Key, out var deviceStreamer))
                            {
                                var  deviceConsumerList = entry.Value;
                                var  indexed            = deviceConsumerList.Count > 1;
                                byte num = 1;

                                foreach (var tuple in deviceConsumerList)
                                {
                                    var consumer = tuple.Item1.NewInstance(session, tuple.Item2, indexed ? num++ : (byte?)null);
                                    if (consumer is IDisposable disposable)
                                    {
                                        disposablePool.Add(disposable);
                                    }
                                    deviceStreamer.Attach(consumer);
                                    disposablePool.Add(new DelegatedDisposable(() => deviceStreamer.Detach(consumer)));
                                }
                            }
                        }

                        sessionListener?.BeforeStart(i, session);
                        var result = session.Run();
                        sessionListener?.AfterCompleted(i, session);

                        disposablePool.DisposeAll(); // Release resources.

                        new SessionInfo(session).JsonSerializeToFile(session.GetDataFileName(SessionInfo.FileSuffix), JsonUtils.PrettyFormat, Encoding.UTF8);
                        result?.Save(session);

                        if (session.UserInterrupted && i < experimentParts.Count - 1 &&
                            MessageBox.Show("Continue following sessions?", "User Exit", MessageBoxButton.YesNo,
                                            MessageBoxImage.Question, MessageBoxResult.No, MessageBoxOptions.None) == MessageBoxResult.No)
                        {
                            break;
                        }
                    }
                }
                finally
                {
                    streamers.Stop();
                    monitorWindow?.Release(); // Detach session from monitor.
                }
            }
            sessionListener?.AfterAllCompleted(sessions);
        }