public void Setup(CompositeDisposable cd, IEngine engine) { engine.Worker(cd, Dep.On(Register, Unregister), () => { var registered = registeredScenes.AsWriteProxy(); for (int i = 0, n = Register.Count; i < n; ++i) { registered.Add(Register[i]); } for (int i = 0, n = Unregister.Count; i < n; ++i) { // TODO Should be RemoveExact registered.Remove(Unregister[i]); } registered.Commit(); }); var watcher = engine.Wa(cd, registeredScenes, scene => scene.State); engine.Worker(cd, Dep.On(watcher, Unregister), () => { var active = ActiveScenes.AsWriteProxy(); for (int i = 0, n = Unregister.Count; i < n; ++i) { active.Remove(Unregister[i]); } for (int i = 0, n = registeredScenes.Count; i < n; ++i) { var scene = registeredScenes[i]; var state = scene.State.Read(); if ((state == SceneState.Opened || state == SceneState.Opening) && !active.Contains(scene)) { active.Add(scene); } else if (state == SceneState.Closed && active.Contains(scene)) { active.Remove(scene); } } active.Commit(); }); engine.Worker(cd, Dep.On(Back), () => { bool isSystem; if (!Back.TryRead(out isSystem) || ActiveScenes.Count <= 1) { return; } ActiveScenes[ActiveScenes.Count - 1].Back.Fire(isSystem); }); }