2018年7月15日 (日)

「無限ループが発生してもハングアップしません」

最近、Unreal Engine の勉強を(少しだけ)していて、今日は「UE4 ブループリント超入門編」を読んだ。今までブループリントというのは、ゲームに必要になる典型的な処理だけをビジュアルにプログラムできるシステムだと思っていたので、基本機能が一通りそろっていて万能なのだという話は目からうろこだった。

それはともかく、この記事の最後の方にこう書いてある。

ちなみにブループリントは優秀なことに無限ループが発生してもなんとハングアップしません。かわりに無限ループが発生したと判断すればエラーになってエディターに戻ってきますので、安心して実行できますのでご安心ください。

ぱっと見、「止まらないコードはすべて検出してエラーにする」と言っているように見えるが、ブループリントが万能である以上、もちろんそんなことは不可能だ。そこで、実際に無限ループするブループリントを作って試してみた。いや、停止問題とかそういう高級なヤツじゃなくて、ばかみたいなやつ。

Infiniteloop

元記事にならって疑似コードで書けばこんな感じだ。

EventBeginPlay()
{
    while (true)
    {
        PrintString("Iterating...");
    }
    PrintString("Done.");
}

これをコンパイルすると…コンパイルできてしまう。VisualStudioだってコンパイル時にエラーを出す(「無限ループ」とは言わず、「while の後ろの PrintString に至るコードパスが存在しない」とかなんとか言うんだったと思うが)くらいの単純な例なのだが。コンパイルできたので動かしてみると、一瞬画面いっぱいにIterating...が並んで、エラーで止まった。Infinite Loop detected と言っている。なるほど、確かに実行時検出はできているようだ。だが停止問題は実行時にも検出できないはずだし、そもそも1周目では検出できないのに何周か動いたところで検出できるというのも奇妙だ。どういう風に検出しているのだろうか。いろいろ調べたところ、どうやらブループリントでは、「コードの同じ個所を100万回実行したら無限ループとみなして止める」という感じのことをやっているらしい。

なるほど。それならできる。お手軽でナンチャッテ的な手法だが、1フレーム時間(約17ms)を超えて動き続けるコードが(「無限」ループであろうとなかろうと)許されないゲームのスクリプトとしては、非常に実用的なデバッグ法なのだろう。これもまた目からうろこだった。

2018年5月13日 (日)

Wraith PrismクーラーのLED配線と制御

連休中にRyzen 7 2700xを買ったのだが、これにバンドルされているWraith Prismと称するクーラーにはLEDがたくさんついている。それはいいのだが、LEDを制御するための配線でハマったのでメモしておく。
 
このクーラー、ファンを回転させるためのケーブルに加え、LEDを制御するためのケーブルが2本も出ている。箱から出した時点ではコネクターがあり、ゴムのフタがかぶせてあるが、専用ケーブルが2本ついている。以下の画像は4Gamer.netの記事にあったものだが、両方刺すとこんな感じになる。(画像クリックで拡大。)
012
 
これが、間違いの始まり。
 
実は、このLED制御ケーブルは両方刺してはいけないのだった。
クーラー側4ピン、マザボ側専用4ピンのケーブル(上の画像の左側)は配線しなくていい。クーラー側3ピン、マザボ側USB10ピンコネクターになっているケーブルだけ配線すればいいのだ。というか、私のように両方配線してしまうと、うまく発光をコントロールできなくなってしまう。
 
私が使っているマザボはAsRockのAB350M Pro4というものだが、その取説にもこんなイラストが入っていて、いかにも両方刺せと言っている。
Ab350mpro423
(もっとも、取説はよく読むと、「Please note that only one cable should be used at a time」と書いてあった。とは言え、ケーブルを3本示して「only one」と言い、実際には図示しているケーブルのうち2本を接続する、というのは、やはり適切な説明とは思えない。)
だったら、どうしてこんな使わない4ピンケーブルが付いてくるんだ、そもそも無ければ間違えないぞ、という話だが、どうやら、従来のRyzenを含む2700x以外にバンドルされているLEDクーラーは専用4ピンケーブルで制御するので、ある意味、それとの互換用なんじゃないかと思う。(よくわからない。)
 
次に、この「USB」のコネクターをどこに刺すか、ということなのだが、結論から言うと、普通に内蔵USBコネクターのどこかに刺せば良い。だが、AB350M Pro4には「AMD LED Fan USB Header」という名前の(シルクはUSB_5だが)ヘッダーがあり、取説もそこに刺せと言っている。それで、そこに刺すものだと思ってしまった。
 
これが2つ目の間違い。
 
いや、ここに刺してもいいのだが、ケーブルのコネクターはUSBの2列10ピンなのに、実際に配線されているのは3本。また、マザボ側はピンが1列4本。これをどういう風に指すのかがわからず間違えたのだ。
 
結局正解は、USB_5の1/2/3/4番ピンに、USBコネクターの10ピンで言うところの6/7/8/9/10が来るように刺すことだった。上のイラストは、正解がわかってから見ると、確かに正しい刺し方を示しているのだが、この図から正しい刺し方を読み取れなかったのだ。
 
以上が正しい配線で、こう配線した後は、AMDのウェブサイトから「AMD Ryzen Wraith Prism RGB lighting control software powered by Cooler Master」という長い名前のソフトをダウンロードしてインストールすれば、すべてのLEDを好きなように設定できる。
 
なお、このソフトを初めて起動したときに、ファームウェアのバージョンアップがあると言われ、そのアップデートをすることになった。どうも、このクーラーにはLEDを制御するためのマイコンが入っていて、そのファームウェアをUSBで書き込めるようになっているようだ。

2018年5月 4日 (金)

Ryzen アップグレード

約1年前にRyzen 1700でPCを組んだのだが、そのCPUだけRyzen 2700Xにアップグレード。
(ただし、マザーボードのBIOS(というか、UEFI?)は最新版にバージョンアップしてある。)
おおむね各種レビューの通り、クロックが速くなった分だけCPUの動作性能が上がったという感じ。AMDの発表によると、CPUの動作クロック以外にキャッシュレイテンシーの大幅改善みたいなことも書いてあるが、それが利いているのかいないのか、よくわからない。使っているメモリが、DDR4-2400というRyzen的には遅めのものということもあるのかもしれない。
 
 

2017年10月20日 (金)

CancelEventArgs は Serializable じゃない

System.ComponentModel.CancelEventArgs は Serializable じゃない。だから remoting で渡せない。
 
だったらこんなの使わねーよ、自分で作るよ、たかが bool 一個なんだし、みたいな。
こうして、名前が違うだけで同じ内容のクラスがどんどん増える。再利用せずに。
System.ComponentModel という namespace の名前が空々しい。
 
というか、まあ、謎の誤動作の原因を調べたらこれだったという、俺の1日を返せ、みたいな。でも、なんというか、EventArgs 的なクラスはいつでも必ず絶対に Serializeable なものだと思い込んでいて、早い段階で間違った道に突き進んでしまったのが敗因なんですけど。
 
とはいえ、なぜ Microsoft がわざわざこれを Serializable なしにしているのか疑問ではある。さすがに「うっかり忘れました、テヘペロ」じゃないよね…。

2017年5月28日 (日)

久しぶりのPCアップグレード

10年くらい前は結構頻繁にPCの部品買っていたのですが、最近はあまりやらなくなってました。ふと気が付くと、最近のゲームが動きにくくなっていて、久々にアップグレード。
AMD Ryzen 7 1700
ASRock AB350M Pro4
G.Skill F4-2400C15D-32GVR (DDR4-2400 16GB CL15 x 2)
Samsung 960EVO (M.2 NVMe SSD 500GB)
久々だったので coldsweats01 これだけまとめて買い込みました。
 
Ryzenはメモリの相性が、みたいな話があるので心配だったのですが、適当に買ったモジュールで特に問題なく動作しました。
また、RyzenはUSB3が、みたいな話がありますが、今のところなにも問題起きていません。もっとも、手持ちの USB3デバイスはストレージだけで、残りのキーボード、マウス、ゲームコントローラーはどれもUSB2デバイスだから、かもしれません。

2016年8月27日 (土)

WPF で OpenFileDialog にコントロールを追加する

結論
  • Microsoft.Win32.OpenFileDialog をハックするのは困難。
  • それよりも Microsoft Windows API Code Pack の CommonOpenFileDialog を使う方が良さそう。
  • Microsoft Windows API Code Pack は nuget にある。
ということで、やはり自分で作るより出来合いのものを拾うのが吉ということか。
Microsoft Windows API Code Pack は、msdn のページも削除されて久しいし、メンテされていない。フォークをメンテしようとしている人もいるようだが、あまり活発ではない様子。ソースはあるので、自分に必要な個所だけ自力で直す覚悟をすることになるのだろう。
 
 

2015年10月18日 (日)

すし職人ロボット

東洋経済オンラインで「人間の生活は人工知能に脅かされるのか?」という記事を読んだ。その中の一部に疑問、というかイチャモン。
この記事では、1ページ目の最後に
人工知能搭載の寿司職人ロボットが、本物の寿司職人を凌駕する日が来るかもしれません。
と述べ、それを受けた「そうなると、寿司職人も失業してしまう?」という問いに対して
そうはならないでしょう。
ロボットを前にして寿司をつまむのが楽しいでしょうか。私なら、ベテランの寿司職人と会話を楽しみながら寿司を食べるほうがいい。
として、すし職人をりょうがするロボットができても職人は失業しないだろうと主張する。
本当だろうか?僕には、そうは思えない。
それは、すしを作るのが人間の職人よりも上手なロボットが実用化され、それが妥当な価格で供給されたら、すしはロボットに作らせ、客との会話が得意な(すし職人ではない)人間を接客用に雇うのが合理的だと思うからだ。たぶん、すし職人にも、客との会話が得意な職人も、得意じゃない職人もいるのだろう。客との会話が上手なことがすし職人の必須スキルなのであれば(そうなのかどうか、よく知らないが)、一流のすし職人は必ず会話が上手ということになるが、その場合は「会話が苦手というだけの理由で二流とみなされている、すしを作る技術は超一流の職人」みたいな人が大勢いるのかもしれない。
なんであれ、たぶん世の中には、そういうすし職人さんよりも、すしは握れなくとも会話が得意という人が大勢いるはずだ。会話が得意なすし職人と、会話が得意なだけの人とを比べたら、たぶん会話が得意なだけの人のほうが会話は上手なのではないか。少なくとも同程度の賃金で雇えば。逆に言うと、会話の技術が同程度の人を、すし職人でもある会話が得意な人よりは、会話だけが得意な人を雇ったほうが安上がりに雇えるだろう、ということだ。
そもそも、この記事自体が
人工知能が得意な分野は人工知能に任せてしまい、私たち人間は人間にしかできない、人間の脳が得意とする分野で力を発揮する。人間と人工知能が互いにすみ分けをしながら、共存していけばいい
と述べているのだ。すしを作るのは人工知能のほうが得意、というのが本当になったなら(冒頭に紹介した議論は、仮にそうなったら、という前提の話だ)、すしを握るのはロボットに任せてしまい、客が楽しく会話する相手をするという、人間にしかできない分野を人間が担当すればいい、という主張にどうしてならないのか。それがおかしいと思った。
ちなみに、実は僕は、「ベテランの寿司職人と会話を楽しむ」という感覚がさっぱりわからない。僕は、すし職人にかぎらず、外食店にも限らず、店員と会話したくない。口をききたくない。こちらから話しかけるのも、何か話しかけられるのもイヤだ。だから僕は、(店員と会話して注文を伝える必要のない)券売機で注文品を選べる店が好きだし、すし職人が作るすし屋でもカウンターじゃなくてテーブルに座りたいし、もっと言うと多少まずくても回転ずしのほうが好きだ(注文を口頭で伝える必要がないことのほうが、多少の味の良し悪しよりも、僕には重要なのだ。まぁ、値段が安いというのも魅力だが。coldsweats01)だから僕は、そういう人間の職人よりもうまいすしを作るロボットが実用化されたら、そもそも会話用に人間をやとうこともしない店(たぶん、そういうのも登場するだろう)を好むことになるに違いない。
まぁ、最後の部分は、たぶん、僕が変なヤツだと言っているだけで、元記事の問題ではないのだが。

2015年9月22日 (火)

今までに見た中で最低のWindowsのメッセージ

日本語版Windowsの出すメッセージは誤訳が多い。
昔(Windows 3.1 とか)のWindowsが出すメッセージは、誤訳というよりも日本語として成立していないようなものとか、文法上は日本語になっているが内容が意味をなさないものとかが多かったが、最近のWindowsのメッセージは、文法上まったく正しい流暢な日本語で、一見すると(その文だけを文脈なしに読むと)意味もよくわかるが、でも文脈と整合していないという類の誤訳になってきている。
でも、文脈と整合していなければ何かおかしいと気づく、それは素晴らしいことなのだなと、今日痛感した。それは、今朝Window 7からWindows 10にアップデートしたあと、こんなメッセージが出たからだ。
About_to_fail
「バックアップを保存するディスクに障害が発生しようとしています。」と言っている。これは、まぁ要はディスクが壊れかかっているという意味だと思うよね。ってゆーか他に考えられない。
この「バックアップの場所」というのは、実際には増設ハードディスクで、たぶんもう5年以上使っている。(バックアップされていた一番古いファイルは2012年4月というタイムスタンプだった。3年半経っている。)そろそろ壊れても何の不思議もない。SMARTなんてものもあるし、ドライブのファームウェアが不調を検出して、それをWindows 10になって機能強化されたバックアップソフトが教えてくれた、なんて、非常にまともなシナリオだ。文脈に照らしてもきわめて妥当だ。
…でも、そうじゃなかった。(だから誤訳の話から入ったわけだし。coldsweats01)
最初は、ディスクが壊れかけているのだと信じて、何も疑わず、ただ、どれくらい緊急なのかを知りたいと思っただけなのだ。それで、このメッセージをぐぐってみた。「このメッセージが出たらあと××日くらいで故障が起きると思いましょう」みたいな解説記事を期待したのだ。が、ヒットしない。1件もヒットしない。似た文言はいくらでもあるが、そのものズバリがない。
Windowsのメッセージで検索すると、たいていは対処法の記事がみつかるものなので、これには驚いた。ひょっとして、このメッセージは滅多に出ない、きわめてマレなものなのだろうか。確かに、Windowsの標準のバックアップソフトで自動バックアップを設定していて、そのバックアップ先を増設ディスクにしている人というのは、あまりいないのかもしれない。その少ない人数の人が、たまたまディスクの故障に遭遇するのはめずらしいことなのかもしれない。そう思った。
そこで、日本語版Windowsに比べれば圧倒的に利用者の多い英語版Windowsの同じメッセージで調べれば何かわかるだろうと思い、マイクロソフトのLocalized Error Message Lookupで英語のメッセージを調べた。実は、僕がここで英語メッセージを調べるのは、誤訳としか思えないメッセージをみつけ、その正しい意味が知りたい時だ。そのため、ひょっとしてこのメッセージも誤訳かも、という気が一瞬したが、どうも、そういうことではないようだった。
英語のメッセージは、「The disk that your backup is saved on is about to fail.」というものだった。この英文も、ディスクが壊れかけているという意味に見える。「バックアップを保存するディスクに障害が発生しようとしています。」という翻訳も、まったく妥当に見える。
それで、この英語のメッセージを検索してみると、記事がいくつか見つかったが、どれも「買って間もないディスクでこのメッセージが出た」とか「冗長構成NASでこのメッセージが出たが、NASの管理ソフトで診断しても何ら異常はみつからない」とか、このメッセージの内容が状況と整合していないと感じた人たちの当惑がフォーラムに投稿されたものだった。そして、その結論は驚くべきものだった。
このメッセージは、そういう意味じゃないのだ。ディスクが壊れかけているわけではないのだ。
フォーラムの回答によると、このメッセージが伝えようとしている内容は、「このままこのディスクにバックアップを続けると、バックアップ処理が失敗しますよ。」ということなのだそうだ。
びっくりだ。
では、バックアップがなぜ失敗しそうなのか。それは「システム イメージ」のバックアップをしているから、らしい。「システム イメージ」というのは、要はOSそのもので、Windowsをアップグレードすると、システム イメージの形式が変わって同じ場所に上書きでバックアップできなくなるのだそうだ。
そんなこと、このメッセージからは絶対にわからない。
どうやら、英語でも同じ状況のようで、英語のネイティブスピーカーが、そういう意味だとわかった上でこの「The disk that your backup is saved on is about to fail」という文を読み返しても、そういう意味に解釈するのは無理らしい。真相は不明だが、英語がへたくそな(でも、たぶんプログラムを書くのは上手な)エンジニアが書いた、英文として成立していない変な英文をテクニカルライターがチェックして、内容を誤解した上で「文法上正しいきれいな英文」に書き直したのだろう、みたいな話になっていた。うーん。まぁ、そういうこともあるかも。
ということで、本件の結論。
「バックアップを保存するディスクに障害が発生しようとしています。」というメッセージは、「ディスクが壊れかけている」という意味ではない。「このままの設定でバックアップを取るとソフトウェアの仕様によりエラーが起きる。」という意味である。
この奇妙な日本語メッセージの原因は誤訳ではない。おかしな英語のメッセージを正確にそのまま翻訳したことが原因。
いやはや。最低だ。

2015年7月12日 (日)

新骨言道、あるいは、WPFが言語を意識してフォントを切り替えているらしい件

 WPFには Language という dependency property (日本語では「依存関係プロパティ」と言うらしい) がある。このあたりに説明があるが、これを読んでも、どういう働きをするのかさっぱりわからない。

それで、ふと思いついてサンプルプログラムを書いてみたところ、どうやら font fallback (日本語では「フォンント フォールバック」と言うらしい) の選択に使っているらしい。いや、他にも使っているのかもしれないが。

と、いうことで、これがサンプル。(例によって、画像をクリックすると拡大します。)

Wpf1

バリバリのWPFプログラマーの皆さんには常識だったりするのかもしれないが、そういう層と、こういう地域による漢字の字体差に関心がある層との間にはかなり距離があるような気がする。後者の人たちは、マイクロソフトがどういう努力をしているか全然知らないんじゃないかという気もする。このサンプルを見て面白がっていただければ幸いです。

さて、プログラマ的には、見所は、

  • XAML の Label 要素には、それぞれ異なる Language 属性を指定しているが、フォントに類するものは指定していない。
  • フォントの指定は Window 要素に対して行っており、そこに FontFamily="Arial" と書いてある。

というあたり。

後者がどうして見所なのかというと、次のスクリーンショットを見るとわかる。

Wpf2

こちらは、Language の値によらず同じ表示になっているが、XAML 上の違いは、WindowFontFamily を削除しただけ。なぜ、そうなるのか、よくわかっていないのだが、どうやら Label/@Languageの働きは、最初からフォントを選ぶわけではなくて、フォント フォールバックに影響を与えるだけらしい、という気がする。

Visual Studio で WPF アプリの XAML 書いている人は先刻ご承知と思うが、Visual Studio のウィザードが生成する雛形 XAML には、FontFamily 属性はついていない。FontFamily 属性を指定していない XAML の要素のプロパティを Visual Studio で見ると、FontFamily のデフォルトは Meirio UI である、と表示される。(日本語 Windows で開発している場合。) この、「デフォルトは Meiryo UI」ということの意味も、よくわからないのだが、これは「実行時には Meiryo UI が使われる」ということではなくて、「FontFamily として Meiryo UI が指定されているものとみなす」ということのようだ。そうでないと、ここで観察した動作は説明できないように思う。

つまり、FontFamily="Arial" があると、各 Label では Arial を使って「新骨言道」と表示しようとするが、Arial というフォントにはそんな文字は含まれていない。それでフォント フォールバックの仕組みが働き、Language の値を参照してフォントを選択する。他方、FontFamilyがないと、まず FontFamily のデフォルト値として Meiryo UI が採用され、各 Label は Meiryo UI を使って「新骨言道」と表示しようとする。Meiryo UI にはこの4文字が含まれるのでフォント フォールバックの仕組みは働かず、Langauge が参照されることもない。そういうことなのだろうと思う。

いわゆる英語版のウィンドウズでは、フォントのデフォルトは Meiryo UI ではない。Segoe UI になるはずだ。Segoe UI にも、「新骨言道」は含まれない。ということは、上の 2 個目のサンプル プログラムは、完全に同一の XAML であっても、英語版の Windows で開発すると、1 個目のサンプルと同じ表示になるのだろうか。それとも、開発した環境じゃなくて、実行した環境によって、つまり 2 個目のサンプル プログラムは、英語版の Windows で実行すると、1 個目のサンプルと同じ表示になるのだろうか。いずれにしても気持ち悪いし、前者ならまだしも、後者だとすると、これはサポート担当者には悪夢じゃなかろうか。(この悪夢を避けるためには、Language 属性の使用を禁止するだけでいいのだろうが。

ちなみに、WPF ではデフォルトのフォントはどうやって決まるのか、という点は、世界中のプログラマを悩ませている謎のようだ。英語でそれっぽい検索をすると、様々な驚くべき現象に出会った人たちがみつかる。MSDN のサポート フォーラムにも似たような質問が多数ある。マイクロソフト側の人の回答は大抵の場合「様々な要因によって最適なものが選択されます」みたいな、意味がわからないものだ。たぶん、回答している人にもよくわかってないんじゃないかと思う。

2015年5月 3日 (日)

プライバシーポリシー

Google Playではコンテントレーティングを義務付けるので、今のうちにレーティングを付けておかないとアプリが削除されるよ。

Googleからそんな感じのメールが来た。いや、来たのは1月くらい前だけど、レーティングとかいかにも大変そうだったので、放置していたのだ。そうしたら、5月5日までにレーティングしないと削除するよ、っていうメールが来た。幸い連休でヒマなので、なんとかしようと始めたのだが。

レーティング以前に、Google Playではいろいろと必須情報が増えていて、まずそれを追加しないとレーティングに進めないという罠。大きなサイズの画像とか、そういうのはなんとかでっち上げるが、いきなり「プライバシーポリシーのURLが必須です」と言われても。

しかたないので、とりあえず一筆書き、ここに「掲載」したうえで、そのURLを設定。意味あるんですかね、こういうの。

そこを突破すれば、本題のレーティングは拍子抜けするほど簡単で、すぐにできました。質問10個ちょいにYes/Noで答えるだけ。結果は「3歳以上」。(13じゃなくて3歳。)3歳未満が除外されているのはなぜなのだろう。ま、いいけど。

ちなみに、設定したのは「これ」と「これ」です。たった今は従来の表示のままですが、半日くらいで更新されるはず。

※ まだGoogle Playのページは更新されていませんが、先にIARBからメールが来て、こういうのをもらいました。

より以前の記事一覧