ほげほげー

C#メインで困ったことや面白く感じたことをメモしていきます。

iPhone XS Max レビュー

iPhone XS Max を早速購入して色々と思うところがあったので簡単にレビューしてみようと思う。

続きを読む

爪を切るのをやめました

前置き


先日の記事で Realforce をやめて Surface Ergonomic Keyboard にした話を書きました。

このキーボード、基本的にはなんの不満もないんですが、ただ一点、キーストロークが浅い事が問題になってきます。

特に自分にとっては。

キーストロークが浅いキーボードだと、少し爪が伸びるだけで劇的にタイピングがし辛く感じませんか?

爪が当たって入力したい文字とは違う文字を打ってしまったり、
カチカチ当たる音が鬱陶しかったり感触が不快だったり。

この点、キーストロークの深いキーボードだとそれほど気にならないのですが、浅いものはそうも行かず。

こまめに爪を切ればいいでしょと言われるかもしれませんが、爪を切るって行為が存外面倒で。

習慣付けが難しいんですよね。1日毎や2日毎という短いスパンだと習慣付けしやすいのですが、
3日以上になると途端に習慣付けが難しくなります。*1

しかしながらなんとか習慣付けないと爪がストレス源となってしまいます。

そんな悩みをどうするか、考えて実践してみました。

*1:個人の感想です

続きを読む

マウスとキーボードをワイヤレス化したい人に向けて

色々思うところがあって、コードをなるべく減らそうと思い立ちまして、キーボードとマウスをワイヤレスにしました。

ワイヤレスにするにあたって考えたこと、何故それを選んだか等をまとめておこうと思います。

打鍵感重視の人には恐らく参考になるとは思いますが、打鍵感の良し悪しは人によって様々ですので、
実際に購入される際には店頭で触ってみることをおすすめします。

続きを読む

Windows で US 配列と JIS 配列を共存させたい

ゲーミングノートPC買ってしまいました

昨日デスクトップが壊れかけたのでコードを減らしたいという思いもあり、 かつ持ち運びもしたいということで、勢いで MAX-Q Design なノートパソコン買ってしまいました。

多分これ。*1

予算の都合もあり、CPUが1世代前。まぁ実測値20%程度しか性能差が無いので良いのです。*2

カスタマイズ内容

項目 内容
メモリ(DDR4) 16GB → 32GB
SSD(NVMe) 256GB → 512GB
Windows Home → Pro(自前ライセンス)

f:id:tyhe:20180821022431p:plain f:id:tyhe:20180821022918p:plain

つよい。

流石にCPUは貧弱なので今使ってるデスクトップ(Core i7 2700K)よりもちょい弱いくらい。

具体的には Google ChromeNetflix の適当な動画*3を観ると余裕で1コア食いつぶしてカクカクするくらい。
代替手段で Edge を使えば CPU 使用率3%行かないくらいなんで Netflix 観るなら Edge 一択です。

前置きはここまで

*1:実際にはマウスコンピューター店頭販売限定らしく、多分通販では買えないはず

*2:この辺参考: https://www.youtube.com/watch?v=Oz3MomPV4u8

*3:今回試したのはこいつ https://www.netflix.com/title/80233883

続きを読む

SHARP のドラム式洗濯乾燥機がとても良かった話

先日ドラム式に変えてからの感想とか軽く触れておきます。

tyheeeee.hateblo.jp

買った洗濯機

実際に設置した結果

斜め視点

f:id:tyhe:20180725020556p:plain

f:id:tyhe:20180725020604p:plain

横から

f:id:tyhe:20180725020651p:plain

事前に図面から逆算した数字で測ってたんである程度予想はしていましたが、まさかこれほどとは。

諦めずに頑張って色々計算してみるの超大事ですね。

無事設置できてよかった。

ここからは1ヶ月ちょっと使ってみての感想です。

使い心地

乾燥機能

今の所問題なく乾燥してくれています。

我が家は日当たり劣悪なのでタオルとかが陰干し状態になっていてタオルがバキバキだったのですが、
乾燥機能を使って乾燥させたら寿命かなと思っていたタオルがやわらかふかふかに。

これがハイブリッドによるものなのかヒートポンプならこんなものなのかはわかりませんが、個人的には大満足です。

以前は微かに生乾きの臭いがすることもありましたが、それも無くなり非常にQOLが向上しました。

雨の日でも気にせず洗濯できるのはストレス源を減らすのに非常に効果的ですね。

ただ、洗濯ネットに入れて乾燥させたものについては稀に乾ききらないことがあったのでその辺り不満に感じる人はいるかも知れません。

ドラム式洗濯機ではよほど気にする衣服でない限りは洗濯ネット不要という話もありますし、
洗濯ネットを付けないのがベタなのかもしれません。

干さなくてもいいのは本当に楽。めちゃくちゃいい。

メンテナンス性

乾燥機能を使うとどうしてもホコリが溜まって乾燥機能が落ちるものみたいですが、
このSHARPのドラム式の場合はホコリフィルタの部分にホコリが溜まるように設計されているようでして。

洗濯する前にパパっと1分かからずホコリを取り除けるので大変良いです。

f:id:tyhe:20180725022008j:plain

f:id:tyhe:20180725022014j:plain

糸くずフィルタも本体下部にあって、こちらも取り外し可能で洗いやすいのがいいですね。

静音性

これが一番驚いた事なのですが、以前使用していたタテ型洗濯機と比較して静かになりました。

乾燥中なんか動いている事を忘れるほど。

実際公称スペックで見ても SHARP, パナソニック, 日立, 東芝で比較すると一番静かみたい。

利便性

洗濯物を入れてスイッチを入れると洗剤をどれくらい使えばよいかの目安を提示してくれるのが地味に便利。

今まではとりあえず計量スプーン一杯入れとくかくらいなノリでやっていたので想定外の節約要素に。

洗浄力

そんなに激しく汚すことがないので今の所体感できず。

実際に汚してしまった時に温水機能を使って試します。

洗濯スピード

乾燥なしで洗濯だけの場合は30分かからず終わりました。

洗濯+乾燥の場合は、毎回最初に3時間と提示されますが、実際に乾燥終了するのは洗濯開始してから2時間後です。

おそらく脱水時に洗濯物のバランスが取れずに時間がかかった場合のワーストケースで表示しているのだと思われます。

省エネ

この辺は多分ヒートポンプ系ならどれもどっこいどっこいなんじゃないでしょうか。

とはいえ、実際に参考の電気代水道代を出しているのがSHARPパナソニックだけだったので割といい方なんじゃないでしょうか。

パナソニック VXシリーズ特長:ヒートポンプ乾燥(VX9800・VX8800・VX7800・VX3800)) | 洗濯機/衣類乾燥機 | Panasonic

SHARP ES-P110|洗濯機:シャープ

総評

結果的にこれしか設置できなかったんですが、買った後他と比較してみても大満足という結果に。

やるな、SHARP

タテ型洗濯機からドラム式洗濯乾燥機に変えたお話

どうもご無沙汰してます。

久しぶりな割に技術要素皆無ですみません。

今は貝殻本を買って読んでる最中です。

それはさておき、今回は洗濯機をドラム式にするにあたって落とし穴に嵌りまくったので同じ目に遭う人が一人でも減る事を願って記事化します。

続きを読む

Unity での開発でも async/await を使おう

いつも通り久しぶりに記事を書きます。

Unity で async/await を使うようになってから大変捗っているので覚書。

async/await 以前の非同期

従来の C# では非同期を取り扱うためには色々面倒な事をする必要がありました。

例えば delegateBeginInvoke, EndInvoke を使う。

例えば System.Threading.Thread を使う。

例えば System.Threading.ThreadPool を使う。

などなど。まぁ歴史的経緯もあってほんとに色々あります。

どれでやるにしても本当に簡単な処理を非同期にする時以外は、
メインスレッドに返したり、非同期の連鎖があったりと、
大抵の場合非常にコードが汚くなりがちです。

Unity ではもちろん UI に触るときはメインスレッドからしか受け付けていないので、
別スレッドで処理した場合はメインスレッドに何らかの方法でディスパッチする必要があります。*1*2

async/await 以後の非同期

async/await は C# 5.0(.NET Framework 4.5) から導入された演算子です。

戻り値を void, Task, Task<T> にして、async キーワードを付ける事で、
Task, Task<T> を戻り値にしているメソッドを await 演算子で待機できるようになります。*3

普通のメソッド呼び出しと同じように書けるようになるので非常に読みやすい。

await NanikaOmotaiAsync();
var result = await NanikaOmotaiGetAsync();
await NanikaOmotaiSetAsync(result);

適切に Task で処理されていれば、await で待機した場合、非同期処理後は元のスレッドで処理を再開するので、
重たい処理の間だけ別スレッドで処理して、それ以外の処理は呼び出し元のスレッドで処理する形になります。

f:id:tyhe:20160404220239p:plain

重い処理が MainThread を専有しなくなるので UI が固まることはありません。

Unity で非同期をするには

  • 昔ながらの手段を使う
  • コルーチンを使う(後述)
  • UniRx を使う
  • MinimumAsyncBridge を使う(本記事で紹介)

Unity のコルーチンは非同期なのか

非同期だけどシングルスレッドなので注意しないとUIが固まります。

f:id:tyhe:20160404220034p:plain

StartCoroutine で登録された IEnumerator 全てに対して1フレーム毎に MoveNext を呼び出します。
また、全てのMoveNext の処理が終わるまでの間1フレームが終わりません。
そのため、30fpsのゲームの場合は30ms、60fpsのゲームの場合は15ms超える処理となってしまうとFPSが落ちてしまいます。

コルーチンは基本的に重たい処理を複数フレームに小分けにして処理をするもの、
と考えておくと良いですね。

コルーチンで目にする yield が何なのかについては以下の記事を読んでいただくと比較的分かりやすいと思います。

tyheeeee.hateblo.jp

Unity で async/await を使って開発する

やっと本題。

Unity Script では使えません。残念でした。

しかしながら、Assets/Dlls 以下に設置する dll については別。

dll の作成時には async/await を使おうと思えば使えるのです。
ただし、Unity で使える .NET Framework は 3.5 Subset 相当なので当然 Task クラスやら何やらはありません。

ではどうするか?

自前で Awaiter パターン を実装した Task クラスを実装すれば良いのです。

Awaiter パターンについて詳しくは他の方の記事を見ていただくとして、
ここでは簡単に。

class Hoge
{
    public HogeAwaiter GetAwaiter();
}

class HogeAwaiter
{
    public bool IsCompleted { get; }
    public void OnCompleted(Action continuation) { }
    public T GetResult() { }
}

これらのメソッドを持っているオブジェクトなら実は何でも await 出来ます。
そして拡張メソッドでも OK なので、本当になんでも。

しかしながら、イチから実装するのは大変なので、ここでは株式会社オレンジキューブが公開している
MinimumAsyncBridge を使います。

github.com

NuGet Package も公開されているのでパッケージマネージャコンソールからインストールできます。

Install-Package MinimumAsyncBridge

では早速。

プロジェクトを作成して、対象のフレームワーク .NET Framework 3.5 にする

f:id:tyhe:20160405004041p:plain

参照を右クリックして NuGet パッケージの管理を開く

f:id:tyhe:20160405002422p:plain

MinimumAsyncBridge の最新版をインストールする

f:id:tyhe:20160405002534p:plain

MinimumThreadingBridge も一緒にインストールされるのでインストールする

f:id:tyhe:20160405002629p:plain

これでできました。

あとは何も意識すること無く普通に async/await が使えます。

f:id:tyhe:20160405004242p:plain

さて、何で使えるのかというと、

  • async/await をコンパイルした時に吐かれる IL 自体には何の拡張も無い
  • GetAwaiter 関連さえ実装されていれば async/await は使える

ということは、Unity でも Dlls に入れる分には特に問題なく使えるのです。

その辺の軽い説明はこちらを参照。

[http://tyheeeee.hateblo.jp/entry/2015/06/12/Visual_Studio_2015%E3%81%A8_Unity%E3%81%A8:embed:cite]

特に問題なく使えると言ったな。あれは嘘だ。

async/await 対応は実は完璧ではなくて、
Release ビルドをすると IL2CPP でのビルドに失敗します。

Release ビルド時に特定の最適化がされる事に起因するっぽいのですが、
IL2CPP そのものに修正が入らないとどうにもならないので、まぁ Debug ビルドで我慢。

バグとしては挙げているので、まぁそのうち・・・きっと直らないと思います。

とはいえ、最適化入っても入らなくてもそんな致命的な程には変わらないので、 async/await の利便性を享受するために甘んじて受け入れましょう。

2016/12/27 追記

Release ビルド時に [StructLayout(LayoutKind.Sequential)] 属性が付与される事に起因しているっぽい。 https://unity3d.com/jp/unity/whats-new/unity-5.3.5 の Fixes に書かれている IL2CPP: 基本クラスが StructLayout 属性を持たないときに、StructLayout 属性を持つC# クラスのための適切なC++コードを生成(767367) で直ってるかもしれません(未確認)

これが原因だと分かっていれば無理矢理やってやれない事も無くて、
Mono.Cecil あたりを使って dll 読み込んで属性をちょちょいと外して書き戻してあげれば良かったりします。

実際現在開発中のゲームではそれで動作しています。

Unity の今後について

先日 Xamarin が Microsoft に買収されて、ARM 版の Mono がオープンソース化されたことで、
Unity の C# 最新仕様への対応が飛躍的に進むんでないかと期待していたりします。

そして .NET Foundation への加入も表明し、これから加速していきそうな予感がします。

blogs.unity3d.com

これからの Unity に期待ですね。

C# 6.0 対応はやく

*1:UI をメインスレッドからしかさわれないのは他のフレームワークでもでも大体同様です。WPF や WinForms でもそう。

*2:UI ではない WWW クラスも AssetBundle をダウンロードする機能を積んでいるからか、メインスレッドで触らないといけないのはホントひどい話

*3:厳密には GetAwaiter が使えるクラスなら何でも