示例#1
0
        public void BenchmarkDirectPropertyRead()
        {
            realm.Run(r =>
            {
                var beatmapSet = r.All <BeatmapSetInfo>().First();

                for (int i = 0; i < ReadsPerFetch; i++)
                {
                    string _ = beatmapSet.Beatmaps.First().Hash;
                }
            });
        }
示例#2
0
        private void load(RealmAccess realm)
        {
            string rulesetName = Ruleset?.ShortName;

            var bindings = realm.Run(r => r.All <RealmKeyBinding>()
                                     .Where(b => b.RulesetName == rulesetName && b.Variant == variant)
                                     .Detach());

            foreach (var defaultGroup in Defaults.GroupBy(d => d.Action))
            {
                int intKey = (int)defaultGroup.Key;

                // one row per valid action.
                Add(new KeyBindingRow(defaultGroup.Key, bindings.Where(b => b.ActionInt.Equals(intKey)).ToList())
                {
                    AllowMainMouseButtons = Ruleset != null,
                    Defaults = defaultGroup.Select(d => d.KeyCombination)
                });
            }

            Add(new ResetButton
            {
                Action = () => Children.OfType <KeyBindingRow>().ForEach(k => k.RestoreDefaults())
            });
        }
示例#3
0
        public void Hide(BeatmapInfo beatmapInfo)
        {
            realm.Run(r =>
            {
                using (var transaction = r.BeginWrite())
                {
                    if (!beatmapInfo.IsManaged)
                    {
                        beatmapInfo = r.Find <BeatmapInfo>(beatmapInfo.ID);
                    }

                    beatmapInfo.Hidden = true;
                    transaction.Commit();
                }
            });
        }
示例#4
0
        public void SelectRandomSkin()
        {
            realm.Run(r =>
            {
                // choose from only user skins, removing the current selection to ensure a new one is chosen.
                var randomChoices = r.All <SkinInfo>().Where(s => !s.DeletePending && s.ID != CurrentSkinInfo.Value.ID).ToArray();

                if (randomChoices.Length == 0)
                {
                    CurrentSkinInfo.Value = Skinning.DefaultSkin.CreateInfo().ToLiveUnmanaged();
                    return;
                }

                var chosen = randomChoices.ElementAt(RNG.Next(0, randomChoices.Length));

                CurrentSkinInfo.Value = chosen.ToLive(realm);
            });
        }
示例#5
0
        public IReadOnlyList <string> GetReadableKeyCombinationsFor(GlobalAction globalAction)
        {
            List <string> combinations = new List <string>();

            realm.Run(context =>
            {
                foreach (var action in context.All <RealmKeyBinding>().Where(b => string.IsNullOrEmpty(b.RulesetName) && (GlobalAction)b.ActionInt == globalAction))
                {
                    string str = keyCombinationProvider.GetReadableString(action.KeyCombination);

                    // even if found, the readable string may be empty for an unbound action.
                    if (str.Length > 0)
                    {
                        combinations.Add(str);
                    }
                }
            });

            return(combinations);
        }
示例#6
0
        public override void SetUp()
        {
            storage = new TemporaryNativeStorage("realm-benchmark");
            storage.DeleteDirectory(string.Empty);

            realm = new RealmAccess(storage, "client");

            realm.Run(r =>
            {
                realm.Write(c => c.Add(TestResources.CreateTestBeatmapSetInfo(rulesets: new[] { new OsuRuleset().RulesetInfo })));
            });

            updateThread = new UpdateThread(() => { }, null);
            updateThread.Start();
        }
        private void load(OsuConfigManager config, Framework.Game game, RealmAccess realm, IAPIProvider api)
        {
            // prevent user from changing beatmap while the intro is still running.
            beatmap = Beatmap.BeginLease(false);

            MenuVoice = config.GetBindable <bool>(OsuSetting.MenuVoice);
            MenuMusic = config.GetBindable <bool>(OsuSetting.MenuMusic);

            if (api.LocalUser.Value.IsSupporter)
            {
                AddInternal(skinnableSeeya = new SkinnableSound(new SampleInfo(SeeyaSampleName)));
            }
            else
            {
                seeya = audio.Samples.Get(SeeyaSampleName);
            }

            // if the user has requested not to play theme music, we should attempt to find a random beatmap from their collection.
            if (!MenuMusic.Value)
            {
                realm.Run(r =>
                {
                    var usableBeatmapSets = r.All <BeatmapSetInfo>().Where(s => !s.DeletePending && !s.Protected).AsRealmCollection();

                    int setCount = usableBeatmapSets.Count;

                    if (setCount > 0)
                    {
                        var found = usableBeatmapSets[RNG.Next(0, setCount - 1)].Beatmaps.FirstOrDefault();

                        if (found != null)
                        {
                            initialBeatmap = beatmaps.GetWorkingBeatmap(found);
                        }
                    }
                });
            }

            // we generally want a song to be playing on startup, so use the intro music even if a user has specified not to if no other track is available.
            if (initialBeatmap == null)
            {
                // Intro beatmaps are generally made using the osu! ruleset.
                // It might not be present in test projects for other rulesets.
                bool osuRulesetPresent = rulesets.GetRuleset(0) != null;

                if (!loadThemedIntro() && osuRulesetPresent)
                {
                    // if we detect that the theme track or beatmap is unavailable this is either first startup or things are in a bad state.
                    // this could happen if a user has nuked their files store. for now, reimport to repair this.
                    var import = beatmaps.Import(new ZipArchiveReader(game.Resources.GetStream($"Tracks/{BeatmapFile}"), BeatmapFile)).GetResultSafely();

                    import?.PerformWrite(b => b.Protected = true);

                    loadThemedIntro();
                }
            }

            bool loadThemedIntro()
            {
                var setInfo = beatmaps.QueryBeatmapSet(b => b.Protected && b.Hash == BeatmapHash);

                if (setInfo == null)
                {
                    return(false);
                }

                setInfo.PerformRead(s =>
                {
                    if (s.Beatmaps.Count == 0)
                    {
                        return;
                    }

                    initialBeatmap = beatmaps.GetWorkingBeatmap(s.Beatmaps.First());
                });

                return(UsingThemedIntro = initialBeatmap != null);
            }
        }
示例#8
0
        public virtual Live <TModel>?Import(TModel item, ArchiveReader?archive = null, bool lowPriority = false, CancellationToken cancellationToken = default)
        {
            return(Realm.Run(realm =>
            {
                cancellationToken.ThrowIfCancellationRequested();

                bool checkedExisting = false;
                TModel?existing = null;

                if (archive != null && !HasCustomHashFunction)
                {
                    // this is a fast bail condition to improve large import performance.
                    item.Hash = computeHashFast(archive);

                    checkedExisting = true;
                    existing = CheckForExisting(item, realm);

                    if (existing != null)
                    {
                        // bare minimum comparisons
                        //
                        // note that this should really be checking filesizes on disk (of existing files) for some degree of sanity.
                        // or alternatively doing a faster hash check. either of these require database changes and reprocessing of existing files.
                        if (CanSkipImport(existing, item) &&
                            getFilenames(existing.Files).SequenceEqual(getShortenedFilenames(archive).Select(p => p.shortened).OrderBy(f => f)) &&
                            checkAllFilesExist(existing))
                        {
                            LogForModel(item, @$ "Found existing (optimised) {HumanisedModelName} for {item} (ID {existing.ID}) – skipping import.");

                            using (var transaction = realm.BeginWrite())
                            {
                                existing.DeletePending = false;
                                transaction.Commit();
                            }

                            return existing.ToLive(Realm);
                        }

                        LogForModel(item, @"Found existing (optimised) but failed pre-check.");
                    }
                }

                try
                {
                    LogForModel(item, @"Beginning import...");

                    // TODO: do we want to make the transaction this local? not 100% sure, will need further investigation.
                    using (var transaction = realm.BeginWrite())
                    {
                        if (archive != null)
                        {
                            // TODO: look into rollback of file additions (or delayed commit).
                            item.Files.AddRange(createFileInfos(archive, Files, realm));
                        }

                        item.Hash = ComputeHash(item);

                        // TODO: we may want to run this outside of the transaction.
                        Populate(item, archive, realm, cancellationToken);

                        if (!checkedExisting)
                        {
                            existing = CheckForExisting(item, realm);
                        }

                        if (existing != null)
                        {
                            if (CanReuseExisting(existing, item))
                            {
                                LogForModel(item, @$ "Found existing {HumanisedModelName} for {item} (ID {existing.ID}) – skipping import.");

                                existing.DeletePending = false;
                                transaction.Commit();

                                return existing.ToLive(Realm);
                            }

                            LogForModel(item, @"Found existing but failed re-use check.");

                            existing.DeletePending = true;
                        }

                        PreImport(item, realm);

                        // import to store
                        realm.Add(item);

                        transaction.Commit();
                    }

                    LogForModel(item, @"Import successfully completed!");
                }
                catch (Exception e)
                {
                    if (!(e is TaskCanceledException))
                    {
                        LogForModel(item, @"Database import or population failed and has been rolled back.", e);
                    }

                    throw;
                }

                return (Live <TModel>?)item.ToLive(Realm);
            }));
        }
示例#9
0
 /// <summary>
 /// Perform a lookup query on available <see cref="ScoreInfo"/>s.
 /// </summary>
 /// <param name="query">The query.</param>
 /// <returns>The first result for the provided query, or null if no results were found.</returns>
 public ScoreInfo Query(Expression <Func <ScoreInfo, bool> > query)
 {
     return(realm.Run(r => r.All <ScoreInfo>().FirstOrDefault(query)?.Detach()));
 }