コミケ告知

サークル活動の詳細は circle タグの記事へ。
2013年2月9日土曜日

RxJavaをScala(+SBT)から試してみる

# はてなダイアリーから移動した記事です。あまり真面目に整形していません。

C#のReactive ExtensionsのJava版*1であるRxJavaが、NetflixからApache License Version 2.0で公開されていました。

Rxについては

SBTのコンフィグレーション

rxjava-scalaへの依存性を書けばOK。依存しているrxjava-coreも取ってきてくれるので。

libraryDependencies += "com.netflix.rxjava" % "rxjava-scala" % "0.5.+"

最初見たときは0.5.0でしたが、今見たら0.5.1でした。

動作確認

ScalaAdaptorでテストに使われているサンプルほぼそのまま*2。くだらないけど、これが動かなければ設定がおかしいので、まずはここから。

    Observable.toObservable("1", "2", "3").take(1).subscribe(Map(
      "onNext" -> ((callback: String) => {
        println("testTake: callback = " + callback)
      })
    ))
run
[info] Running info.moccos.Main
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
testTake: callback = 1

動いているようです。
SLF4Jが邪魔ですが、ログは今は出なくてもいいので見なかったことに。(以後のログでも省きます)

java.lang.RuntimeException: Unsupported closure type というエラー

サポートしていない型をObservable.toObservableに渡すと、そんな型知らんとRuntimeExceptionを飛ばされます。最初、rxjava-core(ScalaのAdaptorがない)を引っ張ってきていたときに遭遇しました。

もう少し使ってみる

    val xs = 1 to 10
    Observable.toObservable(xs)
      .take(3)
      .subscribe(Map(
        "onNext" -> ((x: Int) => {
          println("testTake: callback = " + x)
        })
      ))
[info] Running info.moccos.Main
[error] (run-main) java.lang.ClassCastException
java.lang.ClassCastException
[trace] Stack trace suppressed: run last compile:run for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
        at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) Nonzero exit code: 1

ぬ?
ここでonNextで拾う型をとりあえずAnyにしてみると…

testTake: callback = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

お、おう。テストコードにあったようなtupleだと、ScalaAdapterが直接変換してくれて上手くいきますが、コレクションの変換はまだ実装されていないみたいです。明示的にJavaの理解できる型を渡してあげないと。

    val xs: java.util.List[Int] = 1 to 10

または

    Observable.toObservable[Int](xs)
[info] Running info.moccos.Main
testTake: 1
testTake: 2
testTake: 3

これはOK。ちなみにStreamの無限数列を渡したら、無限に数えます。push型=値を生成できる限りどんどんpushするのだから、そりゃ当然か。

使える操作

rx-coreのpackage rx.operatorsを見ればわかりそうです。

参考までに本家Rxのものは…もう2年半前で古い記事ですがこれを。

合成したり取得する値を選んだりという基本中の基本だけ備わっている状態です。それから、onCompletedって書いても動いてくれないみたい。まだ趣味プロジェクトの範囲内かなあ。時間系が入ってくると面白いんですが。
pull requestにあるように、Netflixの狙い通り(?)にいくつか飛んできているので、興味を持った人たちによってじわじわと増えるのでしょう。*3

雑感

生まれたてです。既に実戦投入されたものを公開したわけではないので、これからみんなでがんばろうぜ!と煽っている段階ですね。
Scalaだと、Akka発のFutureが強力だし、元々マッチングも手軽に色々できるので、rxjavaすげー!世界が変わる!ということにはならないかもしれませんが、今後どうなるのか楽しみではあります。

*1:JVM版と呼ぶべきかどうか

*2:テスト文取って改行を足した。

*3:お前も参加しろと言われると、力不足ですまんと答えるほかない…

2013年2月6日水曜日

Raspberry Piでboostの使えるクロスコンパイル環境を構築

# はてなダイアリーから移動した記事です。あまり真面目に整形していません。

Raspberry Piはいいハードウェアですが、これの上でコード書いたりコンパイルしたりというのは大変です。入出力が弱いこともあって、C++のSTLやboostのヘッダをincludeすいると悲しいことになります。GNU screenの上に妙なプラグインがいくつも走るVimをたくさん開く開発スタイルもきつそう。

distcc(分散コンパイル環境)を走らせれば…と一瞬思いましたが、Raspberry Pi上のリソースを使う意味が皆無なので、まっとうなPCの上でクロスコンパイルすることにしました。

試した環境

Windows上で走っているVirtualBox内の、64bitのDebianです。

Linux version 2.6.32-5-amd64 (Debian 2.6.32-46) (dannf@debian.org) (gcc version 4.3.5 (Debian 4.3.5-4) ) #1 SMP Sun Sep 23 10:07:46 UTC 2012

クロスコンパイル環境の構築

参考記事:How to build a cross compiler for your Raspberry Pi | Chris's Digital Realm
多少のバージョン番号の違いはあれど、上記記事の箇条書きに従って進めれば、あっさりとクロスコンパイル環境が出来ました。

微妙にはまったところは…

  • ディスク容量は4GBでは足りなかった
    • 仮想マシン等でディスク容量が限られる場合や、RAMディスク上で済ませようとする場合は注意
  • C++を使いたい場合は、参考記事の手順では足りない
    • コメントにある通り、C-compiler → Additional supported languages and enable C++を有効にする
  • rootユーザーで作業しないこと

rootユーザーについては、ct-ng menuconfig内に警告文があります。以下引用。

You normally do *not* need to be root to build a toolchain using crosstool-NG.
In fact, it is *VERY* dangerous to run as root, as crosstool-NG will, as part of the build process, remove a few directories.
If anything goes wrong, running as root can ruin your host distribution.

変な設定してrootで走らせると、OSごとまともに動かなくなる可能性もあるよ!という警告。警告文があるだけでなくて、何か所かそれっぽい設定にチェックを入れないと実行も出来ません。

全てが無事終わると、/opt/cross/x-tools/arm-unknown-linux-gnueabi/bin 以下に、arm-unknown-linux-gnueabi-xxx といった名前のものがごろごろしているので、これらを用いればあっさりとクロスコンパイルが出来ます。

% arm-unknown-linux-gnueabi-gcc main.c
% file a.out a.out: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.7.3, not stripped

boostの準備

ヘッダだけで済むものは何の苦労もないですが、ライブラリをリンクする必要のあるものはboostをビルドする必要があります。たぶん。
めんどいので完成品をいただきました。
→ Raspberry Pi • View topic - Boost C++ libraries for Raspberry Pi

適当なコードを書いて…

#include <stdio.h>
#include <unistd.h>
#include <boost/thread.hpp>

int main(int argc, char **argv) {
  bool enabled = true;
  boost::thread th1([&enabled](){
    while (enabled) {
      printf("hoge!\n");
      sleep(1);
    }
  });
  getchar();
  enabled = false;
  return 0;
}

適当に必要なパス情報を与えてコンパイル。-Lのパスは必要なもの(*.so)を置いた場所によりけり。この場所に置くのが妥当がどうかは知らないけども…

% arm-unknown-linux-gnueabi-g++ -std=c++11 bthread.cpp -I/usr/include -L/opt/cross/x-tools/arm-unknown-linux-gnueabi/lib -lboost_thread

scpでRaspberry Pi上に送って実行。Raspberry Piの環境には、apt-getでboostのライブラリを導入してあります。
raspberrypi ~% ./a.out
hoge!
hoge!
hoge!

動いた。本日ここまで。

2013年2月3日日曜日

GNU findの-regextype指定をどうにかうまく出来ないか

GNU findで正規表現を使いたい場合、デフォルトはエスケープがたくさん必要で使い勝手の悪いemacs正規表現です。というところまでは以前調べました。

毎回-regextype posix-egrepと打つなど本末転倒なので、findとタイプして呼び出すだけで自然についてきて欲しい。そこでまずは、安直にシェルのaliasで解決しようとしました。

alias find='find -regextype posix-egrep'

これで安心と思いきや、探索先のパスを指定すると…つまりカレントディレクトリ以外から探そうとすると動きません。

(上記aliasのfind)
% find ./hoge -regex ".*\.(h|cpp)"
find: paths must precede expression: ../
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

パスは、-regexや-regextypeより前に置けと。エイリアスを使わない形で書くと、次のような形式が正しいようです。

% find ./hoge -regextype posix-egrep -regex ".*\.(h|cpp)"

それならば、最初の引数だけ前の方に動かすシェル関数でも書くか、と次に思いました。簡単な検索ならばそれでOKですが、まだ問題があります。Usageに示されているように、パスよりも前に書く必要のあるオプションがあり、これを真面目に考えるとさらに面倒になります。

% find ./hoge -L -regex ".*\.(h|cpp)"
find: unknown predicate `-L'

これらのオプションは0個以上で不定なので、引数の位置で判断するわけにいかないし、かといってパスを字面から判断するのもなかなか困難でしょう。

-D (デバッグ) と -Olevel (検査の最適化)は使わないと割り切り、-H -L -P(シンボリック関係のオプション)があったら-regextypeの前方に動かして、残りの引数の先頭が-で始まらない場合(=パス)をそれらと-regextypeの間に動かす(という挙動をするシェル関数なりスクリプトなりを書く)、あたりが手抜きの妥協点かなと思いました。

実際作ってみたら、こんな下らない事なのに意外と長く… → [Perl] GNU find wrapper to set -regextype.

2013年2月1日金曜日

Operaの怪しいショートカットを修正してやる!

# はてなダイアリーから移動した記事です。あまり真面目に整形していません。
  • Ctrl+kで検索しようとすると「アカウントを作成する必要があります」とポップアップが出る
  • Ctrl+Tabでタブを巡回しようとすると、2つのタブを往復する

ChromeやらFirefoxやらをメインに使っていると、この不要なオリジナリティにストレスがたまるため、AutoHotKeyになんとかしてもらいました。



ついでにCtrl+PageUp/Downも入れてみたけど、こっちは自分では使っていません。

検索については、Ctrl+eならば IE/Firefox/Chrome/Opera のデフォルト設定で検索が出来るので、そちらにシフトした方が良さそうですね。
Ctrl+Tabは、Operaだけ挙動が違うのでお仕置きが必要です。

ちなみにブラウザを複数使う理由は、SNSの類にログインするブラウザと、普段Webを巡回するブラウザを分けたいからです。Flashを使えば*1クロスブラウザで情報を取れるし、そもそもIPアドレスが同じなので大きな効果は期待できないものの、うっかりワンクリックで(ログイン状態の)SNSに何か投稿してしまうことは防げます。

*1:一応Local Shared Objectを消すアドオンを走らせてはいるけれど…

2013年1月15日火曜日

viユーザー専用PS3コントローラーを作ってみた

# はてなダイアリーから移動した記事です。あまり真面目に整形していません。

PS3コントローラーの配線を外に引っ張り出して、テンキーを繋いでみました。
ゲームのコントローラーの入力(=スイッチ)を引っ張りだして挿げ替えただけですが。

f:id:moccos_info:20130115063320j:image:w300f:id:moccos_info:20130115063333j:image:w300


動画版も作ったんだけど、動画にして面白いものではなかった…(゚Д゚) 原理的にはとても単純だし、見た目がすごくなるわけでもないので、不向きでしたね。
D

動機

東方シリーズでSTGを覚えたため、キーボード操作でしかSTGを遊べない身体になっていました。PS2のSTG買っても、十字キーではとてもプレイする気にならなかったのです。勿体ないので、いつか作ろうとは思っていました。
コントローラーの入力スイッチ部分に、カーソルキーに相当する入力デバイスの出力を繋げれば出来るので、回路は簡単です。外形加工は多少めんどくさいですが…。

昨年末に、そろそろ作ろうかなーと思い立ったとき、ちょうどVimを使い始めの頃だったので、ついでにVimのカーソルキー配置にしようかという余計な考えが混入し、こうなりました。

素材

市販の適当なPS3コントローラーと、適当なUSBテンキーを組み合わせました。特定の製品に依存するようなことはないので、好きなもの(安いもの)を使えば良いはずです。今回使ったのは以下の製品。



コントローラーはSTG目的なので、有線を選択しました。この製品は安いし、レビューを見るとPS2規格ソフトウェアでも動作するようなので選びました。
テンキーはスイッチ部分しか使わないので、入力感に拘るつもりがなければ、安さ追求で良いでしょう。秋葉原だと200円くらいで売っているのも見かけました。運がよければ、100円ジャンクにもあるかも。

工作 - コントローラー側

十字キーの入力を外に引っ張り出すのみです。原理としては一切難しいところはありません。

f:id:moccos_info:20130115063317j:image:w200f:id:moccos_info:20130115063316j:image:w250
スイッチの金属らしき部分はソルダーレジストが乗っているのか、半田付けできませんでした。しかし、どのキーの近辺にも半田付けできるエリアが用意されていたので、ありがたくそれを使わせてもらっています。何のためにこうなっているのかは謎です。


f:id:moccos_info:20130115063318j:image:w250f:id:moccos_info:20130115063314j:image:w250
何かで使った余りの基板の欠片があったので、内部と外部を接続するようにネジ止めして、外側にピンヘッダを付けました。

工作 - テンキー側

分解

以前外付けHDDを分解したときに少し大変だったので身構えていましたが、突くと開くタイプの簡易ツメ+底面のネジで組み立てられていて、綺麗に簡単に分解できる製品でした。底面のゴム足シールの裏にネジが隠されているのに気づかず、筐体の端にでかい穴を開けてしまいましたが、そんなことは不要でした。
f:id:moccos_info:20130115063319j:image:w300

メンブレンスイッチ

メンブレンスイッチの構造については、以下の記事がわかりやすく、参考にしました。

導電インクで回路が印刷されたシートが2枚、絶縁用のシートが間に1枚。
f:id:moccos_info:20130115063330j:image:w300

絶縁用シートにはボタンが押される部分に穴が開いていて、キー入力によりそこが接触し、表・裏間が接続されます。こんな簡単な仕組みだったとは。
流用するためには、端に引き出されている部分のどの線がどう配線されているか、解析する必要があります。このシートに直接半田付けしようとすると溶けてしまうので、無難に元々の配線パターンに従って、端から引き出すことにしました。シートの位置固定の問題もあるので、余計なことはせずに、USBテンキーの元々の形態そのままになりました。使うのはキー4つだけなんですけどね。

f:id:moccos_info:20130115063332j:image:w250f:id:moccos_info:20130115063331j:image:w250

配線パターンは、この製品では以下のようになりました。fが表、rが裏です。製品ごとに違ったり、同じ製品でもロットにより改変がされる可能性もあるので、データそのものが誰かの役に立つものではありませんが。

f:id:moccos_info:20130115084333p:image

当然、それぞれの穴が表裏1つずつと繋がる構造になっています。これなら4/5/6/+を使うのが一番簡単そうですね。ただ今回、間違えて10pinの変換基板を用意してしまい、端を落とす必要があったため、1/2/3/Enterの横並びを使う事になりました。
実は変換基板の値段がテンキーと同じくらいかかっていて微妙感溢れるものの、量産しない場合に390円のコストはまあOKということにしましょう…
f:id:moccos_info:20130115063326j:image:w250

次の写真は、もともと入っていたUSB接続の基板とコネクタ。ここに半田付けして引っ張りだしても良かったかなあ。
f:id:moccos_info:20130115063325j:image:w300

外部への引き出し

コントローラー側と同様に、筐体に穴をあけて基板を通し、内側をネジ止め・外側にピンヘッダという構成です。
f:id:moccos_info:20130115063322j:image:w250f:id:moccos_info:20130115063324j:image:w250
ネジ穴を適当に開けたため、ちょっと曲がっているのがださいですが、誰も見ませんこんなところ。

使用感

viのカーソルキーが全く身についていない状態なので、まだ上下移動がうまくできません。さらに、ナナメ移動のときに1個空きに同時押しするのが直感的に難しいです。
そして、ゲームをする際には当然4本指を固定で置きますが、本来HJKLはJがホームポジションなので、指使いがちょっと違います。JとKの位置関係は覚えられるかもしれないけれど、指使いを脊髄に叩き込むとまでは行かないかもしれません。


また、実は左手で通常コントローラーの右手部を操作していることにも、ちょっと無理があります。こっちも左手用のテンキーを用意するのがベストなのかもしれません。もうやらんけどw

2013年1月4日金曜日

Windows上でVisualStudio 2010と2012用にboostをビルド(x86/x64)

# はてなダイアリーから移動した記事です。あまり真面目に整形していません。

意外とめんどくさくて、次忘れそうなのでメモ。

ビルド環境

cl.exeでビルド。環境変数の設定がたくさんあって大変なので、無理せず、スタートメニューから辿れるビルド環境のコマンドプロンプトを使います。

  • Windows SDK 7.1 Command Prompt
    • Microsoft Windows SDK v7.1の下にある

Visual Studio 2010のVisual Studioコマンドプロンプトだと、x86(32bit)しか作れないっぽいので、x64(64bit)のライブラリをビルドするのには必要。そもそも64bitバイナリをビルドする人はインストールしているはずですが。
Visual Studio 2012ではx86用とx64用のプロンプトが選べるので、2012だけならそちらで良いかも。

x86/x64の選択

setenv でさくっと設定できます。

Usage: "Setenv [/Debug | /Release][/x86 | /x64 | /ia64][/vista | /xp | /2003 | /2008 | /win7][-h | /?]"
/Debug - Create a Debug configuration build environment /Release - Create a Release configuration build environment /x86 - Create 32-bit x86 applications /x64 - Create 64-bit x64 applications /ia64 - Create 64-bit ia64 applications /vista - Windows Vista applications /xp - Create Windows XP SP2 applications /2003 - Create Windows Server 2003 applications /2008 - Create Windows Server 2008 or Vista SP1 applications /win7 - Create Windows 7 applications


Debug版とRelease版両方一度にビルドしてくれるので、そこを設定する必要はなさそうです。
> setenv /x64
または
> setenv /x86


ビルド時の引数による設定

まず、ビルド用の準備(共通)。解凍したboostソースコードのトップディレクトリで、バッチファイルを一撃。

h:\>cd boost_1_52_0
h:\boost_1_52_0>bootstrap.bat


あとは必要に応じてbjamへの引数を変えます。
参考:c++ - 64-bit version of Boost for 64-bit windows - Stack Overflow

  • ターゲットバージョン
    • --toolset=msvc-10.0 など
      • 9.0が2008、10.0が2010、11.0が2012
  • 出力先
    • --stagedir=x64 など
    • 指定したディレクトリの下にさらに lib が掘られて、そこに出力される

例:

bjam --toolset=msvc-11.0 --build-type=complete --stagedir=x86 stage
bjam --toolset=msvc-10.0 address-model=64 --build-type=complete --stagedir=x64 stage


64bit環境にしても、address-modelを設定しないと32bitになります。

32bitのビルドが行われる場合の、ビルド開始直後の表示例。
Performing configuration checks
- 32-bit : yes - x86 : yes


64bitのときは、32-bit の項目が表示されませんでした。(noと表示されるわけではない)
Performing configuration checks
- x86 : yes


出力ファイル

出力ファイル名は boost_random-vc100-mt-1_52.lib のように、コンパイラのバージョン入りになるので、バージョンごとに最終的な置き場所を変える必要はなさそうです。ファイル名のboostバージョンの前の部分に、gdと入っているのがデバッグ版です。boost_random-vc100-mt-gd-1_52.lib など。
ただし、どうやらこの長い名前をプログラマが意識する必要はなさそうです。

リンク

ヘッダをincludeしただけでビルドすると動いてしまい、なんだこりゃ?とヘッダを追いかけてみると、どうやら環境を判断して必要なlibファイルの名前を生成し、勝手にスタティックリンクしてくれているようです。あちこちに転がっているconfig.hppや、config/auto_link.hppなどが暗躍しています。
どうやらダイナミックリンクにしたい場合は…

  • boost関係全てDLLにするなら、BOOST_ALL_DYN_LINKを定義
  • 特定のライブラリのみDLLにするなら、BOOST_PROGRAM_OPTIONS_DYN_LINKのような個別定義を使用

2013年1月3日木曜日

2012年に覚えた(はずの)事一覧

# はてなダイアリーから移動した記事です。あまり真面目に整形していません。

プログラミング関係で何か覚えるたびにTwitterにポストしていたものの振り返り。
Twitter記法並べたらクソ重いなあ。




言語はJavascript(主にjQuery)、Erlang、Java、Scala、C++、まれにC#やPython。環境はVimとgitが多めでした。
覚えた、って書いてもその後二度と使わないようなものは、見事に忘れてます。tmuxはCygwinで動かなかったから使わなくなったし、Vimで画面分割するのに慣れたからGNU screenでの画面分割も使っていないなあ。


しばらくErlangは使わないだろうから、完全に忘れちゃうかもしれません。一昨年少し触ったHaskellは、もはや入門からやり直さないといけない程度に忘れました。うーん勿体ない。Java・Scala・C++はそれなりに進歩、C#・Python・R言語は実力キープ~やや前進という程度でした。
2012年に新しく覚えた言語が無かった気がするけれども、中途半端に手を出しても使わなければ忘れてしまうので、HaskellかC#あたりを強化する方向にしようかなー…と思います。全く新規の物の方が面白いけれども、これ以上器用貧乏で手を広げるより、何か小さくても自慢できるようなものが出来る程度に、何かに専念した方がいいかなーと。