読者です 読者をやめる 読者になる 読者になる

PG日誌

プログラミングの事とか。主にc#。

ASUS Zenfone3でメニューボタンを使用する

ガジェット 雑記

Zenfone3ですが、物理センサーキーなので履歴ボタンを長押しするとメニューが出るはずが初期設定のままだとスクリーンショットが撮影されてしまします。が、この動作設定から変更できます。変更方法は以下の通り

メニューが出ないと操作できないアプリも多いので長押しでメニューが出るように設定を変更します。

設定 > ASUSカスタマイズ設定 > --- タッチキーグループ --- > マルチタスクボタン

から

「ボタンを押し続け、スクリーンショットを保存する」

「ボタンを押し続け、メニューを表示する」

に変更。

これで長押しするとメニューが出るようになります。

f:id:Takachan:20160827220558j:plain:h500

押すと、、、、

f:id:Takachan:20160827220604j:plain:h500

メニューが出ます。

ZenFone 3(ZE520KL)白、開封 & レビュー

ガジェット 雑記

ASUS ZenFone3 ZE520KL(白)を手に入れたので開封と簡単なレビューをしたいと思います。黒のほうが1か月早く発売されていたので、レビューは黒の機種の画像が多いた(せっかくなので)白の画像をアップします。

ご注意:
当方ガジェットレビューなんてしたことないのでいろいろお察しください。
Xperia GX(化石)で画像を撮ってるので撮影するたびに色が違いますがこれで限界みたいです。
あと、家で撮影してていろいろ映り込むんでアングルがおかしいとかも勘弁してください。

化粧箱

これは、黒と同じですね。

f:id:Takachan:20160827162703j:plain:h550

取り出したところ

第一印象は、結構でかいな!でした。
端末の大きさは5.2インチですが5インチと比べても大きい感じがします。

べセルがまぁまぁ細いので画面がいっぱいに広がっています。

f:id:Takachan:20160827162706j:plain

フィルム剥きました

白はフロントパネルが白いです。質感がツルツルしてて光沢があります。
サイドバーのアルミ部分がほんのり金色でかっこいいです。

f:id:Takachan:20160827162710j:plain:h550

右サイド

先出の黒と同じく上から音量ボタン、電源ボタンになっています。
サイドがほんのり金色でかっこいいです(大切なことなので2回言いました)

f:id:Takachan:20160827162713j:plain:h550

トップサイド

上側は、イヤホンジャックがついてます。

f:id:Takachan:20160827164240j:plain

左サイド

上のほうにSIMとSDカードスロットが見えます。

f:id:Takachan:20160827164321j:plain:h550

ボトムサイド

USB-TypeC の充電口がついてます。
なんだか某リンゴの○Phoneにちょっと似てますね(謎)

f:id:Takachan:20160827164554j:plain:h550

裏側

手前から撮影。指紋認証とカメラ、フラッシュなどがついています。
指紋認証のフレームだけサイドフレームと同じくやや金色ががっています。
カメラの盛り上がりは普通の銀色でした。なんで?w

f:id:Takachan:20160827162716j:plain:h550

裏側(横から)

カメラが少しだけ出っ張っています。

f:id:Takachan:20160827162719j:plain

カメラのでっぱり

1-2mmくらいせりあがってるんですかね?
接合部分はしっかりくっついていて加工精度は結構よいですね。

f:id:Takachan:20160827162723j:plain

手持ちしたとき

で、、、でかい!!!
無理ではないですが、これ以上大きいと片手では無理になりそうなギリギリのライン。

f:id:Takachan:20160827162726j:plain:h550

親指の到達範囲

端までは普通に届きます。(男目線)
半分より上は、この握り方だと全然届かないです。

f:id:Takachan:20160827162729j:plain:h550

まとめ

新しガジェットに浮かれて冷静なコメントはできませんw

が、台湾製と侮るなかれ、たった3万円ですが普通に質感がいいです。

あとXperiaGXの半分の厚さしかないので大画面ですが持った感じかなりコンパクトです。
144グラムだそうですが、重さはほとんど感じないでいです。

よく見たことないですがちょっとリンゴの○Phoneに似てる気がしないでもないですね。


ただ、この端末、発売されたばかりで白はプレミアがついています。(えぇ)
Amazonとかで3万5千円弱、eBayでは3万2千円弱で販売されています。

246ドルで販売しているので割高感がぬぐえません。PCパーツでいう今は時期が悪いってやつですね。
あと2週くらいすれば価格も落ち着くのではないでしょうか。

5.5インチ

5.2インチ

補足:
日本未発売端末のため、購入は並行輸入品や個人輸入となります。
各種トラブルは自己責任でお願いします。

Cocos2d-xのwin32プロジェクトをgen-libsで高速化する

cocos2d-x c/c++ 技術ネタ

タイトルの通りですが、win32プロジェクトで、あらかじめgen-libsコマンドで作成したライブラリをリンクして、コンパイルの時間を高速化します。

iOSだとスタティックライブラリを使用して高速化するあたりの話と同じです。

ちなみに、元ネタは以下のフォーラムです。
が、このforumプロジェクトのファイルを手で書き直せなどなかなか難易度が高いのでVisualStudio(GUI)上で作り方を説明したいと思います。

元ネタ
f:id:Takachan:20160815154658p:plain
discuss.cocos2d-x.org

ちょっと長いですが、最後までお付き合い頂けたらと思います。

開発環境

開発環境は以下の通りです。

Item Value
OS Windows10
IDE VisualStudio2015 Community版
Cocos2d-x 3.11.1

前提条件

Cocos2d-xは以下の通りインストール済みとします。

D:\ProgramFiles\Cocos\cocos2d-x-3.11.1

環境変数は上記パスでsetup.pyを使用したので以下の通りになっています。

[PATH]
D:\ProgramFiles\Cocos\cocos2d-x-3.11.1\templates
D:\ProgramFiles\Cocos
D:\ProgramFiles\Cocos\cocos2d-x-3.11.1\tools\cocos2d-console\bin

[COCOS_CONSOLE_ROOT]
D:\ProgramFiles\Cocos\cocos2d-x-3.11.1\tools\cocos2d-console\bin

[COCOS_TEMPLATES_ROOT]
D:\ProgramFiles\Cocos\cocos2d-x-3.11.1\templates

[COCOS_X_ROOT]
D:\ProgramFiles\Cocos

pre-builtコマンドの実行

早速始めたいと思います。
まずはコマンドプロンプトで以下のコマンドを打ち込んで実行します。

cocos gen-libs -p win32 --vs 2015 -m debug

かなり時間がかかるので完了までしばらく待ちます。
完了すると以下のパスにLibやDLLが生成されているので中身を確認します。

D:\ProgramFiles\Cocos\cocos2d-x-3.11.1\prebuilt

これを以下のフォルダを作成して中身をすべて移動します。

D:\ProgramFiles\Cocos\cocos2d-x-3.11.1\prebuilt\win32\Debug

プロジェクトの作成

すでに作成済みのであれば不要ですが、cocos newコマンドを使ってプロジェクトを新規に作成します。

cocos new Sample -d D:\Development -p com.sample -l cpp

VisualStudioの起動

Cocosプロジェクトのwin32プロジェクトを起動します。

ソリューションファイルを選択して開きます。

f:id:Takachan:20160815150300p:plain:h200

起動するとこんな感じになっていると思います。

f:id:Takachan:20160815150330p:plain:h200

プロパティシートの入れ替え

プロパティファイルの入れ替えを行います。
今は表示するにもわかりにくい位置にあるのですが、まずプロパティマネージャーウインドウを表示します。

画面上部のツールバーから以下を選択します。

表示 > その他のウインドウ > プロパティマネージャー

f:id:Takachan:20160815150634p:plain:h200


プロパティマネージャウインドウから作成したプロジェクトのDebug側のプロパティを表示します。

f:id:Takachan:20160815150942p:plain:h200

ここでツリーに表示されている以下を削除します。

"cocos2d_headers"
"cocos2dx"

f:id:Takachan:20160815151533p:plain

新しいプロパティシートを追加します。

Debugを右クリックして「既存のプロパティ シートの追加」を選択します。

f:id:Takachan:20160815151540p:plain

ファイル選択ダイアログが出るので以下のパスを指定します。(複数は選べないので2回操作します)

D:\ProgramFiles\Cocos\cocos2d-x-3.11.1\cocos\2d\cocos2d_headerd.proprs
D:\ProgramFiles\Cocos\cocos2d-x-3.11.1\cocos\2d\cocos2dx.props

f:id:Takachan:20160815151954p:plain

追加が完了すると以下のような表示になります。

f:id:Takachan:20160815152154p:plain

ライブラリパスの変更

次はライブラリパスの変更です。

Sampleプロジェクトのプロパティを選択してプロパティダイアログを表示します。
ダイアログの右側のツリーから

VC++ ディレクト

を選択し、右側のリストの

「ライブラリディレクトリ」

を選択します。

f:id:Takachan:20160815152424p:plain:h200

欄の右側の編集ボタンを押して編集ダイアログを表示しDLLがあるフォルダパスを指定します。

f:id:Takachan:20160815152602p:plain:h200

入力が完了すると以下のようになります。

f:id:Takachan:20160815152725p:plain:h200

依存ファイルの追加

次に依存ファイルの追加を行います。

同じプロパティダイアログの右側ツリーから

リンカー > 入力

を選択し、右側リストの

「追加の依存ファイル」

を選択します。また、右側の編集ボタンを押してダイアログから追加の依存ファイルに

libcocos2d.lib

を入力します。

f:id:Takachan:20160815153103p:plain:h200

入力したら[OK]を押して元の画面に戻ると以下のようになります。

f:id:Takachan:20160815153148p:plain:h200

デバッグ環境(環境変数)の追加

次に環境変数の追加の設定を行います。

同じプロパティダイアログの右側ツリーから

デバッグ

を選択し、右側リストの

環境

へ以下の値をそのまま入力します。

PATH=D:\ProgramFiles\Cocos\cocos2d-x-3.11.1\prebuilt\win32\Debug;%PATH%
(必ず"PATH="から入力してください。"d:\"以降だけ入力しても動きません)

入力すると以下のようになります。

f:id:Takachan:20160815153413p:plain:h200

ソリューションから不要なプロジェクトの除去

ソリューションから以下、不要なプロジェクトを削除します。

libbox2d
libbullet
libcocos2d
librecast
libSpine

f:id:Takachan:20160815153955p:plain:h200

削除すると以下の通りになります。

f:id:Takachan:20160815154055p:plain

動作確認

以上で、プロジェクトの設定は完了しましたので動作を確認したいと思います。

"Sample"をスタートアッププロジェクトに設定して、画面上部のローカル Windows デバッガー... を選択します。

以下の通り画面が表示されれば成功です。

f:id:Takachan:20160815154306p:plain:h200

これで、ビルドがかなり早くなったと思います。
お疲れ様でした。

c#のis演算子とtypeofの型判定の挙動の違い

c# 技術ネタ

コード書けばすぐわかる事なんですがis演算子の挙動の話です。

is演算子は複数の型でtrueになる可能性があります。
親子関係がある型で厳密に型を判定したい場合、GetType()とtypeofを使います。

// こんなクラスがあったとして、、
public class BaseClass { }
public class DerivedClass_1 : BaseClass { }
public class DerivedClass_2 : BaseClass { }

// こんなコードを書いたとすると
static void Main(string[] args)
{

    BaseClass test = new DerivedClass_1();

    // is演算子による型判定
    Console.WriteLine("test is BaseClass? = " 
        + (test is BaseClass));
    Console.WriteLine("test is DerivedClass_1? = " 
        + (test is DerivedClass_1));
    Console.WriteLine("test is DerivedClass_2? = " 
        + (test is DerivedClass_2) + "\r\n");

    // typeによる型判定
    Console.WriteLine("test typeof BaseClass? = " 
        + (test.GetType() == typeof(BaseClass)));
    Console.WriteLine("test typeof DerivedClass_1? = " 
        + (test.GetType() == typeof(DerivedClass_1)));
    Console.WriteLine("test typeof DerivedClass_2? = " 
        + (test.GetType() == typeof(DerivedClass_2)));

    Console.ReadLine();
}

出力は以下の通りになります。

test is BaseClass? = True ★この部分
test is DerivedClass_1? = True
test is DerivedClass_2? = False

test typeof BaseClass? = False
test typeof DerivedClass_1? = True
test typeof DerivedClass_2? = False

★の部分で違いがあります。

is演算子はアップキャストできる型の場合trueです。

c#のeventとdelegateの違い

c# 技術ネタ

マウスをクリックした場合などに発生する"イベント"の話ではなく、c#予約語の"event構文"の話です。

f:id:Takachan:20160721155544p:plain

本当にざっくりとした先に結論を書くと、"event構文"は"delegate専用のプロパティ"の一種です。

delegate型をクラス外に公開する場合だけ特別に、"プロパティ構文で公開する"と"event構文"で公開する2種類が選べます。

以下のように自動実装プロパティのように宣言できます。

public class DelegateEvent
{
    // 普通のプロパティで公開する(自動実装)
    public Action<object, EventArgs> PropDelegate { get; set; }

    // event構文で公開する(自動実装)
    public event Action<object, EventArgs> HogeEvent;
}

普通のプロパティで公開した場合デリゲートに対して全ての操作ができるのですが、event構文を使用して公開した場合、利用者からはメソッドの登録と登録解除しかできなくなります。(自クラス内だとデリゲートのように使用できます)

public void Hoge(DelegateEvent source)
{
    // デリゲートのプロパティの操作

    // 自分のメソッドを設定
    source.PropDelegate = this.AnHandler;
    // 自分のメソッドを追加
    source.PropDelegate += this.AnHandler;
    // 登録内容を全部削除
    source.PropDelegate = null;
    // デリゲートを呼び出す(この場合は例外)    
    source.PropDelegate(this, new EventArgs);

    // イベントの操作

    // 自分のメソッドを設定
    source.HogeEvent= this.AnHandler; // ★「できない
    // 自分のメソッドを追加
    source.HogeEvent+= this.AnHandler;
    // 登録内容を全部削除
    source.HogeEvent= null; // ★できない
    // デリゲートを呼び出す(この場合は例外)    
    source.HogeEvent(this, new EventArgs); // ★できない
}

// デリゲートやイベントに設定するメソッド
public void AnHandler(object sender, EventArgs e) { ... }

なので、メソッドの登録解除しかさせたくない場合(オブザーバーパターン的に利用したい場合)event構文を付け加えてデリゲートを宣言します。

重要なのは、event構文を用いた場合、設定元から source.HogeEvent(this, new EventArgs); のようにメソッド呼び出しできなくなり、呼び出せるのは設定したクラス内からのみとなります。

なので「メソッドを運搬したい」や、「ある処理の述語に使用したい」、「デリゲートの終了を待って後続のシーケンスのが継続する」場合普通のプロパティで大丈夫です。

逆に通知しっぱなしの場合、eventでいいとも言えます。

自動実装じゃない場合、以下のように宣言します。

public class DelegateEvent
{
    // 普通のプロパティで公開する
    private Action<object, EventArgs> _PropDelegate
    public Action<object, EventArgs> PropDelegate
    {
        get { return this._PropDelegate; }
        set { this._PropDelegate = value; }
    }

    // event構文で公開する
    public Action<object, EventArgs> _HogeEvent; // ただのデリゲート宣言
    public event Action<sender, MyEventArgs> HogeEvent
    {
        add { this._HogeEvent+= value; }
        remove { this._HogeEvent-= value; }
        // +=, -=でメソッドを複数登録できるようにしておく(お約束)
    }
}

「オブザーバーパターン」の説明はGoFデザインパターンを説明しているサイトがいっぱいあるのでそちらを参照してもらって使い分け方はざっくりと

1. 呼んでほしいメソッドの登録、登録解除しか{させたくない|したくない}場合event構文を使う
2. そうではなくもっといろいろしたい(設定したクラス外からも使う)場合プロパティを使う

かと思います。

補足ですが、event構文を単純に抜いただけだとフィールドを直接公開するだけになってしまうので、eventをとった時は後ろに{ get; set; }を付けるようにしましょう。

// これはよくない

// イベント構文をつけないでデリゲートをそのまま公開
//  => フィールド直接公開になっちゃう
public Action<object, EventArgs> HogeEvent;