Пример #1
0
        /// <summary>
        ///     指定されたノードをフォーカス(選択)する。
        /// </summary>
        /// <remarks>
        ///     必要に応じて、<see cref="フォーカスホルダ"/>, <see cref="フォーカスリスト"/> も変更される。
        /// </remarks>
        /// <return>結果としてフォーカスノードが変わったら true 。</return>
        public bool フォーカスする(Node focusNode)
        {
            var 更前のノード = this.フォーカスノード;

            if (focusNode == 更前のノード)
            {
                return(false);   // 同一
            }
            // ホルダを変更。
            this.フォーカスホルダ = focusNode.親ノード ??
                            throw new Exception("ルートノードをフォーカスすることはできません。");

            // チェック。
            if (!this.フォーカスホルダ.子ノードリスト.SelectItem(focusNode) ||
                this.フォーカスホルダ.子ノードリスト.SelectedItem is null)
            {
                throw new Exception("フォーカスノードの選択に失敗しました。");
            }

            return(true);
        }
Пример #2
0
        /// <summary>
        ///     1つのフォルダに対して検索と構築を行う。
        /// </summary>
        /// <param name="基点フォルダパス">検索フォルダの絶対パス。</param>
        /// <param name="親ノード">ノードは、このノードの子ノードとして構築される。</param>
        /// <param name="boxdefが有効">true にすると、フォルダ内の box.def が有効になる。false にすると box.def を無視する。</param>
        private void _構築する(VariablePath 基点フォルダパス, BoxNode 親ノード, bool boxdefが有効 = true)
        {
            #region " 基点フォルダが存在しない場合は無視。"
            //----------------
            if (!(Directory.Exists(基点フォルダパス.数なしパス)))
            {
                Log.WARNING($"指定されたフォルダが存在しません。無視します。[{基点フォルダパス.変数付きパス}]");
                return;
            }
            //----------------
            #endregion

            // 一時リスト。作成したノードをいったんこのノードリストに格納し、あとでまとめて曲ツリーに登録する。
            var 追加ノードリスト = new List <Node>();

            // 各準備。
            var  dirInfo     = new DirectoryInfo(基点フォルダパス.数なしパス);
            var  boxDefPath  = new VariablePath(Path.Combine(基点フォルダパス.数なしパス, @"box.def"));
            var  setDefPath  = new VariablePath(Path.Combine(基点フォルダパス.数なしパス, @"set.def"));
            bool サブフォルダを検索する = true;

            if (boxdefが有効 && File.Exists(boxDefPath.数なしパス))
            {
                #region " (A) このフォルダに box.def がある → BOXノードを作成し、子ノードリストを再帰的に構築する。"
                //----------------
                try
                {
                    // box.defを読み込んでBOXノードを作成する。
                    var boxDef  = new BoxDef(boxDefPath);
                    var boxNode = new BoxNode(boxDef);
                    追加ノードリスト.Add(boxNode);

                    // BOXノードの子ノードリストの先頭に「戻る」と「ランダムセレクト」を追加する。
                    boxNode.子ノードリスト.Add(new BackNode()
                    {
                        親ノード = boxNode
                    });
                    boxNode.子ノードリスト.Add(new RandomSelectNode()
                    {
                        親ノード = boxNode
                    });

                    // このフォルダを対象として再帰的に構築する。ただし box.def は無効とする。
                    // 構築結果のノードリストは、BOXノードの子として付与される。
                    this._構築する(基点フォルダパス, boxNode, boxdefが有効: false);

                    // box.def があった場合、サブフォルダは検索しない。
                    サブフォルダを検索する = false;
                }
                catch (Exception e)
                {
                    Log.ERROR($"box.def に対応するノードの生成に失敗しました。[{boxDefPath.変数付きパス}][{Folder.絶対パスをフォルダ変数付き絶対パスに変換して返す( e.Message )}]");
                }
                //----------------
                #endregion
            }
            else if (File.Exists(setDefPath.数なしパス))
            {
                #region " (B) このフォルダに set.def がある → その内容でノードを作成する。"
                //----------------
                try
                {
                    // set.def を読み込む。
                    var setDef = new SetDef(setDefPath);

                    // set.def 内のすべてのブロックについて、Song と SongNode を作成する。
                    foreach (var block in setDef.Blocks)
                    {
                        // set.def のブロックから Song を生成する。
                        var song = new Song(block, dirInfo.FullName);

                        // L1~L5が1つ以上有効なら、SongNode を生成して登録する。
                        if (song.譜面リスト.Any((score) => null != score))
                        {
                            追加ノードリスト.Add(new SongNode(song));
                        }
                    }

                    // set.def があった場合、サブフォルダは検索しない。
                    サブフォルダを検索する = false;
                }
                catch (Exception e)
                {
                    Log.ERROR($"set.def からのノードの生成に失敗しました。[{setDefPath.変数付きパス}][{Folder.絶対パスをフォルダ変数付き絶対パスに変換して返す( e.Message )}]");
                }
                //----------------
                #endregion
            }
            else
            {
                #region " (C) box.def も set.def もない → このフォルダにあるすべての譜面ファイルを検索してノードを作成する。"
                //----------------
                var 対応する拡張子 = new[] { ".sstf", ".dtx", ".gda", ".g2d", "bms", "bme" };

                // 譜面ファイルを検索する。曲ファイルは、対応する拡張子を持つファイルである。
                var fileInfos = dirInfo.GetFiles("*.*", SearchOption.TopDirectoryOnly)
                                .Where((fileInfo) => 対応する拡張子.Any(拡張子名 => (Path.GetExtension(fileInfo.Name).ToLower() == 拡張子名)));

                // 列挙されたすべての譜面ファイルについて……
                foreach (var fileInfo in fileInfos)
                {
                    var path = new VariablePath(fileInfo.FullName);
                    try
                    {
                        // 1つの譜面を持つ Song を生成する。
                        var song = new Song(path);
                        追加ノードリスト.Add(new SongNode(song));
                    }
                    catch (Exception e)
                    {
                        Log.ERROR($"SongNode の生成に失敗しました。[{path.変数付きパス}][{Folder.絶対パスをフォルダ変数付き絶対パスに変換して返す( e.Message )}]");
                    }

                    // 続けて、サブフォルダも検索する。
                    サブフォルダを検索する = true;
                }
                //----------------
                #endregion
            }

            #region " 作成した一時リストを親ノードの子として正式に追加する。"
            //----------------
            foreach (var node in 追加ノードリスト)
            {
                // 親ノードの子として登録する。

                親ノード.子ノードリスト.Add(node);
                node.親ノード = 親ノード;


                // SongNode なら Score[] を全譜面リストにも追加する。

                if (node is SongNode snode)
                {
                    for (int i = 0; i < 5; i++)
                    {
                        if (null != snode.曲.譜面リスト[i])
                        {
                            Global.App.全譜面リスト[snode.曲.譜面リスト[i] !.譜面.ScorePath] = snode.曲.譜面リスト[i] !;
Пример #3
0
        private long _進捗カウンタ;   // Interlocked でアクセスすること


        /// <summary>
        ///     1つのフォルダに対して検索と構築を行う。
        ///     同時に、全譜面リストと全曲リストも構築する。
        /// </summary>
        /// <param name="基点フォルダパス">検索フォルダの絶対パス。</param>
        /// <param name="親ノード">ノードは、このノードの子ノードとして構築される。</param>
        /// <param name="boxdefが有効">true にすると、フォルダ内の box.def が有効になる。false にすると box.def を無視する。</param>
        private void _構築する(VariablePath 基点フォルダパス, BoxNode 親ノード, bool boxdefが有効 = true)
        {
            #region " 基点フォルダが存在しない場合やアクセスできない場合は無視。"
            //----------------
            if (!(Directory.Exists(基点フォルダパス.数なしパス)))
            {
                Log.WARNING($"指定されたフォルダが存在しません。無視します。[{基点フォルダパス.変数付きパス}]");
                return;
            }

            try
            {
                Directory.GetFiles(基点フォルダパス.数なしパス);
            }
            catch (UnauthorizedAccessException)
            {
                Log.ERROR($"アクセスできないフォルダです。無視します。[{基点フォルダパス.変数付きパス}]");
                return;
            }
            //----------------
            #endregion

            // 一時リスト。作成したノードをいったんこのノードリストに格納し、あとでまとめて曲ツリーに登録する。
            var 追加ノードリスト = new List <Node>();


            // (1) フォルダ内のファイルからノードを作成

            // set.def/box.def ファイルの有無により処理分岐。
            var  dirInfo     = new DirectoryInfo(基点フォルダパス.数なしパス);
            var  boxDefPath  = new VariablePath(Path.Combine(基点フォルダパス.数なしパス, @"box.def"));
            var  setDefPath  = new VariablePath(Path.Combine(基点フォルダパス.数なしパス, @"set.def"));
            bool サブフォルダを検索する = true;

            if (boxdefが有効 && File.Exists(boxDefPath.数なしパス))
            {
                #region " (A) このフォルダに box.def がある → BOXノードを作成し、子ノードリストを再帰的に構築する。"
                //----------------
                // box.defを読み込んでBOXノードを作成する。
                var boxDef  = new BoxDef(boxDefPath);
                var boxNode = new BoxNode(boxDef);
                追加ノードリスト.Add(boxNode);

                // BOXノードの子ノードリストの先頭に「戻る」と「ランダムセレクト」を追加する。
                boxNode.子ノードリスト.Add(new BackNode()
                {
                    親ノード = boxNode
                });
                boxNode.子ノードリスト.Add(new RandomSelectNode()
                {
                    親ノード = boxNode
                });

                // このフォルダを対象として再帰的に構築する。ただし box.def は無効とする。
                // 親ノードとしてBOXノードを指定しているので、構築結果のノードはBOXノードの子として付与される。
                this._構築する(基点フォルダパス, boxNode, boxdefが有効: false);

                // box.def があった場合、サブフォルダは検索しない。
                サブフォルダを検索する = false;
                //----------------
                #endregion
            }
            else if (File.Exists(setDefPath.数なしパス))
            {
                #region " (B) このフォルダに set.def がある → その内容で任意個のノードを作成する。"
                //----------------
                Interlocked.Increment(ref this._進捗カウンタ);

                // set.def を読み込む。
                var setDef = new SetDef(setDefPath);

                // set.def 内のすべてのブロックについて、Song と SongNode を作成する。
                var list = new List <Node>(5);
                foreach (var block in setDef.Blocks)
                {
                    // set.def のブロックから Song を生成する。
                    var song = new Song(block, dirInfo.FullName);

                    // L1~L5が1つ以上有効なら、このブロックに対応する SongNode を生成する。
                    if (song.譜面リスト.Any((score) => null != score))
                    {
                        list.Add(new SongNode(song));
                    }
                }
                // 1つ以上の SongNode がある(1つ以上の有効なブロックがある)場合のみ登録する。
                if (0 < list.Count)
                {
                    追加ノードリスト.AddRange(list);
                }

                // set.def があった場合、サブフォルダは検索しない。
                サブフォルダを検索する = false;
                //----------------
                #endregion
            }
            else
            {
                #region " (C) box.def も set.def もない → このフォルダにあるすべての譜面ファイルを検索してノードを作成する。"
                //----------------
                var 対応する拡張子 = new[] { ".sstf", ".dtx", ".gda", ".g2d", "bms", "bme" };

                // 譜面ファイルを検索する。曲ファイルは、対応する拡張子を持つファイルである。
                var fileInfos = dirInfo.GetFiles("*.*", SearchOption.TopDirectoryOnly)
                                .Where((fileInfo) => 対応する拡張子.Any(拡張子名 => (Path.GetExtension(fileInfo.Name).ToLower() == 拡張子名)));

                // 列挙されたすべての譜面ファイルについて……
                foreach (var fileInfo in fileInfos)
                {
                    Interlocked.Increment(ref this._進捗カウンタ);

                    var path = new VariablePath(fileInfo.FullName);
                    try
                    {
                        // 1つの譜面を持つ Song を生成する。
                        var song = new Song(path);
                        追加ノードリスト.Add(new SongNode(song));
                    }
                    catch (Exception e)
                    {
                        Log.ERROR($"SongNode の生成に失敗しました。[{path.変数付きパス}][{Folder.絶対パスをフォルダ変数付き絶対パスに変換して返す( e.Message )}]");
                    }

                    // 続けて、サブフォルダも検索する。
                    サブフォルダを検索する = true;
                }
                //----------------
                #endregion
            }


            #region " 作成した一時リストを親ノードの子として正式に追加する。"
            //----------------
            foreach (var node in 追加ノードリスト)
            {
                // 親ノードの子として登録する。
                親ノード.子ノードリスト.Add(node);
                node.親ノード = 親ノード;

                // SongNode なら、全曲リストと全譜面リストにも追加する。
                if (node is SongNode snode)
                {
                    Global.App.全曲リスト.Add(snode.曲);

                    for (int i = 0; i < 5; i++)
                    {
                        if (null != snode.曲.譜面リスト[i])
                        {
                            Global.App.全譜面リスト.Add(snode.曲.譜面リスト[i] !);
                        }
                    }
                }
            }
            //----------------
            #endregion


            // (2) サブフォルダを検索

            if (サブフォルダを検索する)
            {
                // すべてのサブフォルダについて……
                foreach (var di in dirInfo.GetDirectories())
                {
                    if (di.Name.StartsWith("DTXFiles.", StringComparison.OrdinalIgnoreCase))
                    {
                        #region " (A) サブフォルダが DTXFiles. で始まるBOXである → BOXノードを追加し、サブフォルダを再帰的に検索する。"
                        //----------------
                        // BOXノードを作成し、ツリーに登録する。
                        var boxNode = new BoxNode(di.Name[("DTXFiles.".Length)..])