OSDN Git Service

#30333 rev976までの内容を、trunkにマージ。
[dtxmania/dtxmania.git] / DTXManiaプロジェクト / コード / ステージ / 04.コンフィグ / COption.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Linq;\r
4 using System.Text;\r
5 using System.Threading.Tasks;\r
6 using System.Runtime.Serialization;\r
7 using FDK;\r
8 \r
9 namespace DTXMania\r
10 {\r
11         public delegate void VoidFunc();\r
12 \r
13         /// <summary>\r
14         /// Option 基底クラス。\r
15         /// 注意:値の参照は Value プロパティを使ってください。\r
16         /// 一部のクラスは暗黙的な型変換を実装していますが、\r
17         /// オプションクラスインスタンス同士の等価比較には気をつけてください。\r
18         /// </summary>\r
19         [DataContract]\r
20         public abstract class COptionBase\r
21         {\r
22                 public EOptionType type;\r
23                 /// <summary>\r
24                 /// コンフィグ画面におけるこの項目を表す文字列。\r
25                 /// </summary>\r
26                 public string label;\r
27 \r
28                 /// <summary>\r
29                 /// 説明。Properties.Resources から取得してください。\r
30                 /// </summary>\r
31                 public string explanation;\r
32 \r
33                 /// <summary>\r
34                 /// OnEnter で用いる動作。たとえば、この値によってほかのオプションに制約を与える場合などに\r
35                 /// その処理を登録しておけば、値の確定後実行されます。\r
36                 /// </summary>\r
37                 public VoidFunc OnEnterDelegate;\r
38 \r
39                 /// <summary>\r
40                 /// 決定動作。OnEnterDelegate メンバに動作を登録します。\r
41                 /// </summary>\r
42                 public void OnEnter()\r
43                 {\r
44                         if (OnEnterDelegate != null)\r
45                         {\r
46                                 OnEnterDelegate();\r
47                         }\r
48                 }\r
49 \r
50                 /// <summary>\r
51                 /// 前の項目値動作。順序付け可能な値からなるオプションは相応に実装する必要があります。\r
52                 /// </summary>\r
53                 public virtual void OnPrevious()\r
54                 {\r
55                 }\r
56 \r
57                 /// <summary>\r
58                 /// アイテムインデックス。\r
59                 /// </summary>\r
60                 public virtual int Index\r
61                 {\r
62                         get\r
63                         {\r
64                                 return 0;\r
65                         }\r
66                         set\r
67                         {\r
68 \r
69                         }\r
70                 }\r
71 \r
72                 /// <summary>\r
73                 /// OnPrevious の逆順序用。\r
74                 /// </summary>\r
75                 public virtual void OnNext()\r
76                 {\r
77                 }\r
78         }\r
79 \r
80         /// <summary>\r
81         /// Option 基底クラス。\r
82         /// DataContract により XML へのシリアライズ、XML からのデシリアライズが可能です。\r
83         /// </summary>\r
84         /// <typeparam name="T">このオプションの型。</typeparam>\r
85         [DataContract]\r
86         public abstract class COption<T> : COptionBase\r
87         {\r
88                 [DataMember]\r
89                 protected T val;\r
90 \r
91                 public virtual T Value\r
92                 {\r
93                         get\r
94                         {\r
95                                 return val;\r
96                         }\r
97                         set\r
98                         {\r
99                                 val = value;\r
100                         }\r
101                 }\r
102         }\r
103 \r
104         [DataContract]\r
105         public class COptionBool : COption<bool>\r
106         {\r
107                 public static implicit operator bool (COptionBool b)\r
108                 {\r
109                         return b.Value;\r
110                 }\r
111 \r
112                 public override int Index\r
113                 {\r
114                         get\r
115                         {\r
116                                 return val ? 1 : 0;\r
117                         }\r
118                 }\r
119 \r
120                 public COptionBool(bool init)\r
121                 {\r
122                         val = init;\r
123                 }\r
124 \r
125                 public override void OnNext()\r
126                 {\r
127                         OnPrevious();\r
128                 }\r
129 \r
130                 public override void OnPrevious()\r
131                 {\r
132                         val = !val;\r
133                 }\r
134 \r
135                 public override string ToString()\r
136                 {\r
137                         return val ? "On" : "Off";\r
138                 }\r
139 \r
140                 public void Initialize(string lbl, string expl)\r
141                 {\r
142                         label = lbl;\r
143                         explanation = expl;\r
144                 }\r
145         }\r
146 \r
147         [DataContract]\r
148         public class COptionInteger : COption<int>\r
149         {\r
150                 public int nStep;\r
151                 private int nMin;\r
152                 private int nMax;\r
153 \r
154                 public static implicit operator int (COptionInteger n)\r
155                 {\r
156                         return n.Value;\r
157                 }\r
158 \r
159                 public override int Index\r
160                 {\r
161                         get\r
162                         {\r
163                                 return val;\r
164                         }\r
165                 }\r
166 \r
167                 public COptionInteger(int init)\r
168                 {\r
169                         nMin = int.MinValue;\r
170                         nMax = int.MaxValue;\r
171                         val = init;\r
172                 }\r
173 \r
174                 public override int Value\r
175                 {\r
176                         get\r
177                         {\r
178                                 return base.Value;\r
179                         }\r
180 \r
181                         set\r
182                         {\r
183                                 base.Value = value;\r
184                                 LimitValue();\r
185                         }\r
186                 }\r
187 \r
188                 private void LimitValue()\r
189                 {\r
190                         if (val >= nMax)\r
191                         {\r
192                                 val = nMax - 1;\r
193                         }\r
194                         if (val < nMin)\r
195                         {\r
196                                 val = nMin;\r
197                         }\r
198                 }\r
199 \r
200                 public override void OnNext()\r
201                 {\r
202                         val+=nStep;\r
203                         LimitValue();\r
204                 }\r
205 \r
206                 public override void OnPrevious()\r
207                 {\r
208                         val-=nStep;\r
209                         LimitValue();\r
210                 }\r
211 \r
212                 public Converter<int, string> ValueFormatter;\r
213 \r
214                 public override string ToString()\r
215                 {\r
216                         string ret = "";\r
217                         if (ValueFormatter != null)\r
218                         {\r
219                                 ret = ValueFormatter(val);\r
220                         }\r
221                         else\r
222                         {\r
223                                 ret = val.ToString();\r
224                         }\r
225                         return ret;\r
226                 }\r
227 \r
228                 public void Initialize(string lbl, string expl, int min = int.MinValue, int max = int.MaxValue, int step = 1)\r
229                 {\r
230                         label = lbl;\r
231                         explanation = expl;\r
232                         nMin = min;\r
233                         nMax = max;\r
234                         nStep = step;\r
235                 }\r
236         }\r
237 \r
238         public interface IOptionList\r
239         {\r
240 \r
241         }\r
242 \r
243         [DataContract]\r
244         public abstract class COptionList<T> : COption<T>, IOptionList\r
245         {\r
246                 protected T[] vals;\r
247                 protected int ptr;\r
248                 public int Length { get; protected set; }\r
249 \r
250                 public T this[int idx]\r
251                 {\r
252                         get\r
253                         {\r
254                                 return vals[idx];\r
255                         }\r
256                 }\r
257 \r
258                 public override T Value\r
259                 {\r
260                         get\r
261                         {\r
262                                 return base.Value;\r
263                         }\r
264 \r
265                         set\r
266                         {\r
267                                 base.Value = value;\r
268                                 for (int i = 0; i < Length; ++i)\r
269                                 {\r
270                                         if (vals[i].Equals(value))\r
271                                         {\r
272                                                 ptr = i;\r
273                                         }\r
274                                 }\r
275                         }\r
276                 }\r
277 \r
278                 public override int Index\r
279                 {\r
280                         get\r
281                         {\r
282                                 return ptr;\r
283                         }\r
284                         set\r
285                         {\r
286                                 ptr = value;\r
287                                 if (ptr >= Length) ptr = Length - 1;\r
288                                 if (ptr < 0) ptr = 0;\r
289                         }\r
290                 }\r
291 \r
292                 public override void OnNext()\r
293                 {\r
294                         ++ptr;\r
295                         if (ptr >= Length)\r
296                         {\r
297                                 ptr = 0;\r
298                         }\r
299                         val = vals[ptr];\r
300                 }\r
301 \r
302                 public override void OnPrevious()\r
303                 {\r
304                         --ptr;\r
305                         if (ptr < 0)\r
306                         {\r
307                                 ptr = Length - 1;\r
308                         }\r
309                         val = vals[ptr];\r
310                 }\r
311 \r
312                 public override string ToString()\r
313                 {\r
314                         return val.ToString();\r
315                 }\r
316 \r
317         }\r
318 \r
319 \r
320         /// <summary>\r
321         /// 列挙定数用オプションアイテム。\r
322         /// </summary>\r
323         /// <typeparam name="E">\r
324         /// 列挙型。ただし、列挙型以外を渡してもコンパイル時エラーとならないので注意してください。(where 制約不可)\r
325         /// また E のメンバに負の値を持つメンバを入れると意図した順番になりません。</typeparam>\r
326         [DataContract]\r
327         public class COptionEnum<E> : COptionList<E> where E : struct\r
328         {\r
329                 public static implicit operator E(COptionEnum<E> e)\r
330                 {\r
331                         return e.Value;\r
332                 }\r
333 \r
334                 /// <summary>\r
335                 /// リフレクションから列挙定数の集合を取得し、内部ポインタでまわします。\r
336                 /// ※実行時型情報の扱いは基本的に重いので注意してください。\r
337                 /// </summary>\r
338                 public COptionEnum(E init)\r
339                 {\r
340                         val = init;\r
341                 }\r
342 \r
343                 public void Initialize(string lbl, string expl, Type type)\r
344                 {\r
345                         label = lbl;\r
346                         explanation = expl;\r
347 \r
348                         Length = type.GetEnumValues().Length;\r
349                         vals = new E[Length];\r
350                         int initptr = -1;\r
351                         ptr = 0;\r
352                         foreach (E t in typeof(E).GetEnumValues())\r
353                         {\r
354                                 if (t.Equals(val))\r
355                                 {\r
356                                         initptr = ptr;\r
357                                 }\r
358                                 vals[ptr] = t;\r
359                                 ++ptr;\r
360                         }\r
361                         if (initptr == -1)\r
362                         {\r
363                                 val = vals[0];\r
364                                 ptr = 0;\r
365                         }\r
366                         else\r
367                         {\r
368                                 ptr = initptr;\r
369                         }\r
370                 }\r
371 \r
372         }\r
373 \r
374         [DataContract]\r
375         public class COptionString : COption<string>\r
376         {\r
377                 public static implicit operator string (COptionString s)\r
378                 {\r
379                         return s.Value;\r
380                 }\r
381 \r
382                 public COptionString(string init)\r
383                 {\r
384                         val = init;\r
385                 }\r
386 \r
387                 public void Initialize(string lbl, string expl)\r
388                 {\r
389                         label = lbl;\r
390                         explanation = expl;\r
391                 }\r
392 \r
393                 public override string ToString()\r
394                 {\r
395                         return val;\r
396                 }\r
397         }\r
398 \r
399         [DataContract]\r
400         public class COptionStringList : COptionList<string>\r
401         {\r
402                 public COptionStringList(string init)\r
403                 {\r
404                         val = init;\r
405                 }\r
406 \r
407                 public void Initialize(string lbl, string expl, string[] initvals)\r
408                 {\r
409                         label = lbl;\r
410                         explanation = expl;\r
411 \r
412                         Length = initvals.Length;\r
413                         vals = new string[Length];\r
414                         int initptr = -1;\r
415                         ptr = 0;\r
416                         foreach (var t in initvals)\r
417                         {\r
418                                 if (t == val)\r
419                                 {\r
420                                         initptr = ptr;\r
421                                 }\r
422                                 vals[ptr] = t;\r
423                                 ++ptr;\r
424                         }\r
425 \r
426                         if (initptr == -1)\r
427                         {\r
428                                 val = vals[0];\r
429                                 ptr = 0;\r
430                         }\r
431                         else\r
432                         {\r
433                                 ptr = initptr;\r
434                         }\r
435                 }\r
436         }\r
437 \r
438         [DataContract]\r
439         public class COptionFloat : COption<float>\r
440         {\r
441                 public static implicit operator float (COptionFloat f)\r
442                 {\r
443                         return f.Value;\r
444                 }\r
445 \r
446                 public COptionFloat(float init)\r
447                 {\r
448                         val = init;\r
449                 }\r
450 \r
451                 public void Initialize(string lbl, string expl)\r
452                 {\r
453                         label = lbl;\r
454                         explanation = expl;\r
455                 }\r
456 \r
457                 public override string ToString()\r
458                 {\r
459                         return val.ToString();\r
460                 }\r
461         }\r
462 \r
463         public class COptionLabel : COptionString\r
464         {\r
465                 public COptionLabel(string lbl, string expl)\r
466                         : base("")\r
467                 {\r
468                         type = EOptionType.Other;\r
469                         label = lbl;\r
470                         explanation = expl;\r
471                 }\r
472         }\r
473 \r
474         [DataContract]\r
475         public class COptionDictionary<K, V> : COption<Dictionary<K, V>>\r
476         {\r
477                 public V this[K t]\r
478                 {\r
479                         get\r
480                         {\r
481                                 return Value[t];\r
482                         }\r
483                 }\r
484         }\r
485 \r
486         [DataContract]\r
487         public class COptionKeyAssign : COption<CKeyAssign>\r
488         {\r
489                 public EInputDevice 入力デバイス\r
490                 {\r
491                         get\r
492                         {\r
493                                 return Value.InputDevice;\r
494                         }\r
495                         set\r
496                         {\r
497                                 Value.InputDevice = value;\r
498                         }\r
499                 }\r
500 \r
501                 public int ID\r
502                 {\r
503                         get\r
504                         {\r
505                                 return Value.ID;\r
506                         }\r
507                         set\r
508                         {\r
509                                 Value.ID = value;\r
510                         }\r
511                 }\r
512 \r
513                 public int コード\r
514                 {\r
515                         get\r
516                         {\r
517                                 return Value.Code;\r
518                         }\r
519                         set\r
520                         {\r
521                                 Value.Code = value;\r
522                         }\r
523                 }\r
524 \r
525                 public COptionKeyAssign()\r
526                 {\r
527                         val = new CKeyAssign(EInputDevice.Unknown, 0, 0);\r
528                 }\r
529 \r
530                 public void Reset()\r
531                 {\r
532                         Value.InputDevice = EInputDevice.Unknown;\r
533                         Value.ID = 0;\r
534                         Value.Code = 0;\r
535                 }\r
536 \r
537                 public void CopyFrom(CKeyAssign t)\r
538                 {\r
539                         Value.InputDevice = t.InputDevice;\r
540                         Value.ID = t.ID;\r
541                         Value.Code = t.Code;\r
542                 }\r
543         }\r
544 \r
545         [DataContract]\r
546         public class COptionPadBool : STPadValue<COptionBool>\r
547         {\r
548                 private bool DetermineAssignValue(EThreeState state)\r
549                 {\r
550                         return state == EThreeState.On ? true : state == EThreeState.Off ? false : false;\r
551                 }\r
552 \r
553                 public bool bIsAutoHH\r
554                 {\r
555                         get\r
556                         {\r
557                                 return !LC && HH && !SD && !BD && !HT && !LT && !FT && !CY && !RD && HHO;\r
558                         }\r
559                 }\r
560 \r
561                 public bool bIsAutoBD\r
562                 {\r
563                         get\r
564                         {\r
565                                 return !LC && !HH && !SD && BD && !HT && !LT && !FT && !CY && !RD && !HHO;\r
566                         }\r
567                 }\r
568 \r
569                 public bool bIsAutoNeck(EPart e)\r
570                 {\r
571                         bool ret = false;\r
572                         if (e == EPart.Guitar)\r
573                         {\r
574                                 ret = GtR && GtG && GtB && !GtPick;\r
575                         }\r
576                         else if (e == EPart.Bass)\r
577                         {\r
578                                 ret = BsR && BsG && BsB && !BsPick;\r
579                         }\r
580                         return ret;\r
581                 }\r
582 \r
583                 public bool bIsAutoPick(EPart e)\r
584                 {\r
585                         bool ret = false;\r
586                         if (e == EPart.Guitar)\r
587                         {\r
588                                 ret = !GtR && !GtG && !GtB && GtPick;\r
589                         }\r
590                         else if (e == EPart.Bass)\r
591                         {\r
592                                 ret = !BsR && !BsG && !BsB && BsPick;\r
593                         }\r
594                         return ret;\r
595                 }\r
596 \r
597                 public void SetAutoHH()\r
598                 {\r
599                         Set(EPart.Drums, EThreeState.Off);\r
600                         HH.Value = true;\r
601                 }\r
602 \r
603                 public void SetAutoBD()\r
604                 {\r
605                         Set(EPart.Drums, EThreeState.Off);\r
606                         BD.Value = true;\r
607                 }\r
608 \r
609                 public void SetAutoPick(EPart e)\r
610                 {\r
611                         Set(e, EThreeState.Off);\r
612                         if (e == EPart.Drums)\r
613                         {\r
614                                 GtPick.Value = true;\r
615                         }\r
616                         else if (e == EPart.Bass)\r
617                         {\r
618                                 BsPick.Value = true;\r
619                         }\r
620                 }\r
621 \r
622                 public void SetAutoNeck(EPart e)\r
623                 {\r
624                         Set(e, EThreeState.Off);\r
625                         if (e == EPart.Drums)\r
626                         {\r
627                                 GtR.Value = true;\r
628                                 GtG.Value = true;\r
629                                 GtB.Value = true;\r
630                         }\r
631                         else if (e == EPart.Bass)\r
632                         {\r
633                                 BsR.Value = true;\r
634                                 BsG.Value = true;\r
635                                 BsB.Value = true;\r
636                         }\r
637                 }\r
638 \r
639                 public void Set(EPart e, EThreeState state)\r
640                 {\r
641                         bool val = DetermineAssignValue(state);\r
642                         if (EThreeState.X != state)\r
643                         {\r
644                                 if (e == EPart.Drums)\r
645                                 {\r
646                                         LC.Value = HH.Value = HHO.Value = SD.Value =\r
647                                                         BD.Value = HT.Value = LT.Value = FT.Value = CY.Value = RD.Value = val;\r
648                                 }\r
649                                 else if (e == EPart.Guitar)\r
650                                 {\r
651                                         GtR.Value = GtG.Value = GtB.Value = GtPick.Value = GtWail.Value = val;\r
652                                 }\r
653                                 else if (e == EPart.Bass)\r
654                                 {\r
655                                         BsR.Value = BsG.Value = BsB.Value = BsPick.Value = BsWail.Value = val;\r
656                                 }\r
657                         }\r
658                 }\r
659 \r
660                 public bool IsAllFalse(EPart x)\r
661                 {\r
662                         bool ret = false;\r
663                         if (x == EPart.Guitar)\r
664                         {\r
665                                 ret = !GtR && !GtG && !GtB && !GtPick && !GtWail;\r
666                         }\r
667                         else if (x == EPart.Bass)\r
668                         {\r
669                                 ret = !BsR && !BsG && !BsB && !BsPick && !BsWail;\r
670                         }\r
671                         else if (x == EPart.Drums)\r
672                         {\r
673                                 ret = !LC && !HH && !SD && !BD && !HT && !LT && !FT && !CY && !RD && !HHO;\r
674                         }\r
675                         return ret;\r
676                 }\r
677 \r
678                 public bool IsAllTrue(EPart x)\r
679                 {\r
680                         bool ret = false;\r
681                         if (x == EPart.Guitar)\r
682                         {\r
683                                 ret = GtR && GtG && GtB && GtPick && GtWail;\r
684                         }\r
685                         else if (x == EPart.Bass)\r
686                         {\r
687                                 ret = BsR && BsG && BsB && BsPick && BsWail;\r
688                         }\r
689                         else if (x == EPart.Drums)\r
690                         {\r
691                                 ret = LC && HH && SD && BD && HT && LT && FT && CY && RD && HHO;\r
692                         }\r
693                         return ret;\r
694                 }\r
695         }\r
696 \r
697 }\r