2013年8月29日木曜日

マルチリンガルで行こう(WPF編)

えー、前回いつ更新したか覚えてないくらいにはご無沙汰してます、はざまです。
今回は、趣味グラミングアプリを作っていてちょっとはまった部分を自分用メモも兼ねてエントリーにしておこうと思います。題材にするのはその名も、WPFLocalizationExtensionです。このライブラリ、名前の通りWPFで作成するアプリのローカライゼーションを容易にしてくれます。具体的にどんなことができるのかは公式サイトのイントロダクション動画を参照していただくとして、残念ながらこのライブラリーはドキュメンテーションの質がイマイチなので、ここでは準備方法と使用方法の解説をしたいと思います。

まず、インストール方法ですが、nuGetが使えるならそこから入手するのが一番楽です。というか、その方法しか試したことはありません。一からビルドする場合には、ご自身でその方法を調査してみてください。
インストールが終わったら、まずサンプルとして以下のような.xamlファイルを作成します。

<Window
    x:Class="WPFLocalizationExtensionExample.ExampleView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:lex="http://wpflocalizeextension.codeplex.com"
    lex:LocalizeDictionary.DesignCulture="en"
    lex:ResxLocalizationProvider.DefaultAssembly="WPFLocalizationExtension"
    lex:ResxLocalizationProvider.DefaultDictionary="StringResources">
    <Grid>
        <TextBlock Text="{lex:Loc ExampleTexts_HelloWorld}" />
    </Grid>
</Window>

上記のコードに関していくつか補足しておきます。まず5行目の式は見た目通り、WPFLocalizationExtensionの名前空間をlexという名前でXAMLに取り込むことを指定しています。なぜlexなのかは、公式サイトなどでそう推奨されているからとしか答えようがありません。
次の6~8行の式はこのXAMLファイル全体に影響するWPFLocalizationExtensionの設定です。具体的に上から"VSなどのデザイナーで表示する言語設定","WPFLocalizationExtensionがリソースを検索する際に使用するアセンブリー名","WPFLocalizationExtensionがリソースを検索する際に使用する.resxファイルの名前"となっています。これらの式はXAMLファイル中のいずれの場所にも記述できて逐次、設定を変更できるようです。
なお、ここに記すメモはRESXファイルをリソースとして使用することを前提としています。WPFLocalizationExtensionの機能として適切なILocalizationProviderを用意すれば、.csvや.xml、はたまた.txt,.jsonファイルなどもリソースファイルとして使用できるようですが、話が煩雑になるためここでは一切触れません。
さて、XAMLファイルを用意したら次は、リソースを作成します。公式サイトの説明によると、RESXファイルはVSで新規プロジェクトを作成した際にプロジェクト直下に作られるPropertiesという名前のフォルダーになければならないらしいので、その場所に今回はStringResources.resxという名前でRESXファイルを作成します。そして、このファイルに次のエントリーを追加します。
名前(key):ExampleTexts_HelloWorld
値(value):Hello world!
さらにそのリソースファイルを開いたままVS2012の場合は、ファイルタブの直下を見てください。
上の画像で示されたアクセス修飾子というプルダウンリストから"Public"を指定してください。これがないとライブラリーがリソースにアクセスできなくなってしまうようです。
ここまで作業が終わったら先ほどのXAMLファイルのデザイナータブを開いてみてください。全て正常に動作していれば、Hello world!という文字列を表示するウインドウがデザイナー画面に表示されるはずです。これでひとまず、WPFLocalizationExtensionから文字列リソースを扱う準備は整いました。ここからがいよいよ本領発揮となる多言語への対応です。ここでは日本語リソースを追加してみましょう。
まず、Propertiesフォルダー内にStringResources.ja.resxというファイルを作成します。そして、次のエントリーを追加してください。
名前(key):ExampleTexts_HelloWorld
値(value):こんにちは、世界!
エントリーを追加したら一旦IDEを終了し、適当なテキストエディターでIDEで開いていたプロジェクトファイルを開いてください。すると、そこに以下のような要素があるはずです。

<EmbeddedResource Include="Properties\StringResources.ja.resx">

この要素の中身を次のように書き換えてください。
<SubType>Designer</SubType>
<DependentUpon>StringResources.resx</DependentUpon>

書き換えが終わったらしっかり保存してIDEに戻りましょう。この状態でデザイナー画面を開き、XAMLファイル内のlex:LocalizeDictionary.DesignCultureの値をjaにすれば、晴れてウインドウ内に表示されるテキストが日本語化されるはずです。
これでWPFアプリケーションのグローバリゼーションは完了です。あとは、他の言語のRESXファイルを追加するなり、文字列以外のリソースを追加するなり色々試してみてください。WPFLocalizationExtensionは汎用性が高い分、使用方法が幾分煩雑になっていますが、適切な前準備さえ終えてしまえばコードに"WPFLocalizeExtension.Engine.LocalizeDictionary.Instance.Culture = 使用したい言語を表すSystem.Globalization.CultureInfoオブジェクト"の一文を追加するだけで表示する言語が変わるなど非常に使い勝手のいいライブラリーだと思います。



最後に、タイトルの(WPF編)という一言について補足します。WPF編と銘打っているからには今後、シリーズ化して他のプラットフォームでのグローバリゼーションの話題も出すんだろうなと突っ込まれても困ります。シリーズ化するかは未定です。

2013年3月23日土曜日

SharpDevelop用BVEルートファイル作成支援アドインベータ版公開のお知らせ

どうも、こんにちは。はざまです。3回連続でBVEネタです。
表題どおり、前回のポストで発表したSharpDevelop用BVE5ルート作成支援ツールのβ版を公開いたしました。ダウンロードに関してはα版と全く同じなので、前回のポストを参照してください。
α版に比べて、一部不完全だったコードコンプリーション機能の拡充を行い、
Track[a]
のような形の式に対しても、補完候補を提示するようになりました。このとき角括弧の中にカーソルがある場合には、角括弧の前にある型名に合わせてユーザー定義文字列も含めた適切な候補を提示するようになっています。
つまり、
"Sound["と入力する→ルートファイルのヘッダー部分に記述したSound.Loadコマンドからサウンド定義ファイルのパスを取得→その中身を解析して補完候補として提示する
というような感じです。その他にもコマンド名を入力後、開きカッコをタイプすることでそのコマンドに関するドキュメンテーションをツールチップで表示するようになりました。(なお、ドキュメンテーション内に記載されているコマンド引数の型名は当方で勝手に設定したものなので、ツールチップ通りの型を入力したのにBVE5にかけたら弾かれたというような場合にはご一報いただければ幸いです)
 まだ、正式版ではないので、バグや機能の不備など多々問題点があるとは思います(ただのルートファイル作成者の方にとってみれば、SharpDevelopでしか動かないという点が最大の不備かもしれません)が、ルートファイル作成者様方のお力添えとなれるよう、またBVE界の発展にも貢献できるよう今後とも尽力してまいりたいと思います。

(そろそろ、技術系ブログらしく技術ネタを一個くらい挟みたい・・・ )

2013年3月7日木曜日

SharpDevelop用BVE5ルート作成に役立つアドイン

どうもご無沙汰です。はざまです。(もはやこの挨拶が定型化してしまっているな…)
今回も、前回に引き続きBVEネタです。え~、率直にいってしまうとタイトル通りなんですが、それだけでは記事にする意味が無いので、まずダウンロードはこちらから。まだアルファリリースなので、githubからしかダウンロード出来ません。前回の記事同様に、上方左側にあるZIPボタンをクリックしてZIPファイルをダウンロードして下さい。その後のインストール方法については、解答してできたフォルダー内のreleaseフォルダーにあるreadme_ja.txtに詳述してあります。

ここからは、簡単にこのアドインの機能の説明と今後のBVE関連のプログラムに関する展望を記したいと思います。
まず、アドイン自体の機能についてですが、テキストエディターでのルートファイル作成の支援としてシンタックス・ハイライティング(簡単にいえばテキストの色付け機能)、コードコンプリーション(コマンド名を自動で提示・補完する機能)、その他ルートファイル作成時に役立つ機能として、距離程の一括シフトと簡単なカント計算機を実装してあります。
このうち、後者ふたつに関しては、BVE5メニューから呼び出すツールとして実装されています。
距離程の一括シフト機能は、選択された範囲またはルート全体の距離程を一斉に指定した数値だけシフトさせる機能です。この機能を使えば、いままではかなりめんどくさかったルートの原点方向への拡張も容易になるはずです。
一方、カント計算機はその名の通り、列車の通過速度、曲線半径および軌間から適切なカントの値を算出する計算機です。現在のところ、カント算出のアルゴリズムには物理的な観点から見て乗客が感じる遠心力が0となるような条件を元にカントを導出するというアルゴリズムを使用しています。現実にはこのような理想的な環境にはならないですし、各鉄道会社によって規定があるようなので必ずしも正しい値が算出されるとは限りません。あくまでも目安程度にお考えください。
この他にも実装予定の機能がありますが、現段階ではまだ実装されていません。正式版公開までに機能の拡充及び安定化を図る予定です。
最後に今後の展望についてですが、まずはSharpDevelopのアドインとして正式版公開を目指します。また、それとほぼ同時か1ヶ月位内程度にこのアドインの機能を使用したスタンドアローンなテキストエディターをリリースする予定です。というのも、SharpDevelopにはBVE5のルート制作に不必要な機能が沢山付いており、無駄に重くなってしまうため、またSharpDevelop自体の日本語化が公式でサポートされていないためです。個人的にはそれでも一向にかまわないのですが、やはりルート制作者様の役に立ちたいことを考えると、日本語のネイティブサポートは必須事項だと考えています。(ちなみに、このアドイン自体の日本語用リソースは用意してあるので、何らかの方法でSharpDevelop自体の日本語化を実現出来ればこのアドインも日本語で使用できるようになるはずです)
さらに、そちらの独立版テキストエディターも安定化してきたら、GUIによるCADソフトライクなインターフェイスでのルート作成機能などをも実装してBVE5のルート製作用統合開発環境にまで発展させたいという野望もありますが、果たして実現できるのやら・・・

2013年1月30日水曜日

BVE5用の京王線快速2001列車をATC化する作業を自動化するスクリプト

ご無沙汰してます、はざまです。時が経つのは速いもので、もう2013年も一ヶ月がたとうとしていますね。さて、今回はいつもとちょっと毛色の違う話題をしようと思います。といっても、最終的にはプログラミングの話に落ち着くんですけどね(^_^;)


話は年が明けたのを機に調子が悪くなっていたデスクトップPCのビデオカードを入れ替えたところから始まります。自身初のNvidiaだったので、ドライバー入れるまでにWindowsUpdateのせいで何回も再起動させられるなど、紆余曲折を経て無事セットアップを終え、GeForce660の性能を試してみたくていくつかゲームを試してみたんですが、GPU負荷的には余裕がある。こりゃ、今持ってるゲームじゃ660をフル回転させるのは無理だなと判断して普段使ってるノートPCでは起動できないBVEを久しぶりにやろうと考えてなにか面白そうなルートはないかグーグル先生に訊いてみたら、次のような記事を発見したわけですよ。
これは面白そうだということで、早速櫻井 倫氏作成の2001列車ルートを落としてきて書き換えを始めたんですが、作業を始めて20分ぐらいしてから全部手作業でやるのはかなりめんどいことに気づいたわけです。手作業がめんどいんなら全部自動化すればいいよねということで、今回の本題であるPythonスクリプトにご登場願えるわけですよ。
当のPythonスクリプトはこちらからダウンロードしてください。ページ上部左の"ZIP"ボタンを押せばZIPファイルでダウンロードできるはずです。以下、このスクリプトの使い方の解説に入りますが、多少、コマンドプロンプトなどのコマンドラインの知識が要求されることとPython2.7.3のランタイムがインストールされている必要があることを予めご了承ください。

  1. まず、落としてきたZIPファイルを解凍しましょう。今回使用するのはその中のko_2001というフォルダーの中身です。(まあ、まだko_2001以外にフォルダーがないので、迷うことはないとは思いますが)
  2. 櫻井 倫氏のウェブサイトから2001列車のルートデータを、BVE公式サイトからデータコンバーターをそれぞれダウンロードしてきて解凍します。
  3. 2001列車のルートデータをデータコンバーターに通してBVE5で動く形式にします。(一旦、次のステップに行く前にこの状態で本当にBVE5で動作するか軽くテストしてみるといいでしょう。)
  4. ステップ1で解凍したko_2001フォルダーの中身をBVE5用に変換された2001列車データフォルダーに移動します。標準なら"マイドキュメント\Bvets\Scenarios\"にあるはずです。(このステップは、ステップ6で使用しているコマンドの意味がわかる人は飛ばしても構いません。)
  5. 次にコマンドラインを起動し(Windowsの場合Vista以降か7以降かは定かではありませんが、標準でコマンドプロンプトかWindows PowerShellという2種類のコマンドライン(っぽい)環境が使用できますが、今回のスクリプトはコマンドプロンプトの方でのみ動作確認をしております。Cygwinとか入れている人はそれを使ってもいけますが、コマンドプロンプトに合わせてエラーメッセージのエンコーディングをS-JISに設定しているので、エラーメッセージが文字化けします(多分)。Cygwin使いの人たちはf*ck you cmd.exeとでも叫んでおきましょう(^_^;) )先ほどko_2001フォルダーの中身を移動したディレクトリーに移動します。
  6. コマンドラインに次のコマンドを入力します。
    ko_2001フォルダーの中身を移動した人:
    > python ko_2001_bve5-ify.py Map.txt (なにか適当なファイル名:例えば、Map_ATC.txtなど)

    ko_2001フォルダーの中身を移動しなかった人:
    > python (上記のスクリプトへのパス) Map.txt (なにか適当なファイル名:例えば(ry)
以上で、このスクリプト自体の使い方の解説は終わりです。あとは、シナリオファイルや車両ファイルなどを書き換えれば晴れて2001列車をATC環境で運転できるようになります。運転できるようになるんですが、はっきり言って停車パターンが鬼畜です。全線運転して初見で一回もパターンに引っ掛けずに運転するなんてはっきり言って無理でしょう。あんな鬼畜な停車パターンに毎日耐えて運転しているKOの運転士たちはきっとドMに間違…おっと誰か来たようだ。

今回の2001列車ATC化プロジェクトはここでおしまいですが、今後も(面白そうなルートとやる気があれば)BVE5-ifyプロジェクトと題して今回のようなPythonスクリプトを不定期で公開していくかもしれません(もっとも、今回のはBVE5ならではの機能は一切使っていませんが)。もしもシリーズ化することになったら、そのときはお付き合いください。

なお、このスクリプトを使用したために発生した不具合に関しては一切責任を負いかねますので、予めご了承ください。また、Python 2.7.3以外での動作は保証しかねます。