ゆかりすたー METEOR Ver 2.12 α 公開

MainWindowゆかりすたー METEOR(メテオ)の新バージョン、Ver 2.12 α を公開しました。

ゆかりすたー METEOR はニコカラ動画ファイルを整理し、「ゆかり」(持ち込みカラオケ用のブラウザリクエストツール)から検索できるようにするツールです。データベースを活用することにより、タイアップしている番組名や歌手名などの付加情報を含めて整理するので、単なるファイル名検索にとどまらない高い検索性を提供することができるようになります。

ゆかりすたー METEOR は、ニコカラりすたーおよび初代ゆかりすたーの後継ソフトとして開発しています。ニコカラりすたーは一時点でのリスト化機能のみを提供していましたが、ゆかりすたー METEOR は、ゆかりと連携した高度な検索性の提供を目的に、リアルタイムでのリスト化機能と検索用データベース構築機能を提供します。

更新内容

今回のバージョンから、ゆかりすたー METEOR の動作には .NET Framework 4.5.2 以上が必要となります。今までは .NET Framework 4.5 以上で動作していましたので、.NET Framework 4.5 または 4.5.1 をお使いの方は、.NET Framerork のバージョンアップが必要となりますのでご注意ください。

機能的には細かな内容のバージョンアップです。

メインウィンドウやファイル一覧ウィンドウにおいて、行の高さを細くして、一覧性を向上させました。

歌手の編集ウィンドウにおいて、人物が同姓同名の場合はキーワードを併記して見分けが付くように改善しました。

インポートウィンドウにおいて常に進捗を表示するようにしました。

その他、細かい改善をしています。今回の更新内容を含む課題対応履歴についてはこちらをご覧ください。

なお、内部的な構造を刷新し、MVVM プログラミングモデルを採用したため、プログラムはイチから作り直しています。

Windows Defender について

Windows Defender がゆかりすたー METEOR の動作に悪影響を及ぼす場合があり、エラーが発生したり、処理速度が異常に遅くなったりする例が報告されています。

ゆかりすたー METEOR を使う際は、Windows Defender を使わないことをお薦めします。

詳細についてはこちらをご覧ください。

更新・新規インストール方法

ゆかりすたー METEOR は自動更新機能を搭載しています。既にゆかりすたー METEOR をお使いの方は、ゆかりすたー METEOR を起動すると、3 日以内に更新のアナウンスが表示されます。

すぐにアップデートしたい場合は、環境設定ウィンドウのメンテナンスタブを開き、「今すぐ最新情報を確認する」ボタンをクリックすることで、アップデートを開始することができます。

Ver150to168右のようなダイアログが表示されますので、「はい。今すぐ更新します」をクリックしてください。

ゆかりすたー更新版インストール画面に案内が表示されますので、案内に従って操作をして下さい。

ゆかりすたー更新完了ほどなくして、ゆかりすたー METEOR の更新が完了します。

これから初めてゆかりすたー METEOR を使う方(新規の方)や、手動でゆかりすたー METEOR を更新したい方は、下記サイトからどうぞ。

旧作について

ニコカラりすたーおよびゆかりすたー(初代)は開発を終了しました。

今後はゆかりすたー METEOR をご利用下さい。

フォームと WPF でコードメトリックスを計算・比較してみた

MVVM
同等の機能を持つソフトでフレームワークが異なる場合、Visual Studio 2017 で計算できるコードメトリックスはどのくらい変わるのか、というのが気になったので、あまり意味はないけど測定してみた。

対象プロジェクトはゆかりすたー。バージョン間で細かな違いはもちろんあるものの、大まかに見れば機能的にはほとんど同等。結果は以下の通り。

フォーム
ゆかりすたー
Ver 7.51
WPF / コードビハインド
ゆかりすたー METEOR
Ver 1.50
WPF / MVVM
ゆかりすたー METEOR
Ver 2.02
保守容易性指数828486
サイクロマティック複雑度388839334480
継承の深さ799
クラス結合431466465
コード行1249896859333

保守容易性指数

公式解説によれば保守容易性指数の値が大きいほど保守性が高く、0~9 がダメ、10~19 がまぁまぁ、20~100 が OK とのこと。

いずれのフレームワークでも 80 以上なのでかなり良好と言えると思うが、WPF のほうが少し高い数値になっている。

ただ気になるのは、WPF の XAML 部分はあまり考慮されていないのではないかということ。WPF / MVVM で試しにメインウィンドウの XAML からコントロールをさくっと削り、メインウィンドウ部分の評価を比較したのが以下。

元の WPF / MVVMコントロール削除
保守容易性指数91
91
サイクロマティック複雑度11
継承の深さ99
クラス結合72
コード行22

保守容易性指数(というかクラス結合以外)に変化がない。XAML に複雑な表示ロジックをべた書きして、代わりに ViewModel からコードを減らしたら、保守容易性指数はあがってしまうのではないか。ちょっとインチキ臭い。XAML を考慮に入れると、フォームと WPF で保守容易性はほとんど変わらないと言えるかもしれない。

さて、総合的には保守容易性指数が 86 の WPF / MVVM でも、細かく見ていくと値が低い部分もある。最低は 0 で、ViewTFoundsWindowViewModel.cs の DataGridListSorting()。ソート基準項目によってひたすら switch するので低い評価になっている。

次に低いのが CsvOutputWriter.cs の Output() で 28。こちらも出力項目ごとに switch していて、switch の case が並ぶのは低い評価になりやすいのかもしれない。

サイクロマティック複雑度

Wikipedia を読むと、サイクロマティック複雑度(循環的複雑度)はプログラム実行時の経路数に関係する値で、大きいほど経路・分岐が多くなる。プログラムの動作を理解するのが大変になったり、テストケースが多くなって大変になったりするのだろう。

プログラムの規模が大きくなるにつれてサイクロマティック複雑度も大きくなっていく性質があるので、単純に数値だけを見て良い悪いは言えないが、相対的に WPF よりフォームの方が値が小さいので、フォームの方が理解しやすいという見方ができるのではないか。体感としても、フォームの方が簡単だと思う。

継承の深さ

使用しているクラスが、根源となるクラスである Object から何段階派生しているか。WPF のほうがクラス階層が深いが、最大の 9 となっているクラスはすべてウィンドウだった。WPF でウィンドウを使うと必ず 9 以上になるということからすれば、結果が 9 であるというのは少ない値と言えるだろう。

クラス結合

低い方が良い数値。フォームの方が低い。

コード行

ソースコードの行数ではなく、IL の数。ソースコードのコメント行や空行は数値に影響しないと思われるため、単純にソースコードの行数を数えるよりも実際的。

ソースコード行数より少ない数値となる傾向があり、例えば 最大値を記録した SyncClient はソースコード上は 2058 行だが、IL では 882 行と、半分以下になっている。

フレームワーク間で比較すると、WPF のほうがずっと少なくなっている。フレームワークに関係ないところで最適化してるところが(ソースコード行数ベースで)1000 行ほどあるが、それを差し引いても WPF のほうが少ない。

ただし、WPF は使用しているライブラリが多く、それらまで含めると、総合的なコード量はフォームのほうが少なくなるのではないだろうか。

まとめ

元々あまり意味のある比較とは思えないものの、傾向としては、フォームの方がシンプル・コンパクトということになるだろう。元々 WPF / MVVM はシンプルさで売ってないし……。


PetitKara のストレージ認識状況メモ

PetitKara にいくつか USB メモリや HDD を繋げた際の挙動をまとめてメモ。記憶を頼りにしている部分もあり、もしかしたら間違っている部分もあるかもしれない。

使用した PetitKara のバージョンは 1.4.19 で、WAN 側はインターネットに接続していない。

相性の悪い USB メモリ

transcendUSB メモリ A(JetFlash Transcend 2GB、NTFS、動画ファイルなし)を本体に直接挿して起動したところ、Debian のデスクトップまでは起動するが、PetitKara が起動しない。

Debian は USB メモリ A を認識していて、デスクトップに USB メモリ A のアイコンが表示されていた。

動画情報更新で読めない HDD

PetitKara が起動した状態で HDD E(Western Digital My Passport 4TB、青色、NTFS、動画ファイル 4 万個)を本体に直接挿し、動画情報更新をしたところ、10 分以上経っても動画情報更新が終わらない。HDD のアクセスランプが点滅しておらず、HDD にアクセスしている気配が無い。

セルフパワー型ハブ(Anker 10-Port USB 3.0 Hub)に HDD E を挿して動画情報更新をしても終わらない。なお、以降はすべてハブ経由の接続。

guruguru2動画情報更新を中断し、ログインして動画を検索すると、ぐるぐるアイコンから先に進まない。

HDD F(4TB、黒色)についても同様で、起動後の動画情報更新で認識してくれない。

動画情報更新可能な USB メモリ

sonyUSB メモリ B(SONY Storage Media 32GB、NTFS、動画ファイル 250 曲)は、PetitKara 起動後に挿して動画情報更新をしたら認識してくれた。

ストレージ 5 本挿し

storage5a起動後の動画情報更新ではなく、起動時に挿しておくと認識してくれることに気がついた。

USB メモリ B、USB メモリ C(水色)、HDD E、HDD F、HDD G(Buffalo HD-PNFU3、1TB、黄色、動画ファイル 1.3 万個)の 5 つを接続した状態で起動すると、Debian のデスクトップにすべてのストレージのアイコンが表示された。

41709aPetitKara でも基本的には認識されたが、HDD E については認識してくれなかった。検索結果は 42,000 件ほど。

この状態でしばらく運用していたところ、2 回ほど、曲が途中で終了してしまう状況が発生した。

Debian では認識されているが PetitKara からは認識されていない HDD E が何らか影響しているのかと思い、HDD E を外してみた。本来は外した後で動画情報更新を行うべきであるが、動画情報更新はうまくいかないことが分かっているので、動画情報更新はしていない。

notfoundすると、今まで使えていた USB メモリ B の中の動画について、検索結果には引き続き出てくるものの、リクエストしようとすると「動画が見つかりません」というエラーとなった。

USB メモリ B の中には、HDD E と同じファイルの一部が入っている形になっており、ファイル名だけで見れば HDD E と重複しているが、それが何か関係しているのであろうか。

別の組み合わせでストレージ 5 本挿し

USB メモリ B、HDD E、HDD F、HDD G、HDD H(Western Digital My Passport 4TB、黄色)の 5 つのストレージを起動時から接続しておいたところ、先ほど認識されなかった HDD E も含めて 5 つすべてのストレージが認識されたのではないかと思うが、ファイル数が多すぎて今ひとつ自信が無い。HDD E のパスをキーワードにして検索した結果の数から見て、HDD E はたぶん認識されたと思う。

100kキーワードを空にした場合、検索結果が省略されてしまっているが、10 万件ということだと思う。

5087検索結果ページ数は 5087 ページ。





MVVM ダメ Tips

使ってはいけない Tips。コードは Livet 環境前提。

ViewModel から直接 View を参照してしまう

最早 MVVM ではないが、添付ビヘイビアとか作るの面倒くさい時に。
Initialize2() の引数に Window オブジェクトが渡される。

XAML 側コード

<i:EventTrigger EventName="ContentRendered">
    <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="Initialize"/>
    <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="Initialize2" MethodParameter="{Binding ElementName=MyWindow}"/>
</i:EventTrigger>

ViewModel 側コード

public void Initialize2(Object oParam)
{
    Debug.WriteLine("Initialize2() param type: " + oParam?.GetType().ToString());
}


Factory Town 計算ブロックでマインカートを制御する

生産物流箱庭ゲーム「Factory Town」において、マインカート(鉄道)は直進しかできない猪突猛進型のユニットですが、計算ブロックを使うことで、マインカートに様々な振る舞いをさせられるようになります。

以下の記事の内容は把握済みである前提でまとめています。

なお、Factory Town Ver 0.108m 時点(Windows 版)での情報です。画像はクリックすると拡大します。

やりたいこと

マインカートの積み荷によって、行き先を分岐させたいと思います。また、積み荷を降ろして空になったマインカートに対しては、1 台ごとに別の荷物を積むようにします。

whole2全体像が右の写真です。

カートは青白い矢印の向きに時計回りに走るものとします。

①のサイロには木材があり、②の井戸からは水が出てきます。従って、カートは木材か水のどちらかを積んだ状態で、(B) の分岐点に来ます。

木材を積んだカートは (B) を上方向に、水を積んだカートは (B) を右方向に進むようにします。

これにより、③の倉庫には木材だけが、④の倉庫には水だけが溜まっていきます。同じ線路を使用していても、積み荷の振り分けが可能となります。

積み荷を倉庫で降ろして空になったカートは、(A) の分岐点に来ます。

(A) では、上方向と右方向を交互に進ませます。これにより、1 台目のカートが木材を積んだら、2 台目のカートは水を積む、というように、2 種類の積み荷を運ぶことができます。

(補足)積み荷の振り分けは、計算ブロックを使わずとも、ソーターやプッシャーでマインカートを押し出すことにより行えます。本記事は計算ブロックの勉強用としてご覧ください。

施設の配置

fusetsu右の写真のように、施設やレールとバリアゲートを配置します。時間を止めた方がやりやすいです。

バリアゲートは物流ブロックの中にあり、設置時は「オフ」になっていて遮断機がおりた状態で通行できませんが、「オン」にすると遮断機が上がって通行できるようになるというブロックです。

サイロと井戸のレールストップは出力、倉庫のレールストップは入力に設定します。

レールの敷設についてですが、(1)-(2)-(3) の分岐部分は、(1)-(2) を先に敷いてから最後に (3) をつなぐようにします。詳しくは、マインカートの記事の「単線運用」節を参考にしてください。

同様に、(1)-(4)-(5) は (4)-(5) が先、(5)-(6)-(7) は (5)-(6) が先、(7)-(8)-(9) は (7)-(9) が先です。

カートは適当な台数(私は 3 台にしました)を、時計回りに走るように配置します。手動でバリアゲートをオンオフして、それぞれの場合でカートが詰まらずに走れるか確認すると良いと思います。

計算ブロックの配置と設定(右側の分岐)

bunki1右側の分岐(積み荷の種類による分岐)の制御を行う計算ブロックの説明から先にします。(5) から来たカートが (6) か (7) かのどちらかに進む分岐です。

カートの積み荷による分岐を行うには、計算ブロックであるエージェントトリガーを使います。エージェントトリガーは、通過したアイテムによってオンオフを出力するブロックです。

エージェントトリガーを分岐点に上乗せして配置します。簡単のために分岐点に重ねていますが、重ねたくない場合は他の場所に配置しても構いません。ただし、他の場所に配置した場合は、オフセット指定で分岐点を必ず指定して下さい。

エージェントトリガーのアイテムフィルタを「水」にします。

bunki2最後に、オンオフをバリアゲートに伝送するために、エージェントトリガーとバリアゲートをリンクします。エージェントトリガーが送信元(左クリック)、バリアゲートが受け取り先(右クリック)です。

ここまでの設定により、「エージェントトリガーを通過したアイテムが水の場合はオン、そうでないならオフ」という設定がバリアゲートに送られます。バリアゲートはオンの時は通行可能となりますから、結果として、水を積んでいる場合に通行可能となります。カートは直進と左折のどちらもできる分岐に来た場合は直進しますので、直進して (7) の右方向に進みます。

一方で、水を積んでいない場合(木を積んでいるか、または空の場合)はエージェントトリガーがオフになります。バリアゲートはオフの時は通行不可ですから、カートは左折せざるを得ず、(6) の方向に進みます。

結果として、木は上の倉庫に、水は下の倉庫に入ります。

計算ブロックの配置と設定(左側の分岐)

次に左側の分岐(交互に振り分け)の制御を行う計算ブロックの説明をします。(2) から来たカートが (1) か (3) かのどちらかに進む分岐です。

bunki3再びエージェントトリガーを使います。エージェントトリガーを分岐に重ねて下さい(オフセットをしていする場合はどこでも構いません)。

さらに、トグルを付近の適当な場所に設置します。

計算ブロックの設定ですが、左側の分岐では、エージェントトリガーのアイテムフィルタは無しのままにしておきます。こうすると、エージェントトリガーと何かが通過したときに常に信号が発生するようになります。

そして、エージェントトリガーからトグルへ信号を伝送するためにリンクします(エージェントトリガーが送信元、トグルが受け取り先)。

トグルは、何らかの信号が届くたびに、オンとオフが切り替わります。つまり、エージェントトリガーをトロッコが通過する度に、交互にオンとオフになります。

トグルの設定をバリアゲートへ伝送するために、トグルからバリアゲートへリンクします(トグルが送信元、バリアゲートが受け取り先)。

交互にオンオフが送られてくるので、バリアゲートは開いたり閉じたりを繰り返します。

動作結果

ゲーム時間を再開すると、カートが走り出します。

カートが動く様子を動画にしましたので、以下の動画を参照してください。



mokuzai上側の倉庫を見ると、木材だけが溜まっていくのが分かります。

mizu逆に、下側の倉庫を見ると、水だけが溜まっていくのが分かります。

以上により、マインカートを制御して積み荷を振り分けることができました。

単に積み荷の振り分けということでいえば、計算ブロックに限らずやり方はいくつもあり、先の補足に記したようにソーターなどでも実現可能です。

しかし、計算ブロックでマインカートの制御ができるようになることで、いろいろな夢が広がっていくのではないでしょうか。

カウンター


カンパのお願い
Amazon でお買い物の際は、下記で検索して頂けたら幸いです。
記事検索
最新コメント
  • ライブドアブログ