예제 #1
0
    public void Initialize()
    {
        if (!_isInitialized)
        {
            if (_openEditor == null)
            {
                _openEditor = new Subject <Unit>();
            }
            if (_closeEditor == null)
            {
                _closeEditor = new Subject <Unit>();
            }
            if (_disposables == null)
            {
                _disposables = new CompositeDisposable();
            }

            // Get the Gui camera, this will break in Oculus mode
            var cameraMovement = _spectatorCamera;

            var cameraTransform = new Ref <ImmutableTransform>(
                () => cameraMovement.transform.MakeImmutable(),
                transform => cameraMovement.transform.Set(transform));

            var isCourseEditorOpen = _openEditor.Select(_ => true)
                                     .Merge(_closeEditor.Select(_ => false))
                                     .StartWith(false);

            var courseStorageActions  = new CourseStorageActions();
            var courseSelectorActions = new CourseSelectorActions();
            var courseEditorActions   = new CourseEditorActions();
            var closeCurrentCourse    = new Subject <Unit>();

            var fileStorage = CoursesFileStorage.CourseUpdater(courseStorageActions, CoursesFileStorage.CoursesDir.Value);
            _disposables.Add(fileStorage);

            var customCourses = CoursesFileStorage.CustomCourses.Value
                                .ObserveOn(UnityThreadScheduler.MainThread);
            var courseSelectorStore = CourseSelectorStore.Create(courseSelectorActions, customCourses, isCourseEditorOpen);
            _disposables.Add(courseSelectorStore.Connect());
            var courseEditorStore = CourseSelectorStore.CreateCourseEditorStore(
                course => CourseEditorStore.Create(courseEditorActions, course, cameraTransform),
                courseSelectorStore.Select(s => {
                if (s.SelectedCourse.IsJust)
                {
                    return(s.AvailableCourses.Find(c => c.Id.Equals(s.SelectedCourse.Value)));
                }
                return(Maybe.Nothing <CourseData>());
            }));
            _disposables.Add(courseEditorStore.Connect());

            _disposables.Add(_openEditor.Subscribe(_ => _courseEditorGui.Show()));
            _disposables.Add(closeCurrentCourse
                             .WithLatestFrom(courseEditorStore, (_, finalCourseState) => finalCourseState)
                             .Subscribe(finalCourseState => {
                // Storing course changes to disk
                Debug.Log("deselecting a course");
                courseStorageActions.UpdateCourse.OnNext(finalCourseState.ToSerializableFormat());

                courseSelectorActions.DeselectCourse.OnNext(Unit.Default);
            }));

            // Initialize input for course editor store
            var propRenderer = new PropRenderer <PropId>(propId => "__CourseEditor-" + propId);
            // Clear the prop renderer when done editing
            _disposables.Add(courseEditorStore.Subscribe(_ => propRenderer.Clear()));
            CourseEditorInput.InitializeCourseEditor(courseEditorActions, courseEditorStore, _gameCamera, cameraTransform, _renderableProps, propRenderer, _clock);

            _courseEditorGui.CourseStorageActions  = courseStorageActions;
            _courseEditorGui.CourseEditorActions   = courseEditorActions;
            _courseEditorGui.CourseSelectorActions = courseSelectorActions;
            _courseEditorGui.CourseEditorChanges   = courseEditorStore;
            _courseEditorGui.CourseSelectorChanges = courseSelectorStore;
            _courseEditorGui.CloseCurrentCourse    = closeCurrentCourse;
            _courseEditorGui.CloseEditor           = _closeEditor;
            _courseEditorGui.ActiveLanguage        = _activeLanguage;
            _courseEditorGui.Initialize();

            var rightMouseButtonPressed = UnityObservable.CreateUpdate <bool>(observer => {
                if (Input.GetMouseButtonDown(1))
                {
                    observer.OnNext(true);
                }
                else if (Input.GetMouseButtonUp(1))
                {
                    observer.OnNext(false);
                }
            });

            _disposables.Add(courseSelectorStore
                             .CombineLatest(isCourseEditorOpen, rightMouseButtonPressed, (state, isOpen, isRightMouseButtonIsPressed) => {
                return(state.SelectedCourse.IsJust && isOpen && isRightMouseButtonIsPressed);
            })
                             .StartWith(false)
                             .Subscribe(isMovementEnabled => {
                if (isMovementEnabled)
                {
                    cameraMovement.EnableInputProcessing();
                }
                else
                {
                    cameraMovement.DisableInputProcessing();
                }
            }));

            _disposables.Add(_closeEditor.Subscribe(_ => {
                _courseEditorGui.Hide();
                propRenderer.Clear();
            }));

            _isInitialized = true;
        }
    }