手続き型音楽の日常

関数型音楽に乗り換えたい

ブログデザインを変更しました その他私事の報告

最近ブログ記事書いて無いなぁと思いつつ、いろいろをはてブの設定を見ていたんですが。

なんかちょっとかわいいデザイン見つけちゃって「これいい!!」って一目惚れして変えました。

やっぱ明るくキラキラしているデザインのほうが個人的にも気分が上がりますし、ちょっとだけ見やすいんじゃないかな?と思いまして。

本当はダークモードとか切り替えたいんですけど、それにしてもこのデザインのほうが素敵かなと思います。

というわけで、今後はこのデザインで、今までと記事内容は 何一つ 変更なくやっていきたいと思います。

以上。

松岡修造「だわけねぇだろおぇー!」

はい、以下、私事報告タイムです。

私事その1 転職

この度、 転職 いたします。いやお前もともとどこに勤めてたんだよって話ですが。

名古屋で IT 企業といえば大抵想像はつくと思いますが、今までは小さな少数精鋭の下請け業者として働いていました。

某大企業の工場などで使われるシステムの構築などを請け負っており、私が担当したのはコーディングから導入・調整工程でした。

高校で PLC (シーケンサ) というものに出会い、ラダーや低水準な通信に興味をもって、この世界に飛び込みました。あの頃が懐かしい。

一応、入社当初は何も不満無く、楽しく仕事をさせていただいていました。それが、最近ではすこし不安を覚えるようになってきたのです。

高卒で就職したので 2年間 勤めたことになるのですが、それまで高校なり中学なり趣味なり、そこらで学習してきたスピードと職場で学ぶスピードが、かけ離れている気がしていたんです。

例えば Excel VBA とか HTML なんかは、趣味で基礎的なことはやっていてそれを応用した次のステップが欲しかったところに、実際の業務で与えられた仕事はそれ以下のレベルであったり (会社にノウハウが無いため)。

例えば git やせめて TFS 、まあ欲を言わなければ VSS なり VCS が基本的な今の時代、ファイル名管理な上、 TFS を使ったとしても複数人作業での排他ロック程度にしか使わなかったり。

例えば「工場の IoT (インターネットにはつなぐことはできません)」という謳い文句を見てしまったり。

技術面だけでもいろいろとありますが、ビジネスマナーが重要視されていない(?)ので覚える機会がないとか、フレックスタイムで個人の自由が増える反面イベントが無いとか。

結局、少数精鋭ということで既に実力や社会を見てきてこの会社に入れば、活躍する場も勉強することも自分の力で獲得できるんだろう、と思うのです。

私のように高卒でたたき上げるためにはチャンスはとても少ないし、見られる世界も少ないなと、思うわけです。

というわけで、個人的にはそういうチャンスがありそうな、というか着実に今より 仕事が絶賛ハードな 会社に転職いたします。今より確実にやることも覚えることも増えます。

この 2年間 で忘れ去ってしまったであろう学習意欲とか元気とか、やる気をもう一度取り戻すべく、頑張っていこうと思います。

いやコネって強いですね。

私事その2 サイトを作ります

先ほどとは打って変わってこちらは 実現するかわからない 宣言に近いものですが。

サイトを立ち上げてみようと思います。

すでに VPSドメインを確保してあって、あとは組み上げるだけなのですが、実はまだ企画書とか設計書とか何一つないんですよね。

それなのにドメイン3年間で取得したとか、あたしって、ほんとバカ…

私一人で作るわけではないのでいろいろと調整を重ねながらだんだんと進んでいくことにはなると思いますが。

いろいろなことを書き残せるような、ブログとは違いますがまとめサイト的な、というか初心者プログラマ向けな? IT 業界初心者向けな??

とまで言うと企画没ったときに取り返しがつかないので今回はここまd (殴)

私事その3 アレンジ作ってなくてごめんなさい

正直、 期待してる人0説 あるなと思っているんですけど。

転職とか、あと今年 3月 の年度末ラッシュがとても忙しくて、それどころじゃなかったんですよね。

年末から年始にかけて、あと 4月 あたりに 1本 ずつ出せるかなぁとかいろいろと考えてはいたものの、とても定時には帰れないし年末も大掃除で忙しいし。

スプラトゥーンとMUSECAでストレス発散する時間が多いだけのようにも見えますが、そんなことありませんよ。それ以前とやってる時間は変わってませんから。

f:id:yuzutan_hnk:20180513170935j:plain:w300

え?何か問題でも? (^q^)

最後に

まあだいたいお察しの通り、デザインを変えたのもだいたい気分を一新するためです。はい。

将来自分がどうあるべきかって考えても実現できない環境にあったのか、はたまた自分が甘いだけなのかはわかりませんが、現状は足元しか見ることができなくなっているなとつくづく思います。

これからブログや仕事、できれば勉強会やコミュニティにもできるだけ積極的に参加していきたいなとは思っています。

あ、 OWASP Nagoya スタッフも実は仕事や転職が忙しくて放置してしまっていて、ついこの間、辞退の連絡を入れさせていただきました。

その時、リーダーから「ボランティアだからいつでも参加できますよ」って本当に優しい言葉を頂いて、ほんとコミュ障すぎてなんて返していいかわからず放置してしまってるんですが。

皆さん、なんでこんなに優しいんでしょうね。なんでこんなに心が広く、自分以外のことを広く視野に入れることができるんでしょうね。

もっともっと人間として成長しないとな、と感じています。

MUSECA 名古屋交流会に参加してきた話

まさか2回連続 MUSECA の話題でブログ書くことになるとは誰が思っただろうか。私も思ってなかったよ。

でもこれは流石に書かずにはいられない。正直ここ1ヶ月で、控えめに言って最高の1日だったと思います。

というわけで、書きます。いいですか、書きますよ。

>> #Trashで踊るな <<

MUSECA 名古屋交流会に参加してきました

f:id:yuzutan_hnk:20180418024727j:plain

先日 4月14日、名古屋のレジャーランドささしま店で開催された、 MUSECA 名古屋交流会に参加してきました。

前回の記事でも書いた打鍵舞踏廻に引き続き、実に2回目となるゲームイベントへの参加でした。

なんか、たった2ヶ月空いただけなのに、なんだか懐かしいというか、なんというか。

こういう雰囲気、久しぶりだなぁという感覚でした。

こんな日に限って寝坊するとか無いわ〜、ありえないわ〜…

とりわけ私早めに行きたいなぁと思って、というか朝から開店凸ってもいいなぁとか思いつつ。

地元勢だしばっちりリハーサルも兼ねて出かけようかなぁとか思ってたんですよね。気持ちだけは。

というわけで当日の私のツイートをペタリ。

もうこれどうしようもねぇな。

一応、会自体は14時からなので、 間に合ってます 間に合ってません。

いやこれめっちゃ急いで支度して出ないとほんとに間に合わないなと思いつつ、家を飛び出し…。

なんとか直前に会場入り。みんな集まってる、というかめっちゃ人多いな!?みたいな感じでめっちゃ挙動不審してました。

そして打鍵以来のしゃーさんに名札をもらい、メカコさんに記念品(?)のアクリルキーホルダーを貰い。

打鍵舞踏廻のときにも、仔猫吸引さんがアクリルキーホルダーを作ってきてくださって、めっちゃ感動したんですけど。

今回もまた超クオリティなものを頂いてもう感謝感激…。いやいや勿体無くて使えない。でもずっと眺めてたい。

こう、ユーザ参加型のゲームなだけあって、キュレーターの中にコンテンツ提供者がいるっていうちょっと不思議な感覚ではあるんですけど。

実際にクリエイターから直接もらえるって、めちゃくちゃ嬉しい。いや今度の JB は参加したいよ。めっちゃ行きたい。前回行けなくてごめんなさい。

久々にロカマチ!

いやぁ交流会ということで、久々に筐体が4台並ぶところを拝見いたしました。拝み。写真は神様を写すということに値するかもしれないのでなし。

普段は1人でしかやらないのでどちらかといえばマイペースに別機種交えながらやるんですが。

今回はみなさんとロカマチしながら楽しくワイワイ…ワイワイ?

多分、現場にいた皆さんから見えてた私って、こんな感じだと思うんですよね。

私「アッ、アッ、えーっと、うん、アッ」

絶賛コミュ障発揮してるーーーッ!!!

あーなんでこんなコミュ障なんだろネット弁慶極めてるとかホント自慢にならない…

ほんっとなんで自分こんなに人前で緊張しちゃうんだろう、せっかく話しかけてくださった方々と気軽に話せない。うーん。

と思いつつ、何度かいろいろな方とロカマチさせていただきました。

f:id:yuzutan_hnk:20180418015247j:plain:w300 f:id:yuzutan_hnk:20180418015319j:plain:w300 f:id:yuzutan_hnk:20180418015344j:plain:w300 f:id:yuzutan_hnk:20180418015429j:plain:w300 f:id:yuzutan_hnk:20180418015457j:plain:w300 f:id:yuzutan_hnk:20180418015532j:plain:w300 f:id:yuzutan_hnk:20180418015601j:plain:w300 f:id:yuzutan_hnk:20180418015629j:plain:w300 f:id:yuzutan_hnk:20180418015658j:plain:w300 f:id:yuzutan_hnk:20180418015729j:plain:w300 f:id:yuzutan_hnk:20180418015755j:plain:w300 f:id:yuzutan_hnk:20180418015824j:plain:w300 f:id:yuzutan_hnk:20180418015849j:plain:w300 f:id:yuzutan_hnk:20180418015918j:plain:w300 f:id:yuzutan_hnk:20180418015944j:plain:w300 f:id:yuzutan_hnk:20180418020011j:plain:w300

計4回かな?いやめちゃくちゃ楽しかったですよ!

みなさんほんと上手いし、何より楽しそう。というか、 MUSECA ってやっぱ楽しいよね。何度も思う。

いつも全然やってる人を見ないので、本当に自分だけの空間みたいになっちゃうんですけど。

いろんなひとが MUSECA で楽しんでいるところを見ると、ホッとしますね。色々思うところはあります。

最後に

やっぱり MUSECA 楽しいです。

私自身、どちらかといえばエンジョイ勢に寄っているのでこれまであまり突っ込んで活動はしてこなかったのですが。

こうして交流会だったり、大会だったり、いろいろなイベントに足を運んでみると、また違った世界が見えてきます。

純粋に音楽を楽しみたいがために始めた音ゲーが、自分の中でこうも大きな存在になっているのかと改めて実感もしましたし、

色んな人がいろんな思いで一つのことに夢中になれる、本当に素晴らしいゲームなんだなと感じたりもしました。

本当に、楽しかった。

あの場にいた人全員に、感謝しています。ありがとうございました。

打鍵舞踏廻に参加してきたお話

f:id:yuzutan_hnk:20180220020802j:plain:w600

初めて、コンピュータ関係以外の記事を書く気がする。

打鍵舞踏廻に行ってきました。

先日 2月17日、ラウンドワン府中本町駅前店で開催された MUSECA 非公式全国大会、打鍵舞踏廻というイベントに参加してきました。

https://e63s3neu.wixsite.com/mscchampionship

全国のキュレーターが参加できる大会で、去年の暮れからオンライン上で予選を行い、最終決戦が府中が行われました。

私は楽曲プレー部門でエントリーし、29人中10位という成績で最終戦に進出しました。ほかにも、解放ミッション部門とフリースタイル部門がありましたが、そちらには参加しませんでした。

私の MUSECA レベル

勉強会記事とかでも毎回この部分は、私がイベントの趣旨に対してどれだけ経験があるかっていうことをまとめているので今回も。

MUSECA というゲームを知ったのが、実はたまたまゲーセンに行ったらロケテをやっていた、ということでして。

初めて見たとき、SDVX の衝撃がよみがえってきたというか、『あ、このゲームは面白そうだ』と感動したんですよね。

今でこそ SDVX は当時の面影を残さず (BOOTH も FLOOR も) 、様々な進化を遂げて一つのジャンルを築いてきたと思いますが、MUSECA はそれをさらにこじらせたような、なんというか個性の塊というか、魅力を感じました。

時間的に1回?2回やったかな?ロケテをやってみて、「なんだこのゲーム、めちゃくちゃ面白いじゃん」という感覚に襲われ、本稼働してすぐにやりこむようになりました。

というわけで、実はロケテ勢、もっと言えばここ2年本当にやりこんでいる (自分の中では) ゲームなんです。

もう MUSECA レベル…キュレーターレベルは 20 MAXです。はい。何の参考にもならないって?

まず結果から行こうか

というわけで、結果を発表いたしますね。

1回戦敗退 でした。それも、ブロックで最下位。

実力をしっかり発揮できれば、もうあと1,2上を目指せたかなとは思います。後から悔やんでも仕方のないことですが、いろいろと反省しています。

実は、この1~2週間の間 MUSECA やるのサボっていて、全然調整することなく本番を迎えていたんですね。これが一番大きな要因かなと思っています。

当日になって「そういえば左手黄色スピナが入りにくい癖があったんだっけ…」とか「精度とる練習怠ってたな…」とかいろいろ思い返すあたりには 何もやってない っていう。

仕事のせいにするのもちょっと気が引けますが、実際本職が本当に忙しくて、ゲーセンに寄って帰る時間だったり MUSECA する気力だったり全部無くなってしまったっていうのが、正直なところ。

更に体調も微妙な感じ (ちょっと風邪気味、喉が痛い) だったし、当日新幹線で移動するので昼まで練習できないとか、朝ごはん食べれていないとか。

総合的に、計画性の無さ、準備の足りなさ、そして仕事を溜めすぎたっていうのが敗因ですかね。 ごめんなさい最後無かったことにして

皆さん上手すぎる件

とりわけ当日不調だ不調だって散々言いましたけど、調子が良ければ勝てたのかと言われれば 圧倒的に無理 なわけでして。

1回戦の次がもう準決勝だったのですが、その時点で遥かにうまい人しか残っていませんでしたはい。

Lv.15 (最高難易度) の曲が課題曲だったのですが、パーフェクト 100万点 がMAX値のうち、軽々 99万点 出してくるような戦いでして (私95万くらいしかいかない…)

見ていて圧巻というか、唖然というか、レベルが違うってこういうことなんだなぁと実感させられました。

行って良かったと心から思った

とはいえ、最終戦に出場できただけでも嬉しいですし、結果がどうであれその場にいることができたのが本当に幸せです。

本当は予選終了間際まで、出られるか出られないかわからない順位でした。ちょうど真ん中あたり (14位くらい) をうろうろしていたので、予選を通らなかったら仕事忙しいし東京なんて行かないんだろうなぁと思っていました。

でもこうして最終戦に呼んでいただき、東京まで足を運んで、こんなに熱をもって MUSECA をやっているキュレーターの皆さんに出会えて。

私がまだ知らないような世界がそこに広がっていて、ランカーの凄さだけでなくその熱量、なによりその場にいた全員の MUSECA への愛。

普段決して感じることがないような…。言葉が思い当たらないんですが。

MUSECA に出会えて、MUSECA を続けてこれたことが、こんなにうれしいと思える日が来るとは夢にも思っていませんでした。

最後に

普段から日記を書いたり、何か文章に気持ちを書き下ろしたりすることが滅多にないのでなかなかうまく伝えられない部分がありますが。

今までゲームをしてきた中で一番うれしかった1日でした。こんなに嬉しいことがあるんだなって、心から思いました。

当日見に来てくださった皆さん、一緒にプレイしてくださったみなさん、そしてこのイベントを主催してくださったお二方。

本当にありがとうございました。そして、お疲れさまでした。

MVVM 初心者なので、 .NET Standard 2.0 + Xamarin.Forms で Messaging クラスを実装してみた

昨今のお技術についていけていない私は、もちろん MVVM も初心者です。もっぱら Windows Forms に生きてる人なのです。

この間 Xamarin 勉強会に出かけたし、本業でも少し Xamarin を触ることになったので、 WPF 含め MVVM を色々と調べていたのですが。

やっぱり実装する方々それぞれ、いろいろなお作法で実現されていまして。

  • View -> ViewModel の機能呼び出しは ICommand 実装のクラス
  • ViewModel -> View の機能呼び出しは Messaging 機構

というのが現在の流行だという事を知りました。

早速実装してみる。

準備するもの

1. Xamarin.Forms でソリューションを作る

Xamarin.Forms を使ったソリューションを作成。とりあえず PCL で作っておく。

f:id:yuzutan_hnk:20171122014755p:plain:w600

f:id:yuzutan_hnk:20171122015100p:plain:w600

UWP のバージョン指定をしろと言ってくるので、最小バージョンを Fall Creators Update にする。

ここでキャンセルをクリックすると、 UWP とおさらばできる。スクショ撮ってて今知った。

f:id:yuzutan_hnk:20171122015344p:plain:w600

2. .NET Standard 2.0 化する

共有プロジェクトを無理くり .NET Standard 化する。

VS2015 のときは PCL プロジェクトをそのまま .NET Standard 化できていたけれど、 VS2017 ではできない。そこでまず、ソリューションに .NET Standard プロジェクトを追加する。名前は後々役立つように、 PCL プロジェクト名 + Standard にしておく。

f:id:yuzutan_hnk:20171122015937p:plain:w600

VS 15.4 なら大丈夫だと思うけど、念のためプロパティからターゲットを .NET Standard 2.0 にしておく。

f:id:yuzutan_hnk:20171122020310p:plain:w600

ソリューションの NuGet パッケージマネージャで、ほかのプロジェクトの Xamarin.Forms のバージョンを確認する。この画面からではたぶん .NET Standard プロジェクトに Xamarin.Forms を導入できないので、プロジェクト側の NuGet パッケージマネージャでバージョンに気を付けながら導入する。

ついでに、 PCL プロジェクト以外のプロジェクトに NETStandard.Library を導入。 .NET Standard プロジェクトのターゲットを .NET Standard 2.0 にしたので、自動的に NETStandard.Library のバージョンが 2.0.0 に固定される。 2.0.1 入れるとどうなるんだろう…。

f:id:yuzutan_hnk:20171122020627p:plain:w600

f:id:yuzutan_hnk:20171122020846p:plain:w600

PCL 側からソースファイルを全部コピー。ドラッグアンドドロップでおk。

f:id:yuzutan_hnk:20171122021319p:plain:w300

PCL プロジェクトを削除して、各プラットフォーム向けのプロジェクトの参照を .NET Standard のプロジェクトに張り替える。

最後に、ソリューションエクスプローラー上で .NET Standard プロジェクトの名前から「standard」を消す。

これで PCL プロジェクトを完全に置き換えたような形になる。

もっときれいにしたいときは、いったん Visual Studio を閉じ、エクスプローラー上でプロジェクトフォルダの配置や名前を変更、 sln ファイルの中身を弄って正しい配置にする。

3. Messaging クラスを実装する

本題の Messaging クラスです。

Messaging クラスの役割は、コーディング時に呼び出し先が用意する機能を直接参照せずに呼び出すという機能です。

というわけで、相手を見ずに機能を特定する方法を考えます。 いや考えるのが非常にめんどくさいので 文字列を使って特定することにします。

using System;
using System.Collections.Generic;
using System.Linq;

namespace Xamarin_SelfMessaging
{
    /// <summary>
    /// メッセージ機構を実現するクラス
    /// </summary>
    public class Messaging
    {
        #region Private Class

        /// <summary>
        /// 接続先一覧を表すクラス
        /// </summary>
        public class MessagingNetwork : Dictionary<object, MessagingPeer> { }

        /// <summary>
        /// 接続先を表すクラス
        /// </summary>
        public class MessagingPeer : Dictionary<string, Action<object>> { }

        #endregion

        #region Variable / Const

        /// <summary> 既に接続されている </summary>
        private const string EXMSG_CONNECTING = "Already connecting.";

        /// <summary> まだ接続されていない </summary>
        private const string EXMSG_NOTCONNECTED = "Not connected yet.";

        /// <summary> 既に購読されている </summary>
        private const string EXMSG_LISTNING = "Already listening.";

        /// <summary> まだ接続されていない </summary>
        private const string EXMSG_NOTLISTNED = "Not listened yet.";

        /// <summary> 接続先一覧 </summary>
        private MessagingNetwork _network = new MessagingNetwork();

        #endregion

        #region Public Property

        /// <summary>
        /// 現在の接続数 を取得します。
        /// </summary>
        public int ConnectionCount => _network.Count;

        #endregion

        #region Public Method

        /// <summary>
        /// メッセージングネットワークに接続します。
        /// </summary>
        /// <param name="target">接続するオブジェクト</param>
        public void Connect(object target)
        {
            if (target == null) throw new ArgumentNullException(nameof(target));
            if (_network.ContainsKey(target)) throw new InvalidOperationException(EXMSG_CONNECTING);

            _network.Add(target, new MessagingPeer());
        }

        /// <summary>
        /// メッセージングネットワークから切断します。
        /// </summary>
        /// <param name="target">切断するオブジェクト</param>
        public void Disconnect(object target)
        {
            if (target == null) throw new ArgumentNullException(nameof(target));
            if (!_network.ContainsKey(target)) throw new InvalidOperationException(EXMSG_NOTCONNECTED);

            _network.Remove(target);
        }

        /// <summary>
        /// メッセージを購読します。
        /// </summary>
        /// <param name="target">購読するオブジェクト</param>
        /// <param name="key">購読するイベント名</param>
        /// <param name="action">イベントの引数</param>
        public void Listen(object target, string key, Action<object> action)
        {
            if (target == null) throw new ArgumentNullException(nameof(target));
            if (key == null) throw new ArgumentNullException(nameof(key));
            if (!_network.ContainsKey(target)) throw new InvalidOperationException(EXMSG_NOTCONNECTED);
            if (_network[target].ContainsKey(key)) throw new InvalidOperationException(EXMSG_LISTNING);

            _network[target].Add(key, action);
        }

        /// <summary>
        /// メッセージの購読を停止します。
        /// </summary>
        /// <param name="target">購読しているオブジェクト</param>
        /// <param name="key">停止するイベント名</param>
        public void Unlisten(object target, string key)
        {
            if (target == null) throw new ArgumentNullException(nameof(target));
            if (key == null) throw new ArgumentNullException(nameof(key));
            if (!_network.ContainsKey(target)) throw new InvalidOperationException(EXMSG_NOTCONNECTED);
            if (!_network[target].ContainsKey(key)) throw new InvalidOperationException(EXMSG_NOTLISTNED);

            _network[target].Remove(key);
        }

        /// <summary>
        /// メッセージを送信します。
        /// </summary>
        /// <param name="target">送信元オブジェクト</param>
        /// <param name="key">イベント名</param>
        /// <param name="arg">引数</param>
        public void Post(object target, string key, object arg)
        {
            var actionList = _network
                .Where((item) => item.Key != target)
                .Select((item) => item.Value.Where((item2) => item2.Key == key))
                .Where((item) => item.Count() > 0)
                .Select((item) => item.First().Value);

            foreach (var action in actionList)
                action?.Invoke(arg);
        }

        /// <summary>
        /// メッセージを送信します。
        /// </summary>
        /// <param name="target">送信元オブジェクト</param>
        /// <param name="key">イベント名</param>
        public void Post(object target, string key)
            => Post(target, key, null);

        #endregion
    }
}

使うイメージ的には、イベントを購読するクラスを Connect し、購読するイベント名を Listen 。メッセージを発行する側はイベント名を Post する。一通り何かの通信のような感覚で使えるようにしたつもり。

ただ一つ、 宛先を指定できない (=ブロードキャスト状態) という難点があり、ネットワークごとにインスタンスを分ける必要がある…。

今回はめんどくさいので ViewModel にインスタンスを持たせて、 View が BindableContext直接参照で ViewModel をインスタンス化するときにコンストラクタ内でこっそり登録する方針で行きます。

4. DelegateCommand を実装する

Messaging ついでにボタンに登録するコマンドも実装します。

フレームワークには System.Windows.Input.ICommand インターフェイスしか用意しておらず、自前で実装するしかないというちょっと微妙な感覚。

というわけで汎用性を高めるよう、 delegate で処理を指定できるようにする。

using System;
using System.Windows.Input;

namespace Xamarin_SelfMessaging
{
    /// <summary>
    /// 任意の処理を実行可能なコマンド
    /// </summary>
    public class DelegateCommand : ICommand
    {
        #region Variable

        private Action<object> _command;
        private Func<object, bool> _canExecute;

        #endregion

        #region Public Event

        /// <summary>
        /// 実行可能かどうかを取得する必要がある時に発生します。
        /// </summary>
        public event EventHandler CanExecuteChanged;

        #endregion

        #region ctor

        private DelegateCommand() { }

        /// <summary>
        /// 任意の処理を実行可能なコマンドをインスタンス化します。
        /// </summary>
        /// <param name="command">コマンド実行時の処理</param>
        /// <param name="canExecute">実行可能かどうかを返す処理</param>
        public DelegateCommand(Action<object> command, Func<object, bool> canExecute)
        {
            _command = command;
            _canExecute = canExecute;
        }

        #endregion

        #region Public Method

        /// <summary>
        /// コマンドが実行可能かどうかを取得します。
        /// </summary>
        /// <param name="parameter">パラメータ</param>
        /// <returns>実行可能かどうか</returns>
        public bool CanExecute(object parameter) => _canExecute?.Invoke(parameter) ?? false;

        /// <summary>
        /// コマンドを実行します。
        /// </summary>
        /// <param name="parameter">パラメータ</param>
        public void Execute(object parameter) => _command?.Invoke(parameter);

        /// <summary>
        /// <see cref="CanExecuteChanged"/> イベントを発生させます。
        /// </summary>
        public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, new EventArgs());

        #endregion
    }
}

System.Windows.Input.ICommand インターフェイスExecute メソッドと CanExecute メソッド、 CanExecuteChanged イベントを定義しています。

特に引数を必要としないのでデリゲートのほうは引数をなくしてもいいのですが、とりあえず純粋にスルーするだけにしてみます。

指定されたデリゲートが null だったりしたら不通に例外出したほうがもしかしたら安全かも?

5. ViewModelBase を実装してちょっとだけコーディングを楽にする。

すべての ViewModel でいちいち System.ComponentModel.INotifyPropertyChanged を実装したり MessagingConnect するのがめんどくさいので、基底クラスを作っていしまいます。

あとは継承するだけ。使うだけ。って状態にしてみます。

using System.ComponentModel;

namespace Xamarin_SelfMessaging
{
    /// <summary>
    /// ViewModelのためのテンプレート
    /// </summary>
    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        #region Public Property

        /// <summary>
        /// メッセージネットワーク
        /// </summary>
        public Messaging Messaging { get; }

        #endregion

        #region Public Event

        /// <summary>
        /// バインドプロパティが変更されたときに発生します。
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region ctor

        public ViewModelBase()
        {
            Messaging = new Messaging();
            Messaging.Connect(this);
        }

        #endregion

        #region PrivateMethod

        /// <summary>
        /// バインドプロパティを変更したときに呼び出します。
        /// </summary>
        /// <param name="name">変更したプロパティ名</param>
        private void OnPropertyChanged(string name)
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));

        #endregion
    }
}

本当はプロパティだけ用意すれば勝手にバインドしてくれるジェネリックな型を作ってみたい。 ReactiveProperty みたいな。

6. View ~ ViewModel を実装

あとは機能要件を作るのみ。今回はボタンを押したらカウントアップして、さらにダイアログを出すという単純な機能を作ってみます。

View

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:Xamarin_SelfMessaging"
             x:Class="Xamarin_SelfMessaging.MainPage">
    <ContentPage.Content>
        <StackLayout>
            <Button Text="{Binding Count}" Command="{Binding ButtonCommand}"
                    HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
using System;
using Xamarin.Forms;

namespace Xamarin_SelfMessaging
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();

            var viewModel = new MainPageViewModel() as ViewModelBase;

            viewModel.Messaging.Connect(this);
            viewModel.Messaging.Listen(
                this, "A",
                (arg) => DisplayAlert(
                    $"Do you have a watch???",
                    $"It's {(arg as DateTime?)}",
                    $"Awesome!!!")
                );

            BindingContext = viewModel;
        }
    }
}

ViewModel

using System;

namespace Xamarin_SelfMessaging
{
    class MainPageViewModel : ViewModelBase
    {
        private int _Count;
        public int Count
        {
            get { return _Count; }
            set
            {
                _Count = value;
                OnPropertyChanged(nameof(Count));
            }
        }

        private DelegateCommand _ButtonCommand;
        public DelegateCommand ButtonCommand
        {
            get { return _ButtonCommand; }
            set
            {
                _ButtonCommand = value;
                OnPropertyChanged(nameof(ButtonCommand));
            }
        }

        public MainPageViewModel()
        {
            ButtonCommand = InitialButtonCommand;
        }

        private DelegateCommand InitialButtonCommand
            => new DelegateCommand(
                (arg) =>
                {
                    Count++;
                    Messaging.Post(this, "A", DateTime.Now);
                },
                (arg) => true
                );
    }
}

7. 実行

あとは実行するのみ。今回は UWP で動かしてみる。

f:id:yuzutan_hnk:20171123230412p:plain:w600 f:id:yuzutan_hnk:20171123231034p:plain:w400 f:id:yuzutan_hnk:20171123231053p:plain:w600

以上。

IoTLT名古屋 vol.7 に参加してきた話

IoT ってなんだか楽しそう!いろんな端末がインターネットにつながるのって面白そう!やってみたい!

…という人が、ガチ IoT 勉強会に参加してきた世にも恐ろしい話…。

というわけではなく、比較的ラフな LT 大会というジャンルの勉強会に参加してきました。

iotlt.connpass.com

きっかけ

前回の OWASP Nagoya Local Chapter Meeting #1 に参加してから早 2 週間。

日々スプラトゥーンばかりやってて ちょっと退屈な日々でした。嘘。

で。次の勉強会 (?) の OWASP World Tour in Tokyo / Nagoya Satellite までちょっと間が開くなぁと思っていたところ、

友人やいつも追いかけている MSP の方々 が参加される勉強会というだけあって、ちょっと参加してみようと思いました。

最近、思いとどまるということを知らない気がするぞ…。

私の IoT レベル

7月あたり、ハンズオンセミナーで ESP8266 を使った簡単なプログラミング (兼ハンダ付け大会) に行ったこともあり、一応それっぽい知識はあります。

とはいえあれから1ヶ月2ヶ月放置して、全く使っていません…。もうそろそろ使わないと忘れちゃいそう…。

電子工学とか全くわからないし、 HDL とかほぼ組んだこと無いしハードウェアに密接に関わるような分野は難しいなぁと感じています。

でも、 IoT ってそれだけじゃない、はず、よね?

と信じてました。

私の LT レベル

LT ? 無理無理!まず LT 大会に参加したこともないよ!!

という超初見さん状態でした、まる

当日

Misoca さんという会社の会議室で行われました。ルーセントタワーの目の前…。

www.misoca.jp

f:id:yuzutan_hnk:20170926015019j:plain:w600

2011 年創業のスタートアップ企業だそうで、最近いろいろあって綺麗なオフィスを構えることができましたーとおっしゃっていました。

確かにとても清潔感のあるオフィスで、アットホームなスタートアップと言うよりかは、しっかり堅実なオフィスという感じでした。

一般参加 22 人という枠でしたが、席が全部埋まる大盛況でした。私は一番前に座ってエアコンの風に当たって最後のほうちょっと寒かったです。とはいえしっかり見れてよかった。

Twitter トレンド入りを果たそう」 という神の助言があったり connpass のバグがあったり、開始する前もワイワイと盛り上がる盛り上がる。

勉強会ってこういうところラフだなぁと思いながら、 15:35 からスタートしました。

まぐろ㌠ さん

www.slideshare.net

題名は「音のなるIoTデバイス

IoT らしい IoT といえば、音を使うデバイスでしょ!と初っ端ズキッとくる内容。

私もこういうの作りたいと思って IoT ハンズオン行ったんだっけなぁと2ヶ月前の記憶が蘇って来ました。

作られたデバイスDFPlayer miniESPr Developer という 2 種類のボードを使ったもので、その間に噛ませるボードを自作されたそう。

センサを取り付けたり Wi-Fi 越しに操作できるなんてまさに夢のようですね!

ネタ要素もたくさん取り入れられて面白かったし、内容もとても濃かった (というか私が興味あるだけ?) と思います。

@ueponx さん

www.slideshare.net

題名は「DragonBoard410cを使ったソーシャルTVリモコンの作成」

ネットからトレンドのテレビ番組を取得して自動でチャンネルを切り替えるというもの。

最近のテレビは高機能になってネットワークからチャンネル操作とかもできるようになっているので、 Wi-Fi を使って操作するものかなぁと思っていたのですが、実際には赤外線を使ったリモコンでした。

自宅のテレビの操作で検証されていましたが、コマンドをちょっと変えるだけで各社のテレビに対応できるのでとても実用性が高そう。

テレビの機能として実現するのではないので、まさに インターネット を駆使した IoT だなぁと考えさせられました。

更に声まで出せるという、なんともハイテクな機能もついているそうで。もはやスマートスピーカーと言えると思います。

ぶぁぶぁくん さん

題名は「太陽光発電を監視したい!」

connpass で題名見た時、一体どのレベルの話をされるんだろうと不思議に思ったのですが(屋根に太陽光載せる時には基本的に HEMS ってついてくると思うし)

発表を聞いてみたら、趣味の範囲で太陽光パネルを買い、趣味の範囲で HEMS を 1 から作ってらっしゃるという素晴らしい内容でした。もはや IoT じゃねぇ。

とはいえ、その発電量を手動で確認・集計するのは面倒という事で、センサから取得した情報を VPS に流して集計する、というシステムを考えられているみたいです。

将来的には発電量を自動的に視覚化したり、遠隔で負荷を接続・切断したりできるようになるという、私ら SIer 泣かせのシステムが完成するそう。

ほんとに趣味の世界って広いなぁ…。と思います。

ytsuboi さん

題名は「名古屋駅裏にLoRaがやってきた」

LoRa という Low-Power Wide-Area 通信の一種の共有ゲートウェイを、駅裏にあるオフィスに設置されたそう。

IP 通信ではないとか、SORACOM のゲートウェイ・ネットワークサーバなので現状 SORACOM のシールドでしか繋がらないとか制限はあるものの、とにかく省電力で運用できるものだそう。

実際に街を歩いてどこまで電波が取れるかと調べた結果、実測 500m ほど飛ぶそうで (オフィスが1階のため) 、円を描けば駅西もすこしの距離カバーできてるみたいです。

タッパーを持ち歩いている姿見たかったなぁ

IoT が注目されるに従って、こうした省電力な通信ってどんどん注目されてきている気がしますよね。これを広めていく方々、いわゆるフロンティアな方々は、本当に尊敬します。

もしかしたら将来 LoRa が一斉を風靡するようになるのかもしれませんね?

くぅ さん

題名は「」

出来れば Unicode 座標書いて欲しかった

Android Things 使ってみたよ!という紹介。そういえばそんなものもありましたね…。

Raspberry Pi など IoT 向けの Android ビルドで、 Java や Kotlin で開発できる非常にユーザフレンドリな OS らしいです。

インストールもネットからイメージを落としてきて SD カードに焼けば認識するみたい。非常にお手軽。

IoT なだけにピン操作が標準 API として用意されているそうです。

ところが、 GUI を扱えるがために通常の Android のアプリを動かせるかなぁとやってみると、簡単には動かず。本家 Android にはあって Things には無い API が多数存在したり、非推奨という名の非対応があったりするそう。

スペック的に追いつかないとか、そもそもフル Android 動かす必要がないとか理由はたくさんありそうですが、これだけ聞くとなかなか手が出せないですね…。

kaizen_nagoya さん

www.slideshare.net

題名は「IoT のサイバセキュリティ対策」

最初の方、 Q&A 形式でこんなの知ってますかーという質問が20問30問くらいあったのですが、全くわからず…。

というのも、セキュリティについての団体を作ろうという計画をされているそうで、それくらい知識がないと務まらないほど高度な作業のようです。

多くの方からシミュレータでいいじゃんなど突っ込まれていたのですが、真摯に

「オーバースペックな処理をしてマシンが燃えた時どうなるか、を検証しなければいけない」

と答えられていて、本当に高度すぎるお話ですありがとうございました。

私達の普段知らないところで、こうした超高度な方々が作業されているからこそ、私達が平和にプログラミングを組めているんだなと思います。本当に感謝です。

わみ さん

題名は「クラウドファンディングの話」

Nerfy というデバイスを作成されているそうで、その資金の調達をクラウドファンディングで行われたそうです。

codezine.jp

会社で別のデバイスクラウドファンディングが成功したので、これはいけるのでは?と挑戦されたのがきっかけだそう。

結果、無事大成功され生産決定されました。おめでとうございます!

ただ実際に当事者になってやってみると大変なことが多かったそうで、量産しなきゃとか、告知しなきゃとか色々と不安要素は多かったみたいです。

そう言われれば、私がこの間投資した Nintendo Switch 用のポータブル充電器を知ったのも、ネットのニュースサイトで取り上げられていたからで、ああいう場所で知らなければ全く気づかずにスルーしてたんだなぁと。

表では手軽で気楽なイメージですが、裏では必至に作業をされているんだなぁと感じました。

まとめ

初の LT 大会とだけあって、終わってみると他の勉強会よりヒアリング重視だったなぁと思います。要するにメモが少ない。

いろいろ笑いを交えながら思われたことを素直に発表されていて、みなさん本当に楽しまれているんだなぁと感じました。

これからどんどんデバイスが普及していって、もはや IoT と特別視されなくなっても、こうした体験が基礎として活きてくるのかもなぁと。

また一段と興味が湧いて来ました。本当にありがとうございました。そして、お疲れ様でした。

コレクション初期化子とオブジェクト初期化子はどちらが優先されるのか

ちょっと気になったのでメモ。

結論

オブジェクト初期化子のほうが優先される

実験

No.1

まず、普通にオブジェクト初期化子を書く。

using System.Collections.Generic;

namespace ClassInheritedListSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Hoge hoge = new Hoge { A = 1, C = 2 };
        }
    }

    class Hoge
    {
        public int A { get; set; }
        public string B { get; set; }
        public int C { get; set; }
    }
}

オブジェクト初期化子に違いない。

No.2

次に、 List<int> を継承してみる。

using System.Collections.Generic;

namespace ClassInheritedListSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Hoge hoge = new Hoge { A = 1, C = 2 };
        }
    }

    class Hoge : List<int>
    {
        public int A { get; set; }
        public string B { get; set; }
        public int C { get; set; }
    }
}

オブジェクト初期化子のままだ。

f:id:yuzutan_hnk:20170923022100p:plain:w600

No.3

次に、 Program クラス側に同様のプロパティを定義する。

using System.Collections.Generic;

namespace ClassInheritedListSample
{
    class Program
    {
        public static int A { get; set; }
        public static string B { get; set; }
        public static int C { get; set; }

        static void Main(string[] args)
        {
            Hoge hoge = new Hoge { A = 1, C = 2 };
        }
    }

    class Hoge : List<int>
    {
        public int A { get; set; }
        public string B { get; set; }
        public int C { get; set; }
    }
}

オブジェクト初期化子のままだ。

f:id:yuzutan_hnk:20170923022359p:plain:w600

No.4

Program に用意したプロパティの型を変えてみる。

using System.Collections.Generic;

namespace ClassInheritedListSample
{
    class Program
    {
        public static int A { get; set; }
        public static int B { get; set; }
        public static int C { get; set; }

        static void Main(string[] args)
        {
            Hoge hoge = new Hoge { A = 1, B = 2 };
        }
    }

    class Hoge : List<int>
    {
        public int A { get; set; }
        public string B { get; set; }
        public int C { get; set; }
    }
}

これもオブジェクト初期化子のまま。 Hoge.B の型が int じゃないと怒られる。

f:id:yuzutan_hnk:20170923022737p:plain:w600

No.5

かっこで括る。

using System.Collections.Generic;

namespace ClassInheritedListSample
{
    class Program
    {
        public static int A { get; set; }
        public static int B { get; set; }
        public static int C { get; set; }

        static void Main(string[] args)
        {
            Hoge hoge = new Hoge { (A = 1), (B = 2) };
        }
    }

    class Hoge : List<int>
    {
        public int A { get; set; }
        public string B { get; set; }
        public int C { get; set; }
    }
}

やっとコレクション初期化子になった。

f:id:yuzutan_hnk:20170923022932p:plain:w600

どうしてこうなるのか

C# 5.0 の言語仕様 7.6.10.3 項を見ると、書いてあります。

コレクション初期化子は、"{“ トークンと ”}“ トークン内のコンマで区切った要素初期化子のシーケンスから構成されます。各要素初期化子は、初期化対象のコレクション オブジェクトに追加する要素を指定し、”{“ トークンと ”}“ トークン内のコンマで区切った式のリストから構成されます。単一式の要素初期化子は、 かっこなしで作成することができますが、メンバー初期化子とのあいまい性を防ぐため、代入式にすることはできません 。non-assignment-expression の生成は 7.18 で定義されています。

ここでいうメンバー初期化子とは、たぶんオブジェクト初期化子で使用される A = B の形式のものだと思われます。明確な定義が見つけられないのですが、オブジェクト初期化子の説明にもメンバー初期化子という言葉が使われています。

オブジェクト初期化子では、メンバー初期化子の形式は次のようにあります。

オブジェクト初期化子は、"{“ トークンと ”}“ トークン内のコンマで区切った一連のメンバー初期化子から構成されます。各メンバー初期化子では、 初期化対象のオブジェクトのアクセス可能なフィールドまたはプロパティを指定し、その後に等号と式、またはオブジェクト初期化子かコレクション初期化子を指定する 必要があります。オブジェクト初期化子に、同じフィールドまたはプロパティに対する複数のメンバー初期化子を含めるのは誤りです。オブジェクト初期化子は、初期化対象の新しく作成したオブジェクトを参照することはできません。

上記二つから考えるに、コンパイラ的には

  • 名称 = から始まる要素が1つでもあれば、オブジェクト初期化子
  • のみで構成される要素しかなければ、コレクション初期化子

と分類している気がします。

dynamic なオブジェクトに IntelliSense を表示する

ネタです。ホントは出ちゃいけないんじゃないの?という記事。

Visual Studio 2015 で最初確認したんですが、家に帰ってきて 2017 でやってみても同じ結果でした。

Roslyn のせいなのかな?

コード

namespace dynamicIntelliSenseTest
{
    class Program
    {
        static void Main(string[] args)
        {
            (0 as dynamic) // この後ドットをつけると補完が出てしまう
        }
    }

    static class Hoge
    {
        public static void ホントは出ちゃいけないんじゃないの(this object hoge){
            return;
        }
    }
}

f:id:yuzutan_hnk:20170908012633p:plain:w600

dynamic の実態は object 型なので間違ってはいないのですが、入力した後は定義を紛失するようです。

f:id:yuzutan_hnk:20170908013007p:plain:w600

現在 0000/00/00 00:00 を生きています。