投稿者「kitzz」のアーカイブ

仕事机を新調した

今まで仕事に使ってた机が微妙に体に合わなくて肩凝りなどの原因になってるように思い、仕事机を新調することにした。

そんで、いろいろ悩んでいろいろやって出来上がった仕事机がコチラ。

とても気に入っている。
電動で昇降し、高さを4つまでメモリーできる。
いま流行りのスタンディングデスクになるのだ。

以下、この仕事机が完成するまでのあれこれを備忘録として記録しときます。

当初はスタンディングデスクとして使うことは全く目論んでなかったりする。

単にキーボードとモニタの高さをミリ単位で調節できるようにしたいという要求から始まった。正しい姿勢でまっすぐディスプレイを見て、肩肘に力の入らない適切な手の位置でキーを打つために。

モニタはモニタアームで調節できるとして問題はキーボード。キーボードトレイを付けるにしてもその高さをぴったりの位置に調節したい。また机の上にノートパソコンを置いたりした時もやはりぴったりの高さにしたい。すると、無段階で高さの調節できる机じゃないとダメだよね?、と思ってネットで調べてもちょうどいいのはなかなかなくて、医療用か、もしくはスタンディングできる昇降デスクか、という選択肢になるのであった。

デスクを新調するにあたり、キーボードの置き場所としてこれを使うことを決めていた。

エルゴトロンのアンダーデスクキーボードアーム。机の下にしまえて高さも調節できる。
ところがこれ、キーボードトレイを机の下にスライドできる構造なのでそのレールを設置するために机の裏側に奥行き40数センチほどの平らな空間が必要になるのだ。
これがかなり曲者で、机の裏側はたいていフレームが横切ってたりして、40センチもの平らな奥行きを確保できるものは稀だったりする。
また、ネットで売ってる机のほとんどは天板裏側がどうなってるかの情報がまったくない。。。。
フレームが横切ってたりして平らな面を確保できない場合は角材をかましてそれらを回避するという手もなくもないが、せっかくの新調デスクがカッコ悪くなるのでやりたくない。

ネットでいろいろと机を物色したものの、このキーボードトレイがきちんと付く確証がないのでほとんどが脱落。

最終的に、以下のふたつの候補が残った

エルゴトロン WorkFit-D
エルゴトロンの昇降ワーキングデスク。エルゴトロンの机なので当然ながらエルゴトロンのキーボードアームが付く。
電動ではなくガス圧昇降式。電動だと高さの変更にちょいと時間がかかるが、ガス圧で少ない力加減でさっと希望の高さに変更できることをウリにしているようだ。
そして天板耐荷重30kg。
海外通販の電動昇降スタンディングデスク

具体的にはココ。 https://www.fully.com/jarvis-reclaimed-wood-standing-desk.html
日本でも岡村やサンワダイレクトなどいくつか電動昇降デスクを出してるところがあるのだが、少々値が張るのと少々大きすぎる。そして前述の通りアンダーデスクキーボードアームが直に設置できるかどうかわからない。
また、海外通販せずとも同じようなものを並行輸入業者と思しきところが楽天で販売しているのだが、直接海外通販すると細かいオプションとか選択できるのでそっちを利用することにする。

さて、それでかなり悩んだ末に、後者の海外通販を行うことにした。
 エルゴトロンの WorkFit-D でもよかったのだが耐荷重が30kgというのが気になった。もちろんそれが支障となる使い方はほぼ間違いなくしないのではあるが。。。 あとガス昇降ということで上に載ってる重さによって昇降の力加減が変わる可能性があることも気になった。
 一方海外通販の方はまずもって海外通販というのが面倒くさい。ただし、キーボードアームが付けられる算段は付いててしかも天板なしで電動昇降のフレームのみの販売もやってる、そしてオプションでキャスターを付けられる。いろいろカスタムできそうというのが決めてになった。また机の高さをメモリーできて、1クリックで指定の高さにできるのもポイント。
 結果的に、この選択をしたことに十分満足してる。でもまあエルゴトロンのデスクを選択したとしてもそれはそれで満足して使ってたとは思いますが^^;..

長くなったので その2

COM と WRL::ComPtr

これまで中途半端にOpenGLESとMetalを使ったことがあるくらいでDirect3Dはまったくいじったことのないオッサンが「まあMetalとそんな変わらんだろう」といきなりDirect3D12に挑戦して四苦八苦してます。ロートルオジサンにはつらい。。。

で表題の件ですがDirectXのオブジェクトは基本COM。Direct3D12になってもCOM。
D3D12からは言語はC++しかサポートせず、そしてオブジェクトの保持や破棄は全てプログラマが責任持って管理するようになったのにCOMを使う利点って何だろう。。。
もうValkanのようにイチから設計し直して欲しかったがそれならValkanをどうぞということだろうか。

それでCOMですが、アラフィフになってえっCOMって何? なロートルおっさんなので勉強しました。

  • 参照カウント方式。AddRefしたらReleaseする。カウンタがゼロになったら解放される
  • 戻り値や引数でCOMを返却する関数は関数側でAddRefして返す。関数から受け取った側は必要なくなったらReleaseする。

MRC時代のObjective-Cの参照カウンタと似たかんじで、これはOK。

次に WRL::ComPtr。 参照カウンタの面倒を自動化してくれる。すばらしい。

ただ、参照カウンタをどう扱うかのポリシーみたいなやつのドキュメントが見当たらない。どう使っていいのかいまいちピンとこない。しかたないのでComPtrのヘッダをみてみる。

WRL::ComPtrはコンストラクタや代入でCOMオブジェクトを受け取る時に必ずAddRefし、管理しなくなる時に必ずReleaseする。
これは徹底している。参照カウンタが元に戻ることが保証される。
右辺値参照にも対応し、moveする場合は参照カウンタは増えない。

これはなかなか良い。

だけども、Create系関数から返却されたオブジェクトをComPtrで扱おうとするとあれっとなる。
Create系関数から返却されたオブジェクトはすでにAddRefされた状態で返ってくるので、こいつはAddRefせずにReleaseだけ行う。
だけどコンストラクタや代入でWRL::ComPtrに渡すとAddRefしてしまう!!

で、どうするんだろうとサンプルコードなどをみると、ComPtrでCOMオブジェクトを受けるのはこんなカンジになってる

ファッ!?? ってなりますよね。 なりますよね?

&deviceって何??
なんでComPtrのアドレスを直にD3D12CreateDeviceの引数にぶっこんでるの??

と思ってComPtrのヘッダをみると、単項 & 演算子がオーバーロードされていた。こいつがDetails::ComPtrRef<ComPtr<T>>を返す。さらに Details::ComPtrRefの operator InterfaceType**() が呼ばれて、元のComPtrのReleaseAndGetAddressOf()を呼ぶ。。。。 つまり、上記のCreateDeviceのところは

と書くのと同じである。

これでようやく、ああ、ComPtr内部で持ってるオブジェクトのポインタのアドレスを渡して直接オブジェクトを得るんだな。この時AddRefはされないんだな。そしてComPtrのデストラクタで無事Releaseされるんだな。というのが理解できた。

これくらいのことをヘッダ辿って調べるのは一般的なC++erだったらきっと至極当然のことなのであろう。だからWRL::ComPtrのこの辺の挙動を疑問に思うエントリがぐぐっても出てこないんだ。たぶん。
でもロートルおじさんはこの辺の挙動を理解するのに苦労したのでこうして書き留めるよ。

しかしこれ、 &device って書くよりも device.ReleaseAndGetAddressOf() って書く方が圧倒的にわかりやすいよねえ。。。

ICC17.0の変数テンプレートが少〜し変よ〜

ICC17.0が出たのでさっそくアップデートしました。

  • Support C++14 variable templates (N3651)

となってるのでワクテカで変数テンプレートを試してみたわけですがちょっとおかしい。

とりあえずconstexprな変数テンプレートのコンパイルは通る。

だがしかし、constexpr な変数テンプレートを特殊化するとコンパイルエラーになる。

これ、ClangやMSVCではコンパイル通るけど、ICC17.0では「a constexpr variable declaration must be a definition」というエラーが出る。

変数テンプレートのconstexprを取り除いて

ってするとICC17.0でもコンパイル通る。。。。 これってICCの変数テンプレートの実装ミスだよなあ。。。。。

[追記:20180302]
ICC18.0 で試したところコンパイル通った。