プロジェクト作りなおして一周回ってきた

by orekyuu 0 Comments

Play最高とか言ってたけど、ajax周りが非常に面倒になってきた。
JSFが使いたい。GlassFish+JavaEE7に戻ってきた。
サーバーの設定は面倒な感じあるけど、なんだかんだで一番よい選択かもしれない。

PlayのScalaテンプレートも面白いけど個人的にJSFが一番しっくりきた感じある。
とか書いてるけど多分数日後にまた変えてると思う。たぶん。

プロジェクト作りなおした(n回目

by orekyuu 0 Comments

SpringBootとかいろいろ試した結果、PlayFrameworkに落ち着いた。
よさ気感ある。というかドキュメントがよく揃ってるのが良い。

問題は学校のチーム製作の授業でPlayFrameworkを使うとなった時チーム組める人がいないって話。
Java触っている人がほとんどいない状態で、ScalaとかFrameworkの規約とか追加で覚えてねってなった時に「一緒にやりたい」となってくれる人いないと思う。
どうしましょうかね・・・

サーバーサイドジャバ始めた

by orekyuu 0 Comments

最近はじめました。
僕はJavaFXとかマイクラみたいなJavaSEしか触ったことがないんだけど、学校の演習でサーバーサイドでなにか作ることになったのでサーバーサイドJavaに手を出してみることにしました。

JavaEE7とかPlayFrameworkとかいろいろ勧められたけど、JavaEEはGlassFishの設定面倒だしjar叩いて起動できるようにしたかったので少し触ってやめて、PlayFrameworkは良さ気だったけどチームで作ることが前提になっていてScalaとか覚えてくれないだろうなということでこれも候補から除外・・・

何か良さそうなのないかなといろいろ試してみたんだけど、SpringBootとか結構良さそうだったのでそれを選択。
とはいえ情報が少なめなのがつらい・・・。どこかに情報まとまってないかな。

少し触った感想としてはJPAすごい使いやすい。JSF最高って感じ。
これから進捗あった時とかは記事にすると思います多分。

MinecraftのModdingで必要なjsonを生成するライブラリを作った

Minecraft1.8からItemModelやBlockModelのjsonを書く必要が出てきて面倒じゃないですか?
僕は見た目の部分をコードから排除するのはすごい良いと思うんだけど、使い回しができずにファイルを複製してひたすら増えていくのはどうかと思うんです。

そこでテンプレートをベースにコンパイル時に生成するライブラリを作りました。
コードはこんなかんじになります。

public class BlockSample {

    @BlockModel(name = "block1", args = {"blocks/brick", "blocks/clay"}, template = "sample:block_base")
    @BlockState(name = "block1", args = {"sample:block1"}, template = "sample:state_base")
    @ItemModel(name = "block1", args = {"sample:block/block1"}, template = "sample:item_block_base")
    @Languages({
            @Language(value = "サンプルブロック1", name = "sampleBlock1", lang = LangType.JA_JP, target = LangTarget.BLOCK),
            @Language(value = "Sample Block 1", name = "sampleBlock1", lang = LangType.EN_US, target = LangTarget.BLOCK)
    })
    public static final Block block1 = new SimpleBlock();
    @BlockModel(name = "block2", args = {"blocks/clay", "blocks/brick"}, template = "sample:block_base")
    @BlockState(name = "block2", args = {"sample:block2"}, template = "sample:state_base")
    @ItemModel(name = "block2", args = {"sample:block/block2"}, template = "sample:item_block_base")
    @Languages({
            @Language(value = "サンプルブロック2", name = "sampleBlock2", lang = LangType.JA_JP, target = LangTarget.BLOCK),
            @Language(value = "Sample Block 2", name = "sampleBlock2", lang = LangType.EN_US, target = LangTarget.BLOCK)
    })
    public static final Block block2 = new SimpleBlock();

    public static void init() {
        CoreProxy.proxy.registerBlock(block1, "block1");
        CoreProxy.proxy.registerBlock(block2, "block2");
    }
}

@BlockModelテンプレートはこんな感じ

{
  "parent": "block/cube",
  "textures": {
    "particle": "{1}",
    "down": "{0}",
    "up": "{0}",
    "north": "{1}",
    "south": "{1}",
    "west": "{1}",
    "east": "{1}"
  }
}

テンプレートの{index}は@BlockModelのargsの各インデックスにバインドされています。
これで同じテンプレートからテクスチャだけ違うBlockModelのjsonが生成されます。
同じように@ItemModelと@BlockStateも利用できます。

次に@Languageはlangファイルへの書き込みを行います。
1つのアイテムやブロックに複数の翻訳を指定したい場合は@Languagesに配列で@Languageアノテーションを入れます。
valueに翻訳後の値
nameにunlocalizedName
langに翻訳言語
targetに翻訳のタイプを指定します。
コンパイル時にアノテーションが処理されてlangが生成されます。

次に必須となるアノテーションを紹介

@Mod(modid = SampleMod.MODID, version = SampleMod.VERSION)
@ResourcesDomain("sample")
@ModID(SampleMod.MODID)
public class SampleMod
{
    public static final String MODID = "sample";
    public static final String VERSION = "1.0";
    
    @EventHandler
    public void init(FMLInitializationEvent event)
    {
        ItemSample.init();
        BlockSample.init();
    }
}

これはエントリポイントのクラスですが、クラスに付けられている@ResourcesDomeinと@ModIDがこのライブラリのアノテーションです。
@ResourcesDomeinは生成されるファイルのドメインを指定します。
多重定義はできません。これが使用されると各リソース生成用アノテーション(@BlockModelとか@ItemModel)のdomeinのデフォルト値として利用されます。
複数のドメインを使いたい場合は1つだけ宣言しておき、その他のドメインはdomein要素を指定してください。

@ModIDはModIDを指定します。
これは多重定義不可で、必ず指定する必要があります。

この2つのアノテーションはエントリポイントとなるクラスに置くのが良いと思います。

最後にこのライブラリの利用方法。
ビルド済みのjarを用意して{projectDir}/libs/MinecraftForgeAnnotations-1.0.jarのように配置します。
build.gradleに以下を追加

//依存関係にMinecraftForgeAnnotationsを追加
dependencies {
    compile files('libs/MinecraftForgeAnnotations-1.0.jar')
}

compileJava {
    //アノテーションプロセッサを指定
    options.compilerArgs += ['-processor', 'net.orekyuu.minecraftanotations.apt.MinecraftAnnotationProcessor', "-Adir=" + file('templates')]
    doLast {
        //コンパイルが終了したらアセットを適切な位置へコピー
        tasks.copyAssets.execute()
    }
}

task copyAssets(type: Copy) {
    from 'build/classes/main/assets/'
    into 'out/production/Minecraft/assets/'
}

-Adirオプションではテンプレートの配置ディレクトリを指定しています。

テンプレートはtemplatesフォルダに配置してください。
動く形になっているサンプルも用意しておいたので良かったら確認して下さい。
サンプルプロジェクト
MinecraftForgeAnnotationsのリポジトリ

バグ報告や要望などはリポジトリのIssueにお願いします。
プルリクエストも待ってます。

富山でぶりしゃぶ食べてきた話

by orekyuu 0 Comments

富山のぶりしゃぶ勉強会に行ってきた。

今まで参加したものと比べると結構特殊で、朝からセッションが始まって終わってから懇親会して宿泊って流れだった。
夜行バスで行ったのでなかなか眠れなくてセッション中ところどころウトウトしてしまったのが無念・・・
セッションは面白そうなのが結構多くてどちらを見に行こうかすごく悩んだけど結局すべてJava会場で見てました。
僕が話してたセッションの裏でやってたVisualStudio2015の話すごい気になってた!できれば全部見たかったなぁ・・・影分身したい人生だった。

その後の懇親会ではブリしゃぶを堪能。


すごいおいしかった!

二次会では寺田さんにJava puzzlerのスライドを見せてもらってJavaのクイズを解いて盛り上がりました!
面白かったので解いて欲しい!
あとは面白い動画を見せてもらったので貼っておきます。

Concurrency Utilitiesをきちんと使えばこんなにCPUを効率よく使うことができるんですね。
まさかThread生で使ってる人はいませんよね?(書き直しながら

宿泊して楽しむタイプの勉強会だったのでいろいろなエンジニアの方と会話出来たのは非常に楽しかったです。
来年も行きたい!よろしくお願いします!

ジェネリクスとオーバーロード

by orekyuu 0 Comments

最近public boolean equals(Hoge)のようにオーバーロードしているequalsメソッドを見かけたので気になって調べてみた。
意図としては「Hogeでオーバーロードしとけばキャストの検査とかいらなくね?」というのがあるんだと思う。たぶん。
で実際正常に動くのか。

Hogeクラスにintのidをもたせてidを比較するequals(Hoge)を作成し、HashSetに追加してみる。
で、だめでした。

どうやらboolean equals(Object)の方が使われている様子。
ジェネリクスが怪しいなということで次のコード

public class Hoge {
 
    private int id;
 
    public Hoge(int i) {
        id = i;
    }
 
    public boolean equals(Hoge obj) {
        return obj.id == id;
    }
 
    @Override
    public int hashCode() {
        return id;
    }
}
public class Main {
    public static void main(String[] args) {
        Hoge hoge = new Hoge(1);
        Hoge hoge1 = new Hoge(1);

        System.out.println(hoge.equals(hoge1));
        System.out.println(isEqual(hoge, hoge1));

    }

    public static <T> boolean isEqual(T hoge, T hoge2) {
        if (hoge == null || hoge2 == null) {
            return false;
        }
        return hoge.equals(hoge2);
    }
}

出力結果
true
false
となりました。

理由をTwitterで聞いてみたんですが、境界が指定されていないTにはどの型がバインドされる可能性もあるので、それを受け止められるのはObjectだけとなり、引数がObjectのequalsが使用されているということでした。
たとえば<T extends Hoge>とすればhoge.equals(Hoge)が呼び出されるっぽい。

ということでequalsでオーバーロードするのは使えないよって話でした。(たぶんやってる人いないと思うけど

2015年あけましておめでとうございます

by orekyuu 0 Comments

あけましておめでとうございます。
今年も一年頑張るぞい!

今年はJavaEEとか鯖サイド勉強しようと思ってます。
あとは今年で3回生なので就職のことも考えないとですね・・・うっ頭が。

それはさておき書き初めです。
今年はセミコロンレスJavaというのがあると聞いたことがあるのでチャレンジ
0から2015までカウントしながらのFizzBuzzですね。

https://gist.github.com/orekyuu/ca569e67b27cb8e837fd

peek見つけるまで悩んだのと、完全修飾名でimport書かなくて済むことを完全に忘れていたので時間かかりました・・・

今年もよろしくお願いします。

Javaビーム工房で学んだチーム開発の難しさ

by orekyuu 0 Comments

同じ学校のメンバーに声をかけて一緒に作っていたTwitterクライアントのα版がようやく出せた。
10月1日から始めたので大体3ヶ月くらい。まぁバグとか結構あったり未実装の部分もあるけどまぁ満足の行くところまでできたと思う。
チーム開発の経験はあまりないけど、3ヶ月ほどやってみて課題とかをまとめてみたいと思う。

今回のプロジェクトはgitとgradleを使った。
プロジェクト構成としては、JavaBeamStudioにJavaBeamStudioAPIとJavaBeamStudioAppの二つのサブプロジェクトがあるだけ。

プロジェクト開始時にgradleラッパーをプロジェクトに入れておくと、チームメンバーの環境が整えやすくて非常に良かった。
各自作業がしやすいようにEclipseかIntelliJの好きな方を使ってくれというスタンスだったが、今になってすごく後悔している。
というのも、コードのフォーマットがばらばらでタブでインデントする人が居たりしてひどいことになった。
最終的にαビルド前に全体にフォーマットかけることにしたが、rebaseするときに「あっ・・・(察し」となるのは目に見えている。

やっぱりIDEは統一させておいたほうがいいのかもしれない。
フォーマットの問題が解決すれば各自使いやすいものでいいと思うけど・・・(各自のモチベーションも上がるだろうし。

開発の流れは、週1回のスカイプ会議で各メンバーにタスクを割り振り、release-1.0.0から新規ブランチを作って完成すればプルリクエストを作成してマージする方法をとっているが、あまり効果が実感できていない。実際バグが大量に出ている。
もう少し厳しいチェックを通す方法を考えたいと思う。

JavaFX Advent Calendar25日目 ~ JavaFXで夢のCanvasライフ

by orekyuu 0 Comments

この記事はJavaFX Advent Calendar25日目の記事です。
前回はs_kozakeさんのAndroidでJavaFXを動かしてみたよ!でした。

みなさんCanvas使ってますか?
使ってない人は今日から夢のCanvasライフを始めませんか?

ところで今日はクリスマスですね!

クリスマスらしく、クリスマスツリーでも見ましょう!
クリスマスツリー

というわけで今回はCanvasを使ってクリスマスツリーを作った話です。

完成品をおいておくのでぜひ触ってください。クリックした所に赤いライト置けます。

Canvasの使い方ですが、かなり簡単です。

Canvas canvas = new Canvas(CanvasWidth, CanvasHeight)
GraphicsContext g = canvas.getGraphicsContext2D();

g.fillOval(x, y, width, height);//○書くよ

のようにGraphicsContextを使って描画していくだけです。

Appletとかに似てるなーと思っていたんですが、Java2D作ってた人がCanvas作っていたみたいですね。
そりゃ似ているわけだ。

ライトや雪が落ちたりするアニメーションはAnimationTimerを使います。

AnimationTimer animationTimer = new AnimationTimer() {

    @Override
    public void handle(long now) {
        GraphicsContext g = canvas.getGraphicsContext2D();
        g.clearRect(0, 0, CanvasWidth, CanvasHeight);
        //背景
        drawSky(g);
        //星を描く
        drawStar(g, now);
        //木を描く
        drawTree(g);
        //ライトを描く
        drawLight(g, now);
        //雪を描く
        drawSnow(g, now);
    }
};
animationTimer.start();

あとは説明するものも特に無いので、コードをgistにおいておきます。
https://gist.github.com/orekyuu/afb416d5c722edeeb79e

最終日はskrbさんです!よろしくお願いします!

ついに僕のコンパイラにデレ期が来た

by orekyuu 0 Comments

Javaビーム工房でJAXB使ってたら可愛いエラーメッセージに出くわした。

無題

確実にこれはデレ期でしょ!「1つで十分です。」って付け加える所が非常に可愛い。
コンパイラ「別に一つでいいんだよ///」的なものを感じてテンションあがった。

疲れてるのかな・・・おやすみなさい。