示例#1
0
 public void End()
 {
     Scheduler.Dequeue(this);
     DebugLog.Info("<-- End {0}", this.GetType().Name);
     enumerator = null;
     OnEnd();
 }
示例#2
0
        public override void Calibrate(CalibrationResultHandler callback)
        {
            IsCalibrated = false;

            DebugLog.Info("EyeTribe: Start calibration");
            UnityCalibrationRunner.StartCalibration(
                CalibrationPointSampleDuration,
                CalibrationPoints,
                (object sender, TETControls.Calibration.CalibrationRunnerEventArgs e) =>
            {
                IsCalibrated = e.CalibrationResult.Result;
                if (IsCalibrated)
                {
                    GazeManager.Instance.AddGazeListener(this);
                }

                Dictionary <string, object> calibrationProperties = new Dictionary <string, object>();
                calibrationProperties["Result"]                  = e.Result.ToString();
                calibrationProperties["Rating"]                  = e.Rating;
                calibrationProperties["AverageErrorDegree"]      = e.CalibrationResult.AverageErrorDegree;
                calibrationProperties["AverageErrorDegreeLeft"]  = e.CalibrationResult.AverageErrorDegreeLeft;
                calibrationProperties["AverageErrorDegreeRight"] = e.CalibrationResult.AverageErrorDegreeRight;

                callback(IsCalibrated, e.Message, calibrationProperties);
            });
        }
示例#3
0
        protected void SaveActivityStateAndTransition <ToViewModel>()
        {
            DebugLog.Info("Save state");
            navigator.Reveal <ProgressIndicatorViewModel>().Then((vm, onRevealed, onRevealError) =>
            {
                ProgressIndicatorViewModel progressIndicatorViewModel = vm.ResultAs <ProgressIndicatorViewModel>();
                ProgressIndicatorViewModel.ProgressInfo busyIndicator = progressIndicatorViewModel.Begin("Saving...");
                activityService.SaveActivityState(ActivityState)
                .Then((prevResult, onCompleted, onError) =>
                {
                    navigator.Transition(this, typeof(ToViewModel));
                    onCompleted(true);
                })
                .Catch((Exception e) =>
                {
                    navigator.Reveal <AlertViewModel>(alert =>
                    {
                        alert.Title           = "Unable to save";
                        alert.Message         = e.Message;
                        alert.Error           = e;
                        alert.AlertDismissed += ((int index) => DebugLog.Info("Button {0} pressed", index));
                    }).Start();
                }).Finally(() =>
                {
                    busyIndicator.Dispose();
                }).Start();

                onRevealed(true);
            }).Start();
        }
        public override void Disconnect()
        {
            int ret = 0;

            try
            {
                DebugLog.Info("SMI Eye Tracker: Disconnect");
                ret = ETDevice.iV_Disconnect();
                if (ret == 1)
                {
                    ETDevice = null;

                    DebugLog.Info("Disconnnected from EyeTracker: {0}:{1}", ServerRecvAddress, ServerRecvPort);
                    IsConnected = false;
                }
                else
                {
                    throw new Exception("Unable to setup disconnect. " + GetErrorMessage(ret));
                }
            }
            catch (Exception e)
            {
                throw new Exception(string.Format("Unable to disconnect from SMI server ({0}:{1}). {2}", ServerRecvAddress, ServerRecvPort, e.Message));
            }
        }
        public AsyncTask Reveal(ViewModel vm, VisibilityEvent.OnceEventHandler handler = null)
        {
            Contract.ArgumentNotNull("vm", vm);

            return(new AsyncTask((prevResult, onCompleted, onError) =>
            {
                try
                {
                    DebugLog.Info("StageManager.Reveal: {0}", vm.GetType().Name);

                    IView view = revealedViews.FirstOrDefault(v => v.BindingContext == vm);
                    if (view == null)
                    {
                        view = viewFactory.Resolve(vm);
                        view.BindingContext = vm;
                        revealedViews.Add(view);
                        view.Reveal(false, (IView revealedView) =>
                        {
                            onCompleted(revealedView.BindingContext);
                        });
                    }
                }
                catch (Exception e)
                {
                    onError(e);
                }
            }));
        }
示例#6
0
        public void OnBoardCellClicked(GameObject button)
        {
            DebugLog.Info("Cell selected: " + button.name);
            Vector2 location = ParseColumnRowFromName(button.name);

            ViewModel.PlaceGlyph(ViewModel.PlayerId, (int)location.x, (int)location.y);
        }
 void Update()
 {
     // Detect field change
     if (brain != previousBrain)
     {
         if (brain != null)
         {
             if (brain.DecisionMaker != null)
             {
                 DebugLog.Info("IntelligentAgent set NavigationController");
                 NavigationController navController = GetComponent <NavigationController>();
                 if (navController != null)
                 {
                     brain.DecisionMaker.LocalKnowledge.Set("NavigationController", navController);
                 }
                 brain.DecisionMaker.IsEnabled = enabled;
             }
             else
             {
                 DebugLog.Error("DecisionMaker not set in {0}", brain.name);
             }
         }
         previousBrain = brain;
     }
 }
示例#8
0
 // Schedule task to run in the scheduler
 public void Start()
 {
     Status = CooperativeTaskStatus.WaitingToRun;
     DebugLog.Info("--> Start {0}", this.GetType().Name);
     enumerator = DoWork().GetEnumerator();
     OnStart();
     TryInlineExecute();
 }
示例#9
0
        private void OnGlyphPlaced(int column, int row, char glyph)
        {
            string glyphString = glyph.ToString();

            DebugLog.Info("Glyph placed ({0},{1}): {2} ", column, row, glyphString);
            Button button = GetButtonAt(column, row);

            button.GetComponentInChildren <Text>().text = glyphString;
            button.interactable = TicTacToeViewModel.Glyphs.All(g => g != glyph);
        }
        protected virtual void OnApplicationQuit()
        {
            DebugLog.Info("Destroying {0} singleton on application exit", typeof(T).Name);

            if (_instance != null)
            {
                Destroy(_instance.gameObject);
                _instance = null;
            }
        }
        public AsyncTask Start(Student student, Activity activity, bool resetActivityState = false)
        {
            return(activityService.LoadActivityState(student.Id, activity.Id, true)
                   .Then((prevResult, onCompleted, onError) =>
            {
                ActivityState activityState = prevResult.ResultAs <ActivityState>();
                if (resetActivityState || !activityState.CanResume)
                {
                    // Generate a new trace ID for restarts or new games that don't have saved state
                    activityState.TraceId = Guid.NewGuid().ToString();
                }

                DebugLog.Info("Start activity!");
//					startedEntry = TraceLog.Player(TraceLog.Action.Started, "Activity",
//					                               "Name", activity.Name,
//					                               "ActivityUri", activity.Uri,
//					                               "IsComplete", activityState.IsComplete,
//					                               "CanResume", activityState.CanResume,
//					                               "Restart", resetActivityState,
//					                               "StartDate", activityState.ModifiedDate.ToIso8601(),
//					                               "Username", student.Username,
//					                               "SubjectId", student.SubjectId,
//					                               "TraceId", activityState.TraceId);
//
//					if (activity.Uri.Contains("episode"))
//					{
//						LaunchEpisode(activityState, activity.Name, activity.Uri, resetActivityState);
//					}
//					else if (activity.Uri.Contains("assessment"))
//					{
//						LaunchAssessment(activityState, activity.Name, activity.Uri);
//					}
//					else if (activity.Uri.Contains("http"))
//					{
//						LaunchUrl(activityState, activity.Name, activity.Uri);
//					}
//					else
//					{
//						throw new Exception(String.Format("{0} has an unknown URI type: ", activity.Name, activity.Uri));
//					}

                onCompleted(viewModelFactory.Resolve <ActivityViewModel>(Resolve(activity.Uri), vm =>
                {
                    vm.Activity = activity;
                    vm.ActivityState = activityState;
                }));

//					promise.Resolve(viewModelFactory.Resolve<WebActivityViewModel>(web =>
//					{
//						web.Title = "Web Browser Launched";
//						web.Message = "Complete web viewer action for " + activity.Name;
//						web.URL = "http://www.google.com";
//					}));
            }));
        }
        /// <summary>
        /// Destroy and recreate the singleton object
        /// </summary>
        public static void Reset()
        {
            DebugLog.Info("Reset {0} singleton", typeof(T).Name);

            if (_instance != null)
            {
                GameObject previousObject = _instance.gameObject;
                _instance = Create();
                Destroy(previousObject);
            }
        }
示例#13
0
        public override void Disconnect()
        {
            UnityCalibrationRunner.Abort();

            GazeManager.Instance.RemoveGazeListener(this);
            GazeManager.Instance.RemoveConnectionStateListener(this);

            DebugLog.Info("Eye Tracker: Disconnect...");
            GazeManager.Instance.Deactivate();
            DebugLog.Info("Disconnnected from EyeTracker: {0}:{1}", ServerRecvAddress, ServerRecvPort);
            IsConnected = false;
        }
        /// <summary>
        /// Factory method that creates a GameObject to host the singleton
        /// </summary>
        private static T Create()
        {
            DebugLog.Info("Creating {0} singleton", typeof(T).Name);

            GameObject gameObject = new GameObject(typeof(T).Name,
                                                   typeof(T));

            // Do not automatically destory the game object when loading a new scene
            DontDestroyOnLoad(gameObject);

            return((T)(gameObject.GetComponent(typeof(T))));
        }
        private void RefreshActivityList()
        {
            try
            {
                Contract.PropertyNotNull("sessionState.CourseSettings", sessionState.CourseSettings);

                DebugLog.Info("RefreshActivityList");
                navigator.Reveal <ProgressIndicatorViewModel>().Then((vm, onRevealed, onRevealError) =>
                {
                    ProgressIndicatorViewModel progressIndicatorViewModel = vm.ResultAs <ProgressIndicatorViewModel>();
                    ProgressIndicatorViewModel.ProgressInfo busyIndicator = progressIndicatorViewModel.Begin("Loading...");
                    activityService.LoadActivities(sessionState.CourseSettings.CourseId)
                    .Then((prevResult, onCompleted, onError) =>
                    {
                        DebugLog.Info("Activities loaded");
                        Activities = prevResult.ResultAs <List <Activity> >();
                        IEnumerable <string> activityIds = Activities.Select(a => a.Id);
                        activityService.LoadActivityStates(sessionState.Student.Id, activityIds).Start(onCompleted, onError);
                    })
                    .Then((prevResult, onCompleted, onError) =>
                    {
                        DebugLog.Info("Activity States loaded");
                        ActivityStates = prevResult.ResultAs <List <ActivityState> >();
                        onCompleted(true);
                    })
                    .Catch((Exception e) =>
                    {
                        DebugLog.Error("Can't load activitues: {0}", e.Message);
                        navigator.Reveal <AlertViewModel>(alert =>
                        {
                            alert.Title           = "Unable to load activity information.";
                            alert.Message         = e.Message;
                            alert.Error           = e;
                            alert.AlertDismissed += ((int index) => DebugLog.Info("Button {0} pressed", index));
                        }).Start();
                    }).Finally(() =>
                    {
                        busyIndicator.Dispose();
                    }).Start();

                    onRevealed(true);
                }).Start();
            }
            catch (Exception e)
            {
                navigator.Reveal <AlertViewModel>(alert =>
                {
                    alert.Title   = "Unable load activity information";
                    alert.Message = e.Message;
                    alert.Error   = e;
                }).Start();
            }
        }
        static string[] OnWillSaveAssets(string[] paths)
        {
            foreach (string path in paths)
            {
                DebugLog.Info(path);
                Brain brain = AssetDatabase.LoadAssetAtPath(path, typeof(Brain)) as Brain;
                if (brain != null)
                {
                    brain.OnSave();
                }
            }

            return(paths);
        }
示例#17
0
        /// <summary>
        /// Get response stream from a web service indicated by URI
        /// </summary>
        /// <param name="uri">URI (path plus query string) to web service</param>
        /// <param name="retries">The number of times to retry get if it fails</param>
        /// <param name="callback">Method called on failure or success that is passed an AsyncResult whose Result property is set to HttpResult</param>
        /// <returns>WebRequest IAsyncResult object</returns>
        public IAsyncResult Get(Uri uri, int retries, AsyncCallback callback)
        {
#if (SILVERLIGHT || WPF || TOOL)
            WebRequest webRequest = WebRequest.Create(uri);
#else
            WebRequest webRequest = new UnityWebRequest(uri);
#endif
            webRequest.Method = "GET";
            IAsyncResult asyncResult = webRequest.BeginGetResponse((responseResult) =>
            {
                bool retry            = false;
                HttpResult httpResult = null;
                try
                {
                    HttpWebResponse response = ((WebRequest)responseResult.AsyncState).EndGetResponse(responseResult) as HttpWebResponse;
                    // Response stream is released when HttpResult is released
                    httpResult = new HttpResult(response.GetResponseStream(), response.StatusCode, response.StatusDescription, response.ContentType);
                }
                catch (WebException we)
                {
                    DebugLog.Error("WebException -> Get '{0}' failed", uri.ToString());
                    DebugLog.Error(we.Message);
                    if (retries > 0 && we.Status != WebExceptionStatus.RequestCanceled)
                    {
                        DebugLog.Info("Retry Get '{0}'", uri.ToString());
                        Get(uri, --retries, callback);
                        retry = true;
                    }
                    else
                    {
                        httpResult = new HttpResult(we);
                    }
                }
                catch (Exception e)
                {
                    DebugLog.Error("HTTP GET '{0}' failed: {1}", uri.ToString(), e.Message);
                    httpResult = new HttpResult(e);
                }
                finally
                {
                    if (!retry && callback != null)
                    {
                        callback(new AsyncResult <HttpResult>(httpResult));
                    }
                }
            },
                                                                   webRequest);

            return(asyncResult);
        }
        public ViewModel Hide(ViewModel vm, VisibilityEvent.OnceEventHandler handler = null)
        {
            Contract.ArgumentNotNull("vm", vm);

            DebugLog.Info("StageManager.Hide: {0}", vm.GetType().Name);

            IView view = revealedViews.FirstOrDefault(v => v.BindingContext == vm);

            if (view != null)
            {
                view.Hide(false, handler);
                revealedViews.Remove(view);
            }

            return(vm);
        }
示例#19
0
        private void OnEnabledChanged()
        {
            DebugLog.Info("FileLogger: {0} Enabled={1}", Filename, Enabled);

            // Lazy initialization so that this can be enabled/disabled after a session has started
            if (Enabled && FileStreamWriter == null)
            {
                Contract.PropertyNotNull("Filename", Filename);

                System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(Filename));

                FileStreamWriter           = new System.IO.StreamWriter(Filename);
                FileStreamWriter.AutoFlush = true;

                FileStreamWriter.Write(Serializer.GetHeader <LogEntry>());
            }
        }
        public void StartActivity(Activity activity)
        {
            try
            {
                Contract.ArgumentNotNull("activity", activity);

                DebugLog.Info("Started Activity {0}", activity.Name);

                navigator.Reveal <ProgressIndicatorViewModel>().Then((vm, onRevealed, onRevealError) =>
                {
                    ProgressIndicatorViewModel progressIndicatorViewModel = vm.ResultAs <ProgressIndicatorViewModel>();
                    ProgressIndicatorViewModel.ProgressInfo busyIndicator = progressIndicatorViewModel.Begin("Starting...");
                    activityLauncher.Start(sessionState.Student, activity, false)
                    .Then((prevResult, onCompleted, onError) =>
                    {
                        navigator.Transition(this, prevResult.ResultAs <ActivityViewModel>());
                        onCompleted(true);
                    })
                    .Catch((Exception e) =>
                    {
                        navigator.Reveal <AlertViewModel>(alert =>
                        {
                            alert.Title           = "Unable to start activity";
                            alert.Message         = e.Message;
                            alert.Error           = e;
                            alert.AlertDismissed += ((int index) => DebugLog.Info("Button {0} pressed", index));
                        }).Start();
                    }).Finally(() =>
                    {
                        busyIndicator.Dispose();
                    }).Start();
                }).Start();
            }
            catch (Exception e)
            {
                navigator.Reveal <AlertViewModel>(alert =>
                {
                    alert.Title   = "Unable to start activity";
                    alert.Message = e.Message;
                    alert.Error   = e;
                }).Start();
            }
        }
 public void SignOut()
 {
     DebugLog.Info("SignOut");
     try
     {
         authenticator.SignOut((bool success, string message) =>
         {
             navigator.Transition(this, typeof(SignInViewModel));
         });
     }
     catch (Exception e)
     {
         navigator.Reveal <AlertViewModel>(alert =>
         {
             alert.Title           = "Unable to sign out";
             alert.Message         = e.Message;
             alert.Error           = e;
             alert.AlertDismissed += ((int index) => DebugLog.Info("Button {0} pressed", index));
         }).Start();
     }
 }
 protected virtual void Awake()
 {
     // If this is the first GameObject to be created, assign it to the instance. Otherwise,
     // destroy it since it is a duplicate.
     if (current == null)
     {
         referenceCache.Clear();
         current = this.GetComponent <T>();
         if (keepOnSceneChange)
         {
             // Do not automatically destory the game object when loading a new scene
             DontDestroyOnLoad(this);
         }
     }
     else
     {
         DebugLog.Info("'{0}' GameObject with '{1}' component already exists. Destroying '{2}' GameObject with duplicate component.",
                       Current.name,
                       typeof(T).Name,
                       this.name);
         GameObject.Destroy(gameObject);
     }
 }
示例#23
0
        public override void Connect()
        {
            ValidateSettings();

            DebugLog.Info("Eye Tracker: Connecting...");
            GazeManager.Instance.AddConnectionStateListener(this);

            bool success = GazeManager.Instance.Activate(
                GazeManager.ApiVersion.VERSION_1_0,
                GazeManager.ClientMode.Push,
                ServerRecvAddress,
                ServerRecvPort);

            if (success)
            {
                DebugLog.Info("EyeTracker: Connnected to EyeTribe server: {0}:{1}", ServerRecvAddress, ServerRecvPort);
                IsConnected = true;
            }
            else
            {
                throw new Exception(string.Format("Unable to connect to EyeTribe server:  {0}:{1}", ServerRecvAddress, ServerRecvPort));
            }
        }
示例#24
0
        private IEnumerator FireTickEvent()
        {
            LastTickTime = UnityEngine.Time.time;

            while (true)
            {
                float waitTime = (float)(Interval.TotalSeconds - (UnityEngine.Time.time - LastTickTime));
                DebugLog.Info("{0} - DispatcherTimer - Wait for {1} seconds", UnityEngine.Time.time, waitTime);
                yield return(new WaitForSeconds(waitTime));

                if (!IsEnabled)
                {
                    break;
                }

                if (Tick != null)
                {
                    DebugLog.Info("{0} - DispatcherTimer - Tick", UnityEngine.Time.time);
                    Tick(this, null);
                }
                LastTickTime = UnityEngine.Time.time;
            }
        }
        public override void Connect()
        {
            ValidateSettings();

            int ret = 0;

            try
            {
                ETDevice = new EyeTrackingController.EyeTrackingController();
                ETDevice.iV_SetLogger(0, new StringBuilder(this.GetType().Name + ".txt"));

                calibrationCallbackDelegate = new CalibrationCallback(CalibrationCallbackFunction);
                sampleCallbackDelegate      = new GetSampleCallback(GetSampleCallbackFunction);

                ETDevice.iV_SetCalibrationCallback(calibrationCallbackDelegate);
                ETDevice.iV_SetSampleCallback(sampleCallbackDelegate);

                // connect to server
                DebugLog.Info("SMI Eye Tracker: Connect");
                ret = ETDevice.iV_Connect(
                    new StringBuilder(ServerSendAddress), ServerSendPort,
                    new StringBuilder(ServerRecvAddress), ServerRecvPort);
                if (ret == 1)
                {
                    DebugLog.Info("EyeTracker connection established: {0}:{1}", ServerRecvAddress, ServerRecvPort);
                    IsConnected = true;
                }
                else
                {
                    throw new Exception("Unable to connect. " + GetErrorMessage(ret));
                }
            }
            catch (Exception e)
            {
                throw new Exception(string.Format("Unable to connect SMI server ({0}:{1}). {2}", ServerRecvAddress, ServerRecvPort, e.Message));
            }
        }
示例#26
0
 public void OnConnectionStateChanged(bool isConnected)
 {
     DebugLog.Info("EyeTribe server isConnected = {0}", isConnected);
 }
 public void Remove(ProgressInfo indicator)
 {
     indicators.Remove(indicator);
     OnActivitiesChanged();
     DebugLog.Info(GetActivities());
 }
 protected virtual void OnDestroy()
 {
     DebugLog.Info("OnDestroy {0} singleton", typeof(T).Name);
     IsBeingDestroyed = true;
 }
示例#29
0
        /// <summary>
        /// Post one or more MIME parts to a URI
        /// </summary>
        /// <param name="uri">The URI of the web service to receive the Http post message</param>
        /// <param name="retries">Number of times to retry post if there is an error</param>
        /// <param name="mimeParts">MIME encoded payload</param>
        /// <param name="callback">Method called on failure or success that is passed an AsyncResult whose Result property is set to HttpResult</param>
        /// <returns>WebRequest IAsyncResult object</returns>
        public IAsyncResult Post(Uri uri, int retries, List <MimePart> mimeParts, AsyncCallback callback)
        {
#if (SILVERLIGHT || WPF || TOOL)
            WebRequest webRequest = WebRequest.Create(uri);
#else
            WebRequest webRequest = new UnityWebRequest(uri);
#endif
            webRequest.Method = "POST";
            IAsyncResult asyncResult = webRequest.BeginGetRequestStream((asynchronousResult) =>
            {
                WebRequest request = (WebRequest)asynchronousResult.AsyncState;

                if (mimeParts.Count > 1)
                {
                    CreateMultiPartRequest(request, asynchronousResult, mimeParts);
                }
                else
                {
                    CreateSinglePartRequest(request, asynchronousResult, mimeParts[0]);
                }

                // Start the asynchronous operation to get the response
                request.BeginGetResponse((responseResult) =>
                {
                    bool retry            = false;
                    HttpResult httpResult = null;
                    try
                    {
                        HttpWebResponse response = ((WebRequest)responseResult.AsyncState).EndGetResponse(responseResult) as HttpWebResponse;
                        // Response stream is released when HttpResult is released
                        httpResult = new HttpResult(response.GetResponseStream(), response.StatusCode, response.StatusDescription, response.ContentType);
                    }
                    catch (WebException we)
                    {
                        DebugLog.Error("WebException -> {0} '{1}' failed", webRequest.Method, uri.ToString());
                        DebugLog.Error(we.Message);
                        if (retries > 0 && we.Status != WebExceptionStatus.RequestCanceled)
                        {
                            DebugLog.Info("Retry {0} '{1}'", webRequest.Method, uri.ToString());
                            Post(uri, --retries, mimeParts, callback);
                            retry = true;
                        }
                        else
                        {
                            httpResult = new HttpResult(we);
                        }
                    }
                    catch (Exception e)
                    {
                        DebugLog.Error("HTTP {0} '{1}' failed: {2}", webRequest.Method, uri.ToString(), e.Message);
                        httpResult = new HttpResult(e);
                    }
                    finally
                    {
                        if (!retry && callback != null)
                        {
                            callback(new AsyncResult <HttpResult>(httpResult));
                        }
                    }
                },
                                         request);
            },
                                                                        webRequest);

            return(asyncResult);
        }
示例#30
0
        public void SignIn(string group, string username, string password)
        {
            try
            {
                if (string.IsNullOrEmpty(username))
                {
                    throw new Exception("Username is blank");
                }

                if (string.IsNullOrEmpty(password))
                {
                    throw new Exception("Password is blank");
                }

                sessionState.Student = null;
                sessionState.Session = null;

                DebugLog.Info("SignIn {0}...", username);
                navigator.Reveal <ProgressIndicatorViewModel>().Then((vm, onRevealed, onRevealError) =>
                {
                    ProgressIndicatorViewModel progressIndicatorViewModel = vm.ResultAs <ProgressIndicatorViewModel>();
                    ProgressIndicatorViewModel.ProgressInfo busyIndicator = progressIndicatorViewModel.Begin("Signing in...");
                    // TODO rgtaylor 2015-12-10 Replace hardcoded 'domain'
                    authenticator.SignIn(group, username, password)
                    .Then((prevResult, onCompleted, onError) =>
                    {
                        DebugLog.Info("Signed in {0}", username);
                        sessionState.Student = prevResult.ResultAs <Student>();
                        sessionService.Start(sessionState.Student.SessionGuid).Start(onCompleted, onError);
                    })
                    .Then((prevResult, onCompleted, onError) =>
                    {
                        DebugLog.Info("Session started");
                        sessionState.Session = prevResult.ResultAs <Session>();
                        courseSettingsService.LoadSettings(sessionState.Student.Id).Start(onCompleted, onError);
                    })
                    .Then((prevResult, onCompleted, onError) =>
                    {
                        DebugLog.Info("Settings loaded");
                        sessionState.CourseSettings = prevResult.ResultAs <CourseSettings>();
                        navigator.Transition(this, typeof(MainMenuViewModel));
                        onCompleted(true);
                    }).Catch((Exception e) =>
                    {
                        navigator.Reveal <AlertViewModel>(alert =>
                        {
                            alert.Title           = "Unable to sign in";
                            alert.Message         = e.Message;
                            alert.Error           = e;
                            alert.AlertDismissed += ((int index) => DebugLog.Info("Button {0} pressed", index));
                        });
                    }).Finally(() =>
                    {
                        busyIndicator.Dispose();
                    }).Start();

                    onRevealed(true);
                }).Start();
            }
            catch (Exception e)
            {
                navigator.Reveal <AlertViewModel>(alert =>
                {
                    alert.Title   = "Unable to sign in";
                    alert.Message = e.Message;
                    alert.Error   = e;
                }).Start();
            }
        }