Atomコードリーディング Part 1
目的
GUIアプリのアーキテクチャを学ぶ
最近、SPAやらネイティブアプリやらで、GUIアプリの作成力が求められてる気がする。なので、Atomを教材にしてGUIアプリケーションのアーキテクチャを勉強したいと思った。Atomの実装はいいものと仮定して進めてくけど、まあ大丈夫だと思ってる。昔だったらEclipse、NetBeansが勉強になったのかな、とか考えてたけど、自分には辛そう。
あと、アプリケーションのソースコードだけじゃなくて、ビルドとか開発フローとかも見ておけば参考になるんじゃないかと考え中。大規模アプリだとこの辺りも重要ということで。
エッジな技術の使われ方をみる
AtomがReactやらShadow DOMやらを使ってるというのは有名だと思うけど、そういったものがどこでどう使われるのかをちゃんと見ておきたい。Atomでxx使い始めたよ~、と聞いたらすぐに追えるようにしておきたい。Atomならフロントエンドで面白そうなことはだいたい実践してきそうな感じはある。あと、使われてるライブラリとかもその都度調べたい。
自分が使ってるエディタの中身を知る
自分で使ってるエディタの中身を理解して、あわよくば自分で改造してみたい。普段WebStormを使っていたんだけど、最近のフロントエンドの流れについていくにはエディタを自分でいじるしかない、と感じたのも動機のひとつ。ライセンス料払ってるのに常にEAP版使っているのは、ちょっともどかしい。
そんな感じで端からゆっくり読んでいく。見てるソースのバージョンどんどんあがっていくと思う。とりあえずコードリーディング開始時のコミットをメモ。Atomのバージョンでいうとv0.188.0くらい。
ビルド
アプリのソースをみるだけなら、エントリーポイントから見ていけばいいんだけど、ビルド周りも見ておきたいので、ざっくり流れを追っておく。
ビルド方法
ドキュメントに載ってる。とりあえずスクリプト実行すれば、Applications以下にAtom.appができる。
git clone https://github.com/atom/atom.git cd atom script/build # Creates application at /Applications/Atom.app
script/build
簡単なjsスクリプト。script/bootstrap
を実行して、gruntのbuild
タスクを実行している。
script/bootstrap
はざっと見たところnpmやapmの依存パッケージをインストールしている。
Gruntfileとしてbuild/Gruntfile.coffee
を指定している。gruntもgulpみたいにCoffeeScriptをサポートしていたんですね。
Grunt
build/Gruntfile.coffee
自体にはconfig系を定義してるくらいで、個々のタスクはbuild/tasks/*-task.coffee
などにある。もうgrunt使ってないけど、タスクの分け方は結構参考になる。
build
タスクはその名の通りbuild/tasks/build-task.coffee
にある。build
タスク自体はcompile
、generate-license:save
、generate-module-cache
、compile-packages-slug
タスクに依存してる(macならcopy-info-plist
タスクにも依存)。
compile
タスク自体はGruntfile.coffee
にある。
grunt.registerTask('compile', ['coffee', 'prebuild-less', 'cson', 'peg'])
coffee
タスクだけ確認しておく。
coffeeConfig = glob_to_multiple: expand: true src: [ 'src/**/*.coffee' 'exports/**/*.coffee' 'static/**/*.coffee' ] dest: appDir ext: '.js'
appDir
はmacだと/Applications/Atom.app/Contents/Resources/app/
になる。それ以下に出力されたjsファイルが置かれる。
他にもたくさんgruntタスクがあるけど、必要になったら見る。
起動
atomコマンドのシェルスクリプト見たけど、よくわからなかった。まあ、起動はatom-shellがやってくれるはず。
ドキュメント見てたら、atom-shellのチュートリアルにメインプロセスについて書かれていた。
package.json
のmain
スクリプトを実行するプロセスがメインプロセス(main process)と呼ばれるみたい。main
には./src/browser/main.js
が指定されてるので、これがエントリーポイントだと考えてよさそう。
メインプロセスから実行されるスクリプトはウェブページを生成することによりGUIを表示できる。
atom-shellはウェブページを表示するのにChromiumを使っていて、ウェブページそれぞれにもプロセスがある。それはレンダラプロセス(renderer process)と呼ばれる。
2つのプロセスの詳細な違いは必要になったら調べる。
src/browser/main.coffee
エントリーポイント。start
関数が定義されていて、それが実行される。
start
関数でやってること
CoffeeScriptのキャッシュは特に追ってない。coffee-cashというものを使っていた。キャッシュディレクトリを指定して登録しておけばファイル単位でキャッシュしてくれるみたい。なんか便利そう。
コマンドライン引数のパースはsubstack氏のoptimistというライブラリでやってた。便利そうなので、コマンド作るときに使ってみたい。開発時に使えそうなコマンドオプションにdevモードがある。コマンドオプションの使い方がわからなかったら、この辺り読めばすぐわかりそう。
appモジュールというのはatom-shellアプリケーションのライフサイクルをコントロールするやつみたい。ライフサイクル系のイベントの発火もしてくれる。ここではready
イベントはハンドラを設定してる。ready
はその名の通りatom-shellの初期化が終わったところで発火する。
ready
ハンドラではsrc/browser/atom-application
をrequireして、それのopen
メソッドを呼んでる。いよいよ始まりといった感じがする。
app.on 'ready', -> # ~ 省略 ~ if args.devMode AtomApplication = require path.join(args.resourcePath, 'src', 'browser', 'atom-application') else AtomApplication = require './atom-application' AtomApplication.open(args) console.log("App load time: #{Date.now() - global.shellStartTime}ms") unless args.test
最初に頑張っても続かないので、続きはあとで
参考
ソシャゲ会社に入って2年ちょっとくらいのまとめとこれから
ソシャゲ作ってる会社に新卒で入って今年で3年目になった。このブログは入社当時になんかアウトプットしなきゃと思ってつくったものなんだけど、最近はまったく書いてないし、存在すら忘れてた…
定期的にアウトプット衝動に駆られるけど、普段からやってないからなかなか書けない。今回は、そのアウトプット衝動と帰省が重なって暇だったので、なんとなく書いてみた。だから、普段mac使ってるけど、実家のWindows使って書いてる。OSはいいんだけどJISキーボードつらい、ソフトもいれたくないからMarkdownはChromeのエクステンションを使ってる。
何書くかなあ?と思ったけど、久しぶりだし、会社入ってやってきたことのまとめとか環境や思考の変化を書いておく。ソシャゲエンジニアとしてはレアケースな気がしている。
心機一転してブログとか書こうとすると、過去記事を一気に消したくなるけど、今回は残しておく。今見ると、ああ…とか思う。
概要
- ソーシャルゲーム作ってた会社の環境は変わり続けてる(ブラウザとネイティブの話)
- フロントエンドエンジニアである僕自身が環境の変化にどう対応していくか
- おもしろいと思ってることがあるので、やれるうちはやる
やってきたこと流れ
1年目
研修があったので本格的に現場に入っていったのは7月くらい。ガラケーとスマホ向けのいわゆるソーシャルゲームを作っていて、技術的にはLAMPとHTML/CSSでオーソドックスな感じ。Flashが多用されていること以外は一昔前のwebページと大差ない。JavaScriptはほとんどなかった。
Flashアニメーションすげーとか負荷つれーとか思ってた。とあるプロジェクトでインフラはやらないけど、サーバサイドからフロントエンドまでやって、つらい運用を経験できたので結構ためになった。オーソドックスなwebだったので、聞いたことがない技術はほとんどなかった。知らなかったのはFlash合成くらいかなあ?
自分の知ってるwebじゃないと思いながらスマホ向けにJSいじってたのもこの時期。コピペじゃないJSを書いてるひとなんていなかったんじゃないかなあという印象がある。外を見ればクライアントサイドMV*、altJS、SPAあたりがちょこちょこ出てきてたと思う。SPAはワードとしては定着してなかった。個人的にこのあたりに一番興味をもっていて、実際に大規模なアプリ作りたかったので、勉強して社内SNSで煽ったりしてた。当然、生意気だったわけだけど、僕の話を拾ってくれる先輩方がいたので、ありがたいなと思ってた。生意気だけど、そこそこできる新卒くらいには思われていた気がする。
市場的にはブラウザが大きくてネイティブはパズドラくらいしか出てなかった。業界の雰囲気はネイティブの流れが少しあった。まあこの時期にちゃんとしたネイティブゲームを仕込んでいた会社が現在ストアでトップランカーになってるんだけど…
2年目
優秀な後輩が何人か入ってきた。みんな今では貫禄がでてきてたくましい。
自分の業務についてはあまり記憶がない。確か運用プロジェクトは抜けていた気がする。1年目の煽りが効いたのか、新規ブラウザゲームで大規模なHTML5を使って作ることになったんだけど、僕はタイミングが悪くて入れなかった。プロジェクトには入れなかったけど、個人的に勉強は続けてた。
市場はパズドラがすごい勢いだった。他には黒猫のウィズとかブレフロとかが出始めてはやり始めてた。2年目後半はすでにネイティブばっかりになってきてて、ブラウザはカードバトルとリアルタイムGvGくらいしか出てなかった。
そういった流れもあってか、業務でネイティブを触る機会がきて、Cocos2d-xでモックみたいの作ってた。何かゲームが出たわけでもなく、僕自身も何をアウトプットしたのかわからないけど、いろいろ気づきはあった。以下気づき
- ゲームプログラミングとやらが必要になってきた
- ネイティブつらそう、ブラウザゆるふわ
- C++は僕には早かった
1つ目は、メインループとかシーンとかゲームプログラミングの用語がいっぱい出てきて、圧倒されたことが始まり。プログラミングを始めた頃にゲーム作ったりしてたので聞いたことがないわけではないけど、しばらくブラウザゲーム作ってたので忘れてた。ブラウザゲームはwebアプリと変わらないし、基本イベントドリブンで書けるのでメインループなかった。
2つ目は、実際に運用となるとネイティブはつらそうだなということ。主に更新性とUI関連なんだけど、ネイティブやっても結局はブラウザとHTMLみたいのが欲しくなるなと考えてた。
3つ目は、急にネイティブでモック作る仕事が来たときの話。期間と僕のスキルを考えて無理だなと思ったので、Cocos2d-xのJavaScript Binding(現在はCocos2d-JS)というのを使った。もともとCocos2d-xの組み込みスクリプト(LuaとJS)の設計思想がいいなと思っていたのも選んだ理由。モックを提出した後にネタバレしたけど、バレてなかったので結構使えるなと思ったのも気づきのひとつ。C++が僕には早かったというかほとんどやっていないというのが実際のところ。モックといえど、それなりに仕様が盛り込まれてたので、ソースコードは結構増えてた。この時、このプログラミングじゃスケールしないと思ったことは1つ目の気づきと共通している。
そんな気づきがありながら、2年目の終わりの方で運用中のブラウザタイトルに戻った。このあたりで役割的にはJavaScriptを書くフロントエンドエンジニアになった。
3年目
また後輩が増えた。すごい優秀。
業界的にも会社的にもネイティブの流れが加速してる感じ。それで、2年目のときからだんだん増えてたけど、コンシューマー出身者がすごい増えてきた気がする。同時に嗅覚の鋭いwebエンジニアは他に移っていた印象がある。
ゲームプログラマとwebエンジニアは結構コンテキストが違う。今のスマホゲーム業界はそんな異なるコンテキストが入り乱れてる感じ。サーバサイドは今のとこどっちでもあまり変わらないけど。
僕自身はブラウザタイトルにいるけど、ガッツリ運用に入っているわけではない。いろいろ実験できるような環境にいるので、何かしらアウトプットして貢献しようとしてるのが最近の動き。簡単に言うとブラウザでもちゃんとしたゲームを作れるようにしたいということ。ブラウザというプラットフォームを使ってゲーム作り(設計からプログラミング)を学びたいと言ったほうがしっくりくる。ブラウザゲームも求められるレベルが上がって、遊びの要素が増えてくると思うので、今のうちやっておきたい。まあ市場に投資をしても仕方がないとなったら引き上げだけど、まだちょっとはやれそう。
こんなこと言ってるとブラウザでネイティブに勝ちたい奴、みたいに思われるかもだけど、ちょっと違う。ブラウザでもネイティブでもやることは本質的に一緒だと思っていて、僕自身が付け入る隙がありそうだからブラウザでやってみる感じ。まあ、それブラウザでよくね?というネイティブゲームがいっぱいあるから、そういうのはブラウザで作ろうよと提案していきたいとは思う。
今必要なこと
ゲームの作り方
上で書いたけど、これは主に設計やプログラミングの話。こういうのは、スクールガールストライカーズの 内製クライアントエンジンみたいにあるとこにはあるんだけど、民主化はされてない。僕が必要としているのはエンジンの設計みたいな低レイヤーのとこではなく、もっと高いレイヤーのとこなんだけど、まだ見つからない。Cocos2d-x入門・Unity入門という本があるとしたら、それらには書いてないようなあたり。Game Programming Gemsに全部書いてあるから読めば?、というのではなくてもうちょっとカジュアルに取り入れたい。このあたりはオープンなweb業界とは違うとこだなと感じてる。
ちなみにスクストの資料に書いてあることはコンシューマー出身なら当たり前のことなんだそうな。当たり前のことをちゃんとやってる感じらしい(ゲームプログラマー怖い
web技術との融合
とりあえずはブラウザ向けに作っていくので、単純にゲームプログラミングをやってれば済むというわけではない。最終的にHTML/CSS/JavaScriptにどうやって落とし込んでいくのかを考える必要がある。このあたりは流れが速いので追っていくのがすごくたいへん。最近だとビルドツールが熱い。サーバも同様にちゃんとする必要がある。
残念なこと
- ゲームコーディング・コンプリートが欲しかったんだけど、地元の本屋には売ってなかった
- いきなり長文書いたのでブログが続かないかもしれない
jQueryプラグインの作り方メモ
jQueryプラグインを作るときにいろいろつまずいたのでメモを残す。
一応ひな形みたいなのがあるらしいけど、プラグインによって全然書き方が違うから、どれが正しいのかわからん。
プラグインのひな形
jQuery プラグインの定義パターンについて調べてみた - Cyokodog :: Diary
このまとめはかなり参考になりました。自分が採用したのは2.7の書き方です。javascriptっぽいし、インスタンスでパラメータを保持できるとこがいいですね。実際のソースコードとしては、リンク先の例にあげられているjQuery Calendarがわかり易かった。初期化、オプションの渡し方、メソッド定義など、とても勉強になると思います。
右も左もわからない場合は、以下の記事も読む。
WIZARD-CODE ウィザード・コードのブログ | WIZ-CODE.blog
thisについて
jQueryのプラグインをつくってみよう - 馬鹿と天才は紙一重
javascript使いこなすにはthisの理解が不可欠だと再認識しました。jQueryプラグインを作るときもとても重要。
参考記事はthis以外にも重要なことが書いてあるので、プラグイン作るときは読むといいかも。dataメソッドは結構使えます。
extend
jQuery.extend マニアックス - てっく煮ブログ
extendメソッドよく使うので一読。オプションをセットするときに使う。
イベント関連
iPhone/Android/PC 対応。jQuery で書くタッチイベント (フェンリル | デベロッパーズブログ)
web帳 | スマートフォン JavaScript タッチ、フリックイベント実装
作ってるプラグインがスマホ用なので、タッチ系のイベントを勉強する必要がありました。
AndroidとiPhoneで挙動が変わるのでよくわからんw