OSDN Git Service

d1fd55c412aefc928122ae835365c92cb1b9893b
[dtxmania/dtxmania.git] / DTXManiaプロジェクト / コード / ステージ / 02.タイトル / CEnumSongs.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Text;\r
4 using System.Diagnostics;\r
5 using System.Runtime.InteropServices;\r
6 using System.IO;\r
7 using System.Threading;\r
8 using System.Runtime.Serialization.Formatters.Binary;\r
9 using SharpDX;\r
10 using SharpDX.Direct3D9;\r
11 using FDK;\r
12 using SampleFramework;\r
13 \r
14 namespace DTXMania\r
15 {\r
16         internal class CEnumSongs             // #27060 2011.2.7 yyagi 曲リストを取得するクラス\r
17         {                         // ファイルキャッシュ(songslist.db)からの取得と、ディスクからの取得を、この一つのクラスに集約。\r
18 \r
19                 public CSongs管理 Songs管理           // 曲の探索結果はこのSongs管理に読み込まれる\r
20                 {\r
21                         get;\r
22                         private set;\r
23                 }\r
24 \r
25                 public bool IsSongListEnumCompletelyDone    // 曲リスト探索と、実際の曲リストへの反映が完了した?\r
26                 {\r
27                         get\r
28                         {\r
29                                 return (this.state == DTXEnumState.CompletelyDone);\r
30                         }\r
31                 }\r
32                 public bool IsEnumerating\r
33                 {\r
34                         get\r
35                         {\r
36                                 if (thDTXFileEnumerate == null)\r
37                                 {\r
38                                         return false;\r
39                                 }\r
40                                 return thDTXFileEnumerate.IsAlive;\r
41                         }\r
42                 }\r
43                 public bool IsSongListEnumerated        // 曲リスト探索が完了したが、実際の曲リストへの反映はまだ?\r
44                 {\r
45                         get\r
46                         {\r
47                                 return (this.state == DTXEnumState.Enumeratad);\r
48                         }\r
49                 }\r
50                 public bool IsSongListEnumStarted       // 曲リスト探索開始後?(探索完了も含む)\r
51                 {\r
52                         get\r
53                         {\r
54                                 return (this.state != DTXEnumState.None);\r
55                         }\r
56                 }\r
57                 public void SongListEnumCompletelyDone()\r
58                 {\r
59                         this.state = DTXEnumState.CompletelyDone;\r
60                         this.Songs管理 = null;            // GCはOSに任せる\r
61                 }\r
62                 public bool IsSlowdown              // #PREMOVIE再生中は検索負荷を落とす\r
63                 {\r
64                         get\r
65                         {\r
66                                 return this.Songs管理.bIsSlowdown;\r
67                         }\r
68                         set\r
69                         {\r
70                                 this.Songs管理.bIsSlowdown = value;\r
71                         }\r
72                 }\r
73 \r
74                 public void ChangeEnumeratePriority(ThreadPriority tp)\r
75                 {\r
76                         if (this.thDTXFileEnumerate != null && this.thDTXFileEnumerate.IsAlive == true)\r
77                         {\r
78                                 this.thDTXFileEnumerate.Priority = tp;\r
79                         }\r
80                 }\r
81                 private readonly string strPathSongsDB = CDTXMania.Instance.strEXEのあるフォルダ + "songs.db";\r
82                 private readonly string strPathSongList = CDTXMania.Instance.strEXEのあるフォルダ + "songlist.db";\r
83 \r
84                 public Thread thDTXFileEnumerate\r
85                 {\r
86                         get;\r
87                         private set;\r
88                 }\r
89                 private enum DTXEnumState\r
90                 {\r
91                         None,\r
92                         Ongoing,\r
93                         Suspended,\r
94                         Enumeratad,       // 探索完了、現在の曲リストに未反映\r
95                         CompletelyDone      // 探索完了、現在の曲リストに反映完了\r
96                 }\r
97                 private DTXEnumState state = DTXEnumState.None;\r
98 \r
99 \r
100                 /// <summary>\r
101                 /// Constractor\r
102                 /// </summary>\r
103                 public CEnumSongs()\r
104                 {\r
105                         this.Songs管理 = new CSongs管理();\r
106                 }\r
107 \r
108                 public void Init(List<Cスコア> ls, int n)\r
109                 {\r
110                         if (state == DTXEnumState.None)\r
111                         {\r
112                                 this.Songs管理.listSongsDB = ls;\r
113                                 this.Songs管理.nSongsDBから取得できたスコア数 = n;\r
114                         }\r
115                 }\r
116 \r
117                 /// <summary>\r
118                 /// 曲リストのキャッシュ(songlist.db)取得スレッドの開始\r
119                 /// </summary>\r
120                 public void StartEnumFromCache()\r
121                 {\r
122                         this.thDTXFileEnumerate = new Thread(new ThreadStart(this.t曲リストの構築1));\r
123                         this.thDTXFileEnumerate.Name = "曲リストの構築";\r
124                         this.thDTXFileEnumerate.IsBackground = true;\r
125                         this.thDTXFileEnumerate.Start();\r
126                 }\r
127 \r
128                 /// <summary>\r
129                 /// \r
130                 /// </summary>\r
131                 public delegate void AsyncDelegate();\r
132 \r
133                 /// <summary>\r
134                 /// 曲検索スレッドの開始\r
135                 /// </summary>\r
136                 public void StartEnumFromDisk()\r
137                 {\r
138                         if (state == DTXEnumState.None || state == DTXEnumState.CompletelyDone)\r
139                         {\r
140                                 Trace.TraceInformation("★曲データ検索スレッドを起動しました。");\r
141                                 lock (this)\r
142                                 {\r
143                                         state = DTXEnumState.Ongoing;\r
144                                 }\r
145                                 // this.autoReset = new AutoResetEvent( true );\r
146 \r
147                                 if (this.Songs管理 == null)   // Enumerating Songs完了後、CONFIG画面から再スキャンしたときにこうなる\r
148                                 {\r
149                                         this.Songs管理 = new CSongs管理();\r
150                                 }\r
151                                 this.thDTXFileEnumerate = new Thread(new ThreadStart(this.t曲リストの構築2));\r
152                                 this.thDTXFileEnumerate.Name = "曲リストの構築";\r
153                                 this.thDTXFileEnumerate.IsBackground = true;\r
154                                 this.thDTXFileEnumerate.Priority = System.Threading.ThreadPriority.Lowest;\r
155                                 this.thDTXFileEnumerate.Start();\r
156                         }\r
157                 }\r
158 \r
159 \r
160                 /// <summary>\r
161                 /// 曲探索スレッドのサスペンド\r
162                 /// </summary>\r
163                 public void Suspend()\r
164                 {\r
165                         if (this.state != DTXEnumState.CompletelyDone &&\r
166                                 ((thDTXFileEnumerate.ThreadState & (System.Threading.ThreadState.Background)) != 0))\r
167                         {\r
168                                 // this.thDTXFileEnumerate.Suspend();           // obsoleteにつき使用中止\r
169                                 this.Songs管理.bIsSuspending = true;\r
170                                 this.state = DTXEnumState.Suspended;\r
171                                 Trace.TraceInformation("★曲データ検索スレッドを中断しました。");\r
172                         }\r
173                 }\r
174 \r
175                 /// <summary>\r
176                 /// 曲探索スレッドのレジューム\r
177                 /// </summary>\r
178                 public void Resume()\r
179                 {\r
180                         if (this.state == DTXEnumState.Suspended)\r
181                         {\r
182                                 if ((this.thDTXFileEnumerate.ThreadState & (System.Threading.ThreadState.WaitSleepJoin | System.Threading.ThreadState.StopRequested)) != 0) //\r
183                                 {\r
184                                         // this.thDTXFileEnumerate.Resume();    // obsoleteにつき使用中止\r
185                                         this.Songs管理.bIsSuspending = false;\r
186                                         this.Songs管理.AutoReset.Set();\r
187                                         this.state = DTXEnumState.Ongoing;\r
188                                         Trace.TraceInformation("★曲データ検索スレッドを再開しました。");\r
189                                 }\r
190                         }\r
191                 }\r
192 \r
193                 /// <summary>\r
194                 /// 曲探索スレッドにサスペンド指示を出してから、本当にサスペンド状態に遷移するまでの間、ブロックする\r
195                 /// 500ms * 10回=5秒でタイムアウトし、サスペンド完了して無くてもブロック解除する\r
196                 /// </summary>\r
197                 public void WaitUntilSuspended()\r
198                 {\r
199                         // 曲検索が一時中断されるまで待機\r
200                         for (int i = 0; i < 10; i++)\r
201                         {\r
202                                 if (this.state == DTXEnumState.CompletelyDone ||\r
203                                         (thDTXFileEnumerate.ThreadState & (System.Threading.ThreadState.WaitSleepJoin | System.Threading.ThreadState.Background | System.Threading.ThreadState.Stopped)) != 0)\r
204                                 {\r
205                                         break;\r
206                                 }\r
207                                 Trace.TraceInformation("★曲データ検索スレッドの中断待ちです: {0}", this.thDTXFileEnumerate.ThreadState.ToString());\r
208                                 Thread.Sleep(500);\r
209                         }\r
210 \r
211                 }\r
212 \r
213                 /// <summary>\r
214                 /// 曲探索スレッドを強制終了する\r
215                 /// </summary>\r
216                 public void Abort()\r
217                 {\r
218                         if (thDTXFileEnumerate != null)\r
219                         {\r
220                                 thDTXFileEnumerate.Abort();\r
221                                 thDTXFileEnumerate = null;\r
222                                 this.state = DTXEnumState.None;\r
223 \r
224                                 this.Songs管理 = null;          // Songs管理を再初期化する (途中まで作った曲リストの最後に、一から重複して追記することにならないようにする。)\r
225                                 this.Songs管理 = new CSongs管理();\r
226                         }\r
227                 }\r
228 \r
229 \r
230 \r
231                 /// <summary>\r
232                 /// songlist.dbからの曲リスト構築\r
233                 /// </summary>\r
234                 public void t曲リストの構築1()\r
235                 {\r
236                         // !注意!\r
237                         // 本メソッドは別スレッドで動作するが、プラグイン側でカレントディレクトリを変更しても大丈夫なように、\r
238                         // すべてのファイルアクセスは「絶対パス」で行うこと。(2010.9.16)\r
239                         // 構築が完了したら、DTXEnumerateState state を DTXEnumerateState.Done にすること。(2012.2.9)\r
240                         DateTime now = DateTime.Now;\r
241 \r
242                         try\r
243                         {\r
244                                 #region [ 0) システムサウンドの構築  ]\r
245                                 //-----------------------------\r
246                                 CDTXMania.Instance.stage起動.eフェーズID = CStage.Eフェーズ.起動0_システムサウンドを構築;\r
247 \r
248                                 Trace.TraceInformation("0) システムサウンドを構築します。");\r
249                                 Trace.Indent();\r
250 \r
251                                 try\r
252                                 {\r
253                                         CDTXMania.Instance.Skin.bgm起動画面.t再生する();\r
254                                         for (int i = 0; i < CDTXMania.Instance.Skin.nシステムサウンド数; i++)\r
255                                         {\r
256                                                 if (!CDTXMania.Instance.Skin[i].b排他)  // BGM系以外のみ読み込む。(BGM系は必要になったときに読み込む)\r
257                                                 {\r
258                                                         CSkin.Cシステムサウンド cシステムサウンド = CDTXMania.Instance.Skin[i];\r
259                                                         if (!CDTXMania.Instance.bコンパクトモード || cシステムサウンド.bCompact対象)\r
260                                                         {\r
261                                                                 try\r
262                                                                 {\r
263                                                                         cシステムサウンド.t読み込み();\r
264                                                                         Trace.TraceInformation("システムサウンドを読み込みました。({0})", cシステムサウンド.strファイル名);\r
265                                                                         //if ( ( cシステムサウンド == CDTXMania.Instance.Skin.bgm起動画面 ) && cシステムサウンド.b読み込み成功 )\r
266                                                                         //{\r
267                                                                         //      cシステムサウンド.t再生する();\r
268                                                                         //}\r
269                                                                 }\r
270                                                                 catch (FileNotFoundException)\r
271                                                                 {\r
272                                                                         Trace.TraceWarning("システムサウンドが存在しません。({0})", cシステムサウンド.strファイル名);\r
273                                                                 }\r
274                                                                 catch (Exception e)\r
275                                                                 {\r
276                                                                         Trace.TraceError(e.Message);\r
277                                                                         Trace.TraceWarning("システムサウンドの読み込みに失敗しました。({0})", cシステムサウンド.strファイル名);\r
278                                                                 }\r
279                                                         }\r
280                                                 }\r
281                                         }\r
282                                         lock (CDTXMania.Instance.stage起動.list進行文字列)\r
283                                         {\r
284                                                 CDTXMania.Instance.stage起動.list進行文字列.Add("Loading system sounds ... OK ");\r
285                                         }\r
286                                 }\r
287                                 finally\r
288                                 {\r
289                                         Trace.Unindent();\r
290                                 }\r
291                                 //-----------------------------\r
292                                 #endregion\r
293 \r
294                                 if (CDTXMania.Instance.bコンパクトモード)\r
295                                 {\r
296                                         Trace.TraceInformation("コンパクトモードなので残りの起動処理は省略します。");\r
297                                         return;\r
298                                 }\r
299 \r
300                                 #region [ 00) songlist.dbの読み込みによる曲リストの構築  ]\r
301                                 //-----------------------------\r
302                                 CDTXMania.Instance.stage起動.eフェーズID = CStage.Eフェーズ.起動00_songlistから曲リストを作成する;\r
303 \r
304                                 Trace.TraceInformation("1) songlist.dbを読み込みます。");\r
305                                 Trace.Indent();\r
306 \r
307                                 try\r
308                                 {\r
309                                         if (!CDTXMania.Instance.ConfigIni.bConfigIniがないかDTXManiaのバージョンが異なる)\r
310                                         {\r
311                                                 CSongs管理 s = new CSongs管理();\r
312                                                 s = Deserialize(strPathSongList);   // 直接this.Songs管理にdeserialize()結果を代入するのは避ける。nullにされてしまうことがあるため。\r
313                                                 if (s != null)\r
314                                                 {\r
315                                                         this.Songs管理 = s;\r
316                                                 }\r
317 \r
318                                                 int scores = this.Songs管理.n検索されたスコア数;\r
319                                                 Trace.TraceInformation("songlist.db の読み込みを完了しました。[{0}スコア]", scores);\r
320                                                 lock (CDTXMania.Instance.stage起動.list進行文字列)\r
321                                                 {\r
322                                                         CDTXMania.Instance.stage起動.list進行文字列.Add("Loading songlist.db ... OK");\r
323                                                 }\r
324                                         }\r
325                                         else\r
326                                         {\r
327                                                 Trace.TraceInformation("初回の起動であるかまたはDTXManiaのバージョンが上がったため、songlist.db の読み込みをスキップします。");\r
328                                                 lock (CDTXMania.Instance.stage起動.list進行文字列)\r
329                                                 {\r
330                                                         CDTXMania.Instance.stage起動.list進行文字列.Add("Loading songlist.db ... Skip");\r
331                                                 }\r
332                                         }\r
333                                 }\r
334                                 finally\r
335                                 {\r
336                                         Trace.Unindent();\r
337                                 }\r
338 \r
339                                 #endregion\r
340 \r
341                                 #region [ 1) songs.db の読み込み ]\r
342                                 //-----------------------------\r
343                                 CDTXMania.Instance.stage起動.eフェーズID = CStage.Eフェーズ.起動1_SongsDBからスコアキャッシュを構築;\r
344 \r
345                                 Trace.TraceInformation("2) songs.db を読み込みます。");\r
346                                 Trace.Indent();\r
347 \r
348                                 try\r
349                                 {\r
350                                         if (!CDTXMania.Instance.ConfigIni.bConfigIniがないかDTXManiaのバージョンが異なる)\r
351                                         {\r
352                                                 try\r
353                                                 {\r
354                                                         this.Songs管理.tSongsDBを読み込む(strPathSongsDB);\r
355                                                 }\r
356                                                 catch\r
357                                                 {\r
358                                                         Trace.TraceError("songs.db の読み込みに失敗しました。");\r
359                                                 }\r
360 \r
361                                                 int scores = (this.Songs管理 == null) ? 0 : this.Songs管理.nSongsDBから取得できたスコア数; // 読み込み途中でアプリ終了した場合など、CDTXMania.Instance.Songs管理 がnullの場合があるので注意\r
362                                                 Trace.TraceInformation("songs.db の読み込みを完了しました。[{0}スコア]", scores);\r
363                                                 lock (CDTXMania.Instance.stage起動.list進行文字列)\r
364                                                 {\r
365                                                         CDTXMania.Instance.stage起動.list進行文字列.Add("Loading songs.db ... OK");\r
366                                                 }\r
367                                         }\r
368                                         else\r
369                                         {\r
370                                                 Trace.TraceInformation("初回の起動であるかまたはDTXManiaのバージョンが上がったため、songs.db の読み込みをスキップします。");\r
371                                                 lock (CDTXMania.Instance.stage起動.list進行文字列)\r
372                                                 {\r
373                                                         CDTXMania.Instance.stage起動.list進行文字列.Add("Loading songs.db ... Skip");\r
374                                                 }\r
375                                         }\r
376                                 }\r
377                                 finally\r
378                                 {\r
379                                         Trace.Unindent();\r
380                                 }\r
381                                 //-----------------------------\r
382                                 #endregion\r
383 \r
384                         }\r
385                         finally\r
386                         {\r
387                                 CDTXMania.Instance.stage起動.eフェーズID = CStage.Eフェーズ.起動7_完了;\r
388                                 TimeSpan span = (TimeSpan)(DateTime.Now - now);\r
389                                 Trace.TraceInformation("起動所要時間: {0}", span.ToString());\r
390                                 lock (this)             // #28700 2012.6.12 yyagi; state change must be in finally{} for exiting as of compact mode.\r
391                                 {\r
392                                         state = DTXEnumState.CompletelyDone;\r
393                                 }\r
394                         }\r
395                 }\r
396 \r
397 \r
398                 /// <summary>\r
399                 /// 起動してタイトル画面に遷移した後にバックグラウンドで発生させる曲検索\r
400                 /// #27060 2012.2.6 yyagi\r
401                 /// </summary>\r
402                 private void t曲リストの構築2()\r
403                 {\r
404                         // !注意!\r
405                         // 本メソッドは別スレッドで動作するが、プラグイン側でカレントディレクトリを変更しても大丈夫なように、\r
406                         // すべてのファイルアクセスは「絶対パス」で行うこと。(2010.9.16)\r
407                         // 構築が完了したら、DTXEnumerateState state を DTXEnumerateState.Done にすること。(2012.2.9)\r
408 \r
409                         DateTime now = DateTime.Now;\r
410                         bool bIsAvailableSongList = false;\r
411                         bool bIsAvailableSongsDB = false;\r
412                         bool bSucceededFastBoot = false;\r
413 \r
414                         try\r
415                         {\r
416 \r
417                                 #region [ 2) 曲データの検索 ]\r
418                                 //-----------------------------\r
419                                 //      base.eフェーズID = CStage.Eフェーズ.起動2_曲を検索してリストを作成する;\r
420 \r
421                                 Trace.TraceInformation("enum2) 曲データを検索します。");\r
422                                 Trace.Indent();\r
423 \r
424                                 try\r
425                                 {\r
426                                         if (!string.IsNullOrEmpty(CDTXMania.Instance.ConfigIni.strSongDataPath))\r
427                                         {\r
428                                                 string[] strArray = CDTXMania.Instance.ConfigIni.strSongDataPath.Value.Split(new char[] { ';' });\r
429                                                 if (strArray.Length > 0)\r
430                                                 {\r
431                                                         // 全パスについて…\r
432                                                         foreach (string str in strArray)\r
433                                                         {\r
434                                                                 string path = str;\r
435                                                                 if (!Path.IsPathRooted(path))\r
436                                                                 {\r
437                                                                         path = CDTXMania.Instance.strEXEのあるフォルダ + str;  // 相対パスの場合、絶対パスに直す(2010.9.16)\r
438                                                                 }\r
439 \r
440                                                                 if (!string.IsNullOrEmpty(path))\r
441                                                                 {\r
442                                                                         Trace.TraceInformation("検索パス: " + path);\r
443                                                                         Trace.Indent();\r
444 \r
445                                                                         try\r
446                                                                         {\r
447                                                                                 this.Songs管理.t曲を検索してリストを作成する(path, true);\r
448                                                                         }\r
449                                                                         catch (Exception e)\r
450                                                                         {\r
451                                                                                 Trace.TraceError(e.Message);\r
452                                                                                 Trace.TraceError(e.StackTrace);\r
453                                                                                 Trace.TraceError("例外が発生しましたが処理を継続します。");\r
454                                                                         }\r
455                                                                         finally\r
456                                                                         {\r
457                                                                                 Trace.Unindent();\r
458                                                                         }\r
459                                                                 }\r
460                                                         }\r
461                                                 }\r
462                                         }\r
463                                         else\r
464                                         {\r
465                                                 Trace.TraceWarning("曲データの検索パス(DTXPath)の指定がありません。");\r
466                                         }\r
467                                 }\r
468                                 finally\r
469                                 {\r
470                                         Trace.TraceInformation("曲データの検索を完了しました。[{0}曲{1}スコア]", this.Songs管理.n検索された曲ノード数, this.Songs管理.n検索されたスコア数);\r
471                                         Trace.Unindent();\r
472                                 }\r
473                                 //      lock ( this.list進行文字列 )\r
474                                 //      {\r
475                                 //              this.list進行文字列.Add( string.Format( "{0} ... {1} scores ({2} songs)", "Enumerating songs", this..Songs管理_裏読.n検索されたスコア数, this.Songs管理_裏読.n検索された曲ノード数 ) );\r
476                                 //      }\r
477                                 //-----------------------------\r
478                                 #endregion\r
479                                 #region [ 3) songs.db 情報の曲リストへの反映 ]\r
480                                 //-----------------------------\r
481                                 //                                      base.eフェーズID = CStage.Eフェーズ.起動3_スコアキャッシュをリストに反映する;\r
482                                 Trace.TraceInformation("enum3) songs.db の情報を曲リストへ反映します。");\r
483                                 Trace.Indent();\r
484 \r
485                                 try\r
486                                 {\r
487                                         if (this.Songs管理.listSongsDB != null)\r
488                                         {\r
489                                                 this.Songs管理.tスコアキャッシュを曲リストに反映する();\r
490                                         }\r
491                                 }\r
492                                 catch (Exception e)\r
493                                 {\r
494                                         Trace.TraceError(e.Message);\r
495                                         Trace.TraceError(e.StackTrace);\r
496                                         Trace.TraceError("例外が発生しましたが処理を継続します。");\r
497                                 }\r
498                                 finally\r
499                                 {\r
500                                         Trace.TraceInformation("曲リストへの反映を完了しました。[{0}/{1}スコア]", this.Songs管理.nスコアキャッシュから反映できたスコア数, this.Songs管理.n検索されたスコア数);\r
501                                         Trace.Unindent();\r
502                                 }\r
503                                 //      lock ( this.list進行文字列 )\r
504                                 //      {\r
505                                 //              this.list進行文字列.Add( string.Format( "{0} ... {1}/{2}", "Loading score properties from songs.db", CDTXMania.Instance.Songs管理_裏読.nスコアキャッシュから反映できたスコア数, cs.n検索されたスコア数 ) );\r
506                                 //      }\r
507                                 //-----------------------------\r
508                                 #endregion\r
509                                 #region [ 4) songs.db になかった曲データをファイルから読み込んで反映 ]\r
510                                 //-----------------------------\r
511                                 //                                      base.eフェーズID = CStage.Eフェーズ.起動4_スコアキャッシュになかった曲をファイルから読み込んで反映する;\r
512 \r
513                                 int num2 = this.Songs管理.n検索されたスコア数 - this.Songs管理.nスコアキャッシュから反映できたスコア数;\r
514 \r
515                                 Trace.TraceInformation("{0}, {1}", this.Songs管理.n検索されたスコア数, this.Songs管理.nスコアキャッシュから反映できたスコア数);\r
516                                 Trace.TraceInformation("enum4) songs.db になかった曲データ[{0}スコア]の情報をファイルから読み込んで反映します。", num2);\r
517                                 Trace.Indent();\r
518 \r
519                                 try\r
520                                 {\r
521                                         this.Songs管理.tSongsDBになかった曲をファイルから読み込んで反映する();\r
522                                 }\r
523                                 catch (Exception e)\r
524                                 {\r
525                                         Trace.TraceError(e.Message);\r
526                                         Trace.TraceError(e.StackTrace);\r
527                                         Trace.TraceError("例外が発生しましたが処理を継続します。");\r
528                                 }\r
529                                 finally\r
530                                 {\r
531                                         Trace.TraceInformation("曲データへの反映を完了しました。[{0}/{1}スコア]", this.Songs管理.nファイルから反映できたスコア数, num2);\r
532                                         Trace.Unindent();\r
533                                 }\r
534                                 //                                      lock ( this.list進行文字列 )\r
535                                 //                                      {\r
536                                 //                                              this.list進行文字列.Add( string.Format( "{0} ... {1}/{2}", "Loading score properties from files", CDTXMania.Instance.Songs管理_裏読.nファイルから反映できたスコア数, CDTXMania.Instance.Songs管理_裏読.n検索されたスコア数 - cs.nスコアキャッシュから反映できたスコア数 ) );\r
537                                 //                                      }\r
538                                 //-----------------------------\r
539                                 #endregion\r
540                                 #region [ 5) 曲リストへの後処理の適用 ]\r
541                                 //-----------------------------\r
542                                 //                                      base.eフェーズID = CStage.Eフェーズ.起動5_曲リストへ後処理を適用する;\r
543 \r
544                                 Trace.TraceInformation("enum5) 曲リストへの後処理を適用します。");\r
545                                 Trace.Indent();\r
546 \r
547                                 try\r
548                                 {\r
549                                         this.Songs管理.t曲リストへ後処理を適用する();\r
550                                 }\r
551                                 catch (Exception e)\r
552                                 {\r
553                                         Trace.TraceError(e.Message);\r
554                                         Trace.TraceError(e.StackTrace);\r
555                                         Trace.TraceError("例外が発生しましたが処理を継続します。");\r
556                                 }\r
557                                 finally\r
558                                 {\r
559                                         Trace.TraceInformation("曲リストへの後処理を完了しました。");\r
560                                         Trace.Unindent();\r
561                                 }\r
562                                 //                                      lock ( this.list進行文字列 )\r
563                                 //                                      {\r
564                                 //                                              this.list進行文字列.Add( string.Format( "{0} ... OK", "Building songlists" ) );\r
565                                 //                                      }\r
566                                 //-----------------------------\r
567                                 #endregion\r
568                                 #region [ 6) songs.db への保存 ]\r
569                                 //-----------------------------\r
570                                 //                                      base.eフェーズID = CStage.Eフェーズ.起動6_スコアキャッシュをSongsDBに出力する;\r
571 \r
572                                 Trace.TraceInformation("enum6) 曲データの情報を songs.db へ出力します。");\r
573                                 Trace.Indent();\r
574 \r
575                                 try\r
576                                 {\r
577                                         this.Songs管理.tスコアキャッシュをSongsDBに出力する(strPathSongsDB);\r
578                                 }\r
579                                 catch (Exception e)\r
580                                 {\r
581                                         Trace.TraceError(e.Message);\r
582                                         Trace.TraceError(e.StackTrace);\r
583                                         Trace.TraceError("例外が発生しましたが処理を継続します。");\r
584                                 }\r
585                                 finally\r
586                                 {\r
587                                         Trace.TraceInformation("songs.db への出力を完了しました。[{0}スコア]", this.Songs管理.nSongsDBへ出力できたスコア数);\r
588                                         Trace.Unindent();\r
589                                 }\r
590                                 //                                      lock ( this.list進行文字列 )\r
591                                 //                                      {\r
592                                 //                                              this.list進行文字列.Add( string.Format( "{0} ... OK", "Saving songs.db" ) );\r
593                                 //                                      }\r
594                                 #endregion\r
595 \r
596                                 //                              if ( !bSucceededFastBoot )      // songs2.db読み込みに成功したなら、songs2.dbを新たに作らない\r
597                                 #region [ 7) songs2.db への保存 ]           // #27060 2012.1.26 yyagi\r
598                                 Trace.TraceInformation("enum7) 曲データの情報を songlist.db へ出力します。");\r
599                                 Trace.Indent();\r
600 \r
601                                 SerializeSongList(this.Songs管理, strPathSongList);\r
602                                 Trace.TraceInformation("songlist.db への出力を完了しました。[{0}スコア]", this.Songs管理.nSongsDBへ出力できたスコア数);\r
603                                 Trace.Unindent();\r
604                                 //-----------------------------\r
605                                 #endregion\r
606                                 //                              }\r
607 \r
608                         }\r
609                         finally\r
610                         {\r
611                                 //                              base.eフェーズID = CStage.Eフェーズ.起動7_完了;\r
612                                 TimeSpan span = (TimeSpan)(DateTime.Now - now);\r
613                                 Trace.TraceInformation("曲探索所要時間: {0}", span.ToString());\r
614                         }\r
615                         lock (this)\r
616                         {\r
617                                 // state = DTXEnumState.Done;           // DoneにするのはCDTXMania.Instance.cs側にて。\r
618                                 state = DTXEnumState.Enumeratad;\r
619                         }\r
620                 }\r
621 \r
622 \r
623 \r
624                 /// <summary>\r
625                 /// 曲リストのserialize\r
626                 /// </summary>\r
627                 private static void SerializeSongList(CSongs管理 cs, string strPathSongList)\r
628                 {\r
629                         bool bSucceededSerialize = true;\r
630                         Stream output = null;\r
631                         try\r
632                         {\r
633                                 //output = File.Create( strPathSongList );\r
634                                 output = new FileStreamSSD( strPathSongList );\r
635                                 BinaryFormatter formatter = new BinaryFormatter();\r
636                                 formatter.Serialize(output, cs);\r
637                         }\r
638                         catch (Exception e)\r
639                         {\r
640                                 bSucceededSerialize = false;\r
641                                 Trace.TraceError(e.Message);\r
642                                 Trace.TraceError(e.StackTrace);\r
643                                 Trace.TraceError("例外が発生しましたが処理を継続します。");\r
644                         }\r
645                         finally\r
646                         {\r
647                                 if ( output != null )           // #36469 outputがnullのままfinallyに来た時の対策\r
648                                 {\r
649                                         output.Close();\r
650                                 }\r
651                                 if (!bSucceededSerialize)\r
652                                 {\r
653                                         try\r
654                                         {\r
655                                                 File.Delete(strPathSongList); // serializeに失敗したら、songs2.dbファイルを消しておく\r
656                                         }\r
657                                         catch (Exception)\r
658                                         {\r
659                                                 // 特に何もしない\r
660                                         }\r
661                                 }\r
662                         }\r
663                 }\r
664 \r
665                 /// <summary>\r
666                 /// 曲リストのdeserialize\r
667                 /// </summary>\r
668                 /// <param name="songs管理"></param>\r
669                 /// <param name="strPathSongList"></param>\r
670                 private CSongs管理 Deserialize(string strPathSongList)\r
671                 {\r
672                         CSongs管理 songs管理 = null;\r
673                         try\r
674                         {\r
675                                 #region [ SongListDB(songlist.db)を読み込む ]\r
676                                 //      byte[] buf = File.ReadAllBytes( SongListDBファイル名 );                    // 一旦メモリにまとめ読みしてからdeserializeした方が高速かと思ったら全く変わらなかったので削除\r
677                                 //      using ( MemoryStream input = new MemoryStream(buf, false) )\r
678                                 using (Stream input = File.OpenRead(strPathSongList))\r
679                                 {\r
680                                         try\r
681                                         {\r
682                                                 BinaryFormatter formatter = new BinaryFormatter();\r
683                                                 songs管理 = (CSongs管理)formatter.Deserialize(input);\r
684                                         }\r
685                                         catch (Exception)\r
686                                         {\r
687                                                 // songs管理 = null;\r
688                                         }\r
689                                 }\r
690                                 #endregion\r
691                         }\r
692                         catch\r
693                         {\r
694                                 Trace.TraceError("songlist.db の読み込みに失敗しました。");\r
695                         }\r
696                         return songs管理;\r
697                 }\r
698         }\r
699 }\r