public void TestSessionStaticsReset() { sessionStatics = new SessionStatics(); sessionStatics.SetValue(Static.LoginOverlayDisplayed, true); sessionStatics.SetValue(Static.MutedAudioNotificationShownOnce, true); sessionStatics.SetValue(Static.LowBatteryNotificationShownOnce, true); sessionStatics.SetValue(Static.LastHoverSoundPlaybackTime, (double?)1d); sessionStatics.SetValue(Static.SeasonalBackgrounds, new APISeasonalBackgrounds { EndDate = new DateTimeOffset(2022, 1, 1, 0, 0, 0, TimeSpan.Zero) }); Assert.IsFalse(sessionStatics.GetBindable <bool>(Static.LoginOverlayDisplayed).IsDefault); Assert.IsFalse(sessionStatics.GetBindable <bool>(Static.MutedAudioNotificationShownOnce).IsDefault); Assert.IsFalse(sessionStatics.GetBindable <bool>(Static.LowBatteryNotificationShownOnce).IsDefault); Assert.IsFalse(sessionStatics.GetBindable <double?>(Static.LastHoverSoundPlaybackTime).IsDefault); Assert.IsFalse(sessionStatics.GetBindable <APISeasonalBackgrounds>(Static.SeasonalBackgrounds).IsDefault); sessionStatics.ResetAfterInactivity(); Assert.IsTrue(sessionStatics.GetBindable <bool>(Static.LoginOverlayDisplayed).IsDefault); Assert.IsTrue(sessionStatics.GetBindable <bool>(Static.MutedAudioNotificationShownOnce).IsDefault); Assert.IsTrue(sessionStatics.GetBindable <bool>(Static.LowBatteryNotificationShownOnce).IsDefault); // some statics should not reset despite inactivity. Assert.IsFalse(sessionStatics.GetBindable <double?>(Static.LastHoverSoundPlaybackTime).IsDefault); Assert.IsFalse(sessionStatics.GetBindable <APISeasonalBackgrounds>(Static.SeasonalBackgrounds).IsDefault); }
private void load(SessionStatics sessionStatics) { muteWarningShownOnce = sessionStatics.GetBindable <bool>(Static.MutedAudioNotificationShownOnce); InternalChild = (content = new LogoTrackingContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, }).WithChildren(new Drawable[] { MetadataInfo = new BeatmapMetadataDisplay(Beatmap.Value, Mods, content.LogoFacade) { Alpha = 0, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, new FillFlowContainer <PlayerSettingsGroup> { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 20), Margin = new MarginPadding(25), Children = new PlayerSettingsGroup[] { VisualSettings = new VisualSettings(), new InputSettings() } }, idleTracker = new IdleTracker(750) }); }
private void load(OsuConfigManager config, SessionStatics sessionStatics) { seasonalBackgroundMode = config.GetBindable <SeasonalBackgroundMode>(OsuSetting.SeasonalBackgroundMode); seasonalBackgroundMode.BindValueChanged(_ => SeasonalBackgroundChanged?.Invoke()); seasonalBackgrounds = sessionStatics.GetBindable <APISeasonalBackgrounds>(Static.SeasonalBackgrounds); seasonalBackgrounds.BindValueChanged(_ => SeasonalBackgroundChanged?.Invoke()); apiState.BindTo(api.State); apiState.BindValueChanged(fetchSeasonalBackgrounds, true); }
private void load(SessionStatics sessionStatics, AudioManager audio) { muteWarningShownOnce = sessionStatics.GetBindable <bool>(Static.MutedAudioNotificationShownOnce); batteryWarningShownOnce = sessionStatics.GetBindable <bool>(Static.LowBatteryNotificationShownOnce); InternalChildren = new Drawable[] { (content = new LogoTrackingContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, }).WithChildren(new Drawable[] { MetadataInfo = new BeatmapMetadataDisplay(Beatmap.Value, Mods, content.LogoFacade) { Alpha = 0, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, PlayerSettings = new FillFlowContainer <PlayerSettingsGroup> { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 20), Margin = new MarginPadding(25), Children = new PlayerSettingsGroup[] { VisualSettings = new VisualSettings(), new InputSettings() } }, idleTracker = new IdleTracker(750), }), lowPassFilter = new AudioFilter(audio.TrackMixer), highPassFilter = new AudioFilter(audio.TrackMixer, BQFType.HighPass) }; if (Beatmap.Value.BeatmapInfo.EpilepsyWarning) { AddInternal(epilepsyWarning = new EpilepsyWarning { Anchor = Anchor.Centre, Origin = Anchor.Centre, }); } }
public void SetUp() { sessionStatics = new SessionStatics(); sessionIdleTracker = new GameIdleTracker(1000); sessionStatics.SetValue(Static.LoginOverlayDisplayed, true); sessionStatics.SetValue(Static.MutedAudioNotificationShownOnce, true); sessionStatics.SetValue(Static.LowBatteryNotificationShownOnce, true); sessionStatics.SetValue(Static.LastHoverSoundPlaybackTime, (double?)1d); sessionIdleTracker.IsIdle.BindValueChanged(e => { if (e.NewValue) { sessionStatics.ResetValues(); } }); }
private void load(AudioManager audio, SessionStatics statics) { lastPlaybackTime = statics.GetBindable <double?>(Static.LastHoverSoundPlaybackTime); }
private void load(BeatmapListingOverlay beatmapListing, SettingsOverlay settings, RankingsOverlay rankings, OsuConfigManager config, SessionStatics statics) { holdDelay = config.GetBindable <float>(OsuSetting.UIHoldActivationDelay); loginDisplayed = statics.GetBindable <bool>(Static.LoginOverlayDisplayed); if (host.CanExit) { AddInternal(exitConfirmOverlay = new ExitConfirmOverlay { Action = () => { if (holdDelay.Value > 0) { confirmAndExit(); } else { this.Exit(); } } }); } AddRangeInternal(new[] { buttonsContainer = new ParallaxContainer { ParallaxAmount = 0.01f, Children = new Drawable[] { buttons = new ButtonSystem { OnEdit = delegate { this.Push(new Editor()); }, OnSolo = onSolo, OnMulti = delegate { this.Push(new Multiplayer()); }, OnExit = confirmAndExit, } } }, sideFlashes = new MenuSideFlashes(), songTicker = new SongTicker { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Margin = new MarginPadding { Right = 15, Top = 5 } }, exitConfirmOverlay?.CreateProxy() ?? Drawable.Empty() }); buttons.StateChanged += state => { switch (state) { case ButtonSystemState.Initial: case ButtonSystemState.Exit: Background.FadeColour(Color4.White, 500, Easing.OutSine); break; default: Background.FadeColour(OsuColour.Gray(0.8f), 500, Easing.OutSine); break; } }; buttons.OnSettings = () => settings?.ToggleVisibility(); buttons.OnBeatmapListing = () => beatmapListing?.ToggleVisibility(); buttons.OnChart = () => rankings?.ShowSpotlights(); LoadComponentAsync(background = new BackgroundScreenDefault()); preloadSongSelect(); }
private void load(DirectOverlay direct, SettingsOverlay settings, OsuConfigManager config, SessionStatics statics) { holdDelay = config.GetBindable <float>(OsuSetting.UIHoldActivationDelay); loginDisplayed = statics.GetBindable <bool>(Static.LoginOverlayDisplayed); if (host.CanExit) { AddInternal(exitConfirmOverlay = new ExitConfirmOverlay { Action = () => { if (holdDelay.Value > 0) { confirmAndExit(); } else { this.Exit(); } } }); } AddRangeInternal(new Drawable[] { new ParallaxContainer { ParallaxAmount = 0.01f, Children = new Drawable[] { buttons = new ButtonSystem { OnChart = delegate { this.Push(new ChartListing()); }, OnEdit = delegate { this.Push(new Editor()); }, OnSolo = onSolo, OnMulti = delegate { this.Push(new Multiplayer()); }, OnExit = confirmAndExit, } } }, sideFlashes = new MenuSideFlashes(), }); buttons.StateChanged += state => { switch (state) { case ButtonSystemState.Initial: case ButtonSystemState.Exit: Background.FadeColour(Color4.White, 500, Easing.OutSine); break; default: Background.FadeColour(OsuColour.Gray(0.8f), 500, Easing.OutSine); break; } }; buttons.OnSettings = () => settings?.ToggleVisibility(); buttons.OnDirect = () => direct?.ToggleVisibility(); LoadComponentAsync(background = new BackgroundScreenDefault()); preloadSongSelect(); }
private void load(ReadableKeyCombinationProvider keyCombinationProvider) { try { using (var str = File.OpenRead(typeof(OsuGameBase).Assembly.Location)) VersionHash = str.ComputeMD5Hash(); } catch { // special case for android builds, which can't read DLLs from a packed apk. // should eventually be handled in a better way. VersionHash = $"{Version}-{RuntimeInfo.OS}".ComputeMD5Hash(); } Resources.AddStore(new DllResourceStore(OsuResources.ResourceAssembly)); if (Storage.Exists(DatabaseContextFactory.DATABASE_NAME)) { dependencies.Cache(EFContextFactory = new DatabaseContextFactory(Storage)); } dependencies.Cache(realm = new RealmAccess(Storage, "client", EFContextFactory)); dependencies.CacheAs <RulesetStore>(RulesetStore = new RealmRulesetStore(realm, Storage)); dependencies.CacheAs <IRulesetStore>(RulesetStore); Decoder.RegisterDependencies(RulesetStore); // Backup is taken here rather than in EFToRealmMigrator to avoid recycling realm contexts // after initial usages below. It can be moved once a direction is established for handling re-subscription. // See https://github.com/ppy/osu/pull/16547 for more discussion. if (EFContextFactory != null) { const string backup_folder = "backups"; string migration = $"before_final_migration_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}"; EFContextFactory.CreateBackup(Path.Combine(backup_folder, $"client.{migration}.db")); realm.CreateBackup(Path.Combine(backup_folder, $"client.{migration}.realm")); using (var source = Storage.GetStream("collection.db")) { if (source != null) { using (var destination = Storage.GetStream(Path.Combine(backup_folder, $"collection.{migration}.db"), FileAccess.Write, FileMode.CreateNew)) source.CopyTo(destination); } } } dependencies.CacheAs(Storage); var largeStore = new LargeTextureStore(Host.CreateTextureLoaderStore(new NamespacedResourceStore <byte[]>(Resources, @"Textures"))); largeStore.AddStore(Host.CreateTextureLoaderStore(new OnlineStore())); dependencies.Cache(largeStore); dependencies.CacheAs(this); dependencies.CacheAs(LocalConfig); InitialiseFonts(); Audio.Samples.PlaybackConcurrency = SAMPLE_CONCURRENCY; dependencies.Cache(SkinManager = new SkinManager(Storage, realm, Host, Resources, Audio, Scheduler)); dependencies.CacheAs <ISkinSource>(SkinManager); EndpointConfiguration endpoints = UseDevelopmentServer ? (EndpointConfiguration) new DevelopmentEndpointConfiguration() : new ProductionEndpointConfiguration(); MessageFormatter.WebsiteRootUrl = endpoints.WebsiteRootUrl; dependencies.CacheAs(API ??= new APIAccess(LocalConfig, endpoints, VersionHash)); dependencies.CacheAs(spectatorClient = new OnlineSpectatorClient(endpoints)); dependencies.CacheAs(multiplayerClient = new OnlineMultiplayerClient(endpoints)); var defaultBeatmap = new DummyWorkingBeatmap(Audio, Textures); // ordering is important here to ensure foreign keys rules are not broken in ModelStore.Cleanup() dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, () => BeatmapManager, Storage, realm, Scheduler, () => difficultyCache, LocalConfig)); dependencies.Cache(BeatmapManager = new BeatmapManager(Storage, realm, RulesetStore, API, Audio, Resources, Host, defaultBeatmap, performOnlineLookups: true)); dependencies.Cache(BeatmapDownloader = new BeatmapModelDownloader(BeatmapManager, API)); dependencies.Cache(ScoreDownloader = new ScoreModelDownloader(ScoreManager, API)); dependencies.Cache(difficultyCache = new BeatmapDifficultyCache()); AddInternal(difficultyCache); dependencies.Cache(userCache = new UserLookupCache()); AddInternal(userCache); dependencies.Cache(beatmapCache = new BeatmapLookupCache()); AddInternal(beatmapCache); var scorePerformanceManager = new ScorePerformanceCache(); dependencies.Cache(scorePerformanceManager); AddInternal(scorePerformanceManager); dependencies.CacheAs <IRulesetConfigCache>(rulesetConfigCache = new RulesetConfigCache(realm, RulesetStore)); var powerStatus = CreateBatteryInfo(); if (powerStatus != null) { dependencies.CacheAs(powerStatus); } dependencies.Cache(SessionStatics = new SessionStatics()); dependencies.Cache(new OsuColour()); RegisterImportHandler(BeatmapManager); RegisterImportHandler(ScoreManager); RegisterImportHandler(SkinManager); // drop track volume game-wide to leave some head-room for UI effects / samples. // this means that for the time being, gameplay sample playback is louder relative to the audio track, compared to stable. // we may want to revisit this if users notice or complain about the difference (consider this a bit of a trial). Audio.Tracks.AddAdjustment(AdjustableProperty.Volume, globalTrackVolumeAdjust); Beatmap = new NonNullableBindable <WorkingBeatmap>(defaultBeatmap); dependencies.CacheAs <IBindable <WorkingBeatmap> >(Beatmap); dependencies.CacheAs(Beatmap); // add api components to hierarchy. if (API is APIAccess apiAccess) { AddInternal(apiAccess); } AddInternal(spectatorClient); AddInternal(multiplayerClient); AddInternal(rulesetConfigCache); GlobalActionContainer globalBindings; base.Content.Add(new SafeAreaContainer { SafeAreaOverrideEdges = SafeAreaOverrideEdges, RelativeSizeAxes = Axes.Both, Child = CreateScalingContainer().WithChildren(new Drawable[] { (MenuCursorContainer = new MenuCursorContainer { RelativeSizeAxes = Axes.Both }).WithChild(content = new OsuTooltipContainer(MenuCursorContainer.Cursor) { RelativeSizeAxes = Axes.Both }), // to avoid positional input being blocked by children, ensure the GlobalActionContainer is above everything. globalBindings = new GlobalActionContainer(this) }) }); KeyBindingStore = new RealmKeyBindingStore(realm, keyCombinationProvider); KeyBindingStore.Register(globalBindings, RulesetStore.AvailableRulesets); dependencies.Cache(globalBindings); PreviewTrackManager previewTrackManager; dependencies.Cache(previewTrackManager = new PreviewTrackManager(BeatmapManager.BeatmapTrackStore)); Add(previewTrackManager); AddInternal(MusicController = new MusicController()); dependencies.CacheAs(MusicController); Ruleset.BindValueChanged(onRulesetChanged); Beatmap.BindValueChanged(onBeatmapChanged); }
private void load(AudioManager audio, SessionStatics statics) { sampleHover = audio.Samples.Get($@"UI/generic-hover{SampleSet.GetDescription()}"); }
private void load() { try { using (var str = File.OpenRead(typeof(OsuGameBase).Assembly.Location)) VersionHash = str.ComputeMD5Hash(); } catch { // special case for android builds, which can't read DLLs from a packed apk. // should eventually be handled in a better way. VersionHash = $"{Version}-{RuntimeInfo.OS}".ComputeMD5Hash(); } Resources.AddStore(new DllResourceStore(OsuResources.ResourceAssembly)); dependencies.Cache(contextFactory = new DatabaseContextFactory(Storage)); dependencies.Cache(realmFactory = new RealmContextFactory(Storage)); updateThreadState = Host.UpdateThread.State.GetBoundCopy(); updateThreadState.BindValueChanged(updateThreadStateChanged); AddInternal(realmFactory); dependencies.CacheAs(Storage); var largeStore = new LargeTextureStore(Host.CreateTextureLoaderStore(new NamespacedResourceStore <byte[]>(Resources, @"Textures"))); largeStore.AddStore(Host.CreateTextureLoaderStore(new OnlineStore())); dependencies.Cache(largeStore); dependencies.CacheAs(this); dependencies.CacheAs(LocalConfig); InitialiseFonts(); Audio.Samples.PlaybackConcurrency = SAMPLE_CONCURRENCY; runMigrations(); dependencies.Cache(SkinManager = new SkinManager(Storage, contextFactory, Host, Resources, Audio)); dependencies.CacheAs <ISkinSource>(SkinManager); // needs to be done here rather than inside SkinManager to ensure thread safety of CurrentSkinInfo. SkinManager.ItemRemoved.BindValueChanged(weakRemovedInfo => { if (weakRemovedInfo.NewValue.TryGetTarget(out var removedInfo)) { Schedule(() => { // check the removed skin is not the current user choice. if it is, switch back to default. if (removedInfo.ID == SkinManager.CurrentSkinInfo.Value.ID) { SkinManager.CurrentSkinInfo.Value = SkinInfo.Default; } }); } }); EndpointConfiguration endpoints = UseDevelopmentServer ? (EndpointConfiguration) new DevelopmentEndpointConfiguration() : new ProductionEndpointConfiguration(); MessageFormatter.WebsiteRootUrl = endpoints.WebsiteRootUrl; dependencies.CacheAs(API ??= new APIAccess(LocalConfig, endpoints, VersionHash)); dependencies.CacheAs(spectatorClient = new OnlineSpectatorClient(endpoints)); dependencies.CacheAs(multiplayerClient = new OnlineMultiplayerClient(endpoints)); var defaultBeatmap = new DummyWorkingBeatmap(Audio, Textures); dependencies.Cache(RulesetStore = new RulesetStore(contextFactory, Storage)); dependencies.Cache(fileStore = new FileStore(contextFactory, Storage)); // ordering is important here to ensure foreign keys rules are not broken in ModelStore.Cleanup() dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, () => BeatmapManager, Storage, API, contextFactory, Scheduler, Host, () => difficultyCache, LocalConfig)); dependencies.Cache(BeatmapManager = new BeatmapManager(Storage, contextFactory, RulesetStore, API, Audio, Resources, Host, defaultBeatmap, true)); // this should likely be moved to ArchiveModelManager when another case appears where it is necessary // to have inter-dependent model managers. this could be obtained with an IHasForeign<T> interface to // allow lookups to be done on the child (ScoreManager in this case) to perform the cascading delete. List <ScoreInfo> getBeatmapScores(BeatmapSetInfo set) { var beatmapIds = BeatmapManager.QueryBeatmaps(b => b.BeatmapSetInfoID == set.ID).Select(b => b.ID).ToList(); return(ScoreManager.QueryScores(s => beatmapIds.Contains(s.Beatmap.ID)).ToList()); } BeatmapManager.ItemRemoved.BindValueChanged(i => { if (i.NewValue.TryGetTarget(out var item)) { ScoreManager.Delete(getBeatmapScores(item), true); } }); BeatmapManager.ItemUpdated.BindValueChanged(i => { if (i.NewValue.TryGetTarget(out var item)) { ScoreManager.Undelete(getBeatmapScores(item), true); } }); dependencies.Cache(difficultyCache = new BeatmapDifficultyCache()); AddInternal(difficultyCache); dependencies.Cache(userCache = new UserLookupCache()); AddInternal(userCache); var scorePerformanceManager = new ScorePerformanceCache(); dependencies.Cache(scorePerformanceManager); AddInternal(scorePerformanceManager); migrateDataToRealm(); dependencies.Cache(rulesetConfigCache = new RulesetConfigCache(realmFactory, RulesetStore)); var powerStatus = CreateBatteryInfo(); if (powerStatus != null) { dependencies.CacheAs(powerStatus); } dependencies.Cache(SessionStatics = new SessionStatics()); dependencies.Cache(new OsuColour()); RegisterImportHandler(BeatmapManager); RegisterImportHandler(ScoreManager); RegisterImportHandler(SkinManager); // drop track volume game-wide to leave some head-room for UI effects / samples. // this means that for the time being, gameplay sample playback is louder relative to the audio track, compared to stable. // we may want to revisit this if users notice or complain about the difference (consider this a bit of a trial). Audio.Tracks.AddAdjustment(AdjustableProperty.Volume, globalTrackVolumeAdjust); Beatmap = new NonNullableBindable <WorkingBeatmap>(defaultBeatmap); dependencies.CacheAs <IBindable <WorkingBeatmap> >(Beatmap); dependencies.CacheAs(Beatmap); fileStore.Cleanup(); // add api components to hierarchy. if (API is APIAccess apiAccess) { AddInternal(apiAccess); } AddInternal(spectatorClient); AddInternal(multiplayerClient); AddInternal(rulesetConfigCache); GlobalActionContainer globalBindings; var mainContent = new Drawable[] { MenuCursorContainer = new MenuCursorContainer { RelativeSizeAxes = Axes.Both }, // to avoid positional input being blocked by children, ensure the GlobalActionContainer is above everything. globalBindings = new GlobalActionContainer(this) }; MenuCursorContainer.Child = content = new OsuTooltipContainer(MenuCursorContainer.Cursor) { RelativeSizeAxes = Axes.Both }; base.Content.Add(CreateScalingContainer().WithChildren(mainContent)); KeyBindingStore = new RealmKeyBindingStore(realmFactory); KeyBindingStore.Register(globalBindings, RulesetStore.AvailableRulesets); dependencies.Cache(globalBindings); PreviewTrackManager previewTrackManager; dependencies.Cache(previewTrackManager = new PreviewTrackManager()); Add(previewTrackManager); AddInternal(MusicController = new MusicController()); dependencies.CacheAs(MusicController); Ruleset.BindValueChanged(onRulesetChanged); }
private void load(AudioManager audio, SessionStatics statics) { sampleHover = audio.Samples.Get($@"UI/{SampleSet.GetDescription()}-hover") ?? audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-hover"); }
private void load(AudioManager audio, SessionStatics statics) { lastPlaybackTime = statics.GetBindable <double?>(Static.LastHoverSoundPlaybackTime); sampleHover = audio.Samples.Get($@"UI/generic-hover{SampleSet.GetDescription()}"); }