2014年2月15日土曜日

毎秒

windows上のVirtualBoxのUbuntuで開発してて、
windows上で動いてるgenymotionにadbでちょっかい出したくなった。

sshd動かそうとしたけどwindows難しすぎた。

仕方ないのでUbuntuからは共有フォルダに実行するスクリプトを書き込んで、
windowsの方で毎秒ファイル監視するスクリプトを書いて、
ファイル変わってたら変更されたスクリプトを実行するようにしてみた。

ださいし平均0.5秒遅れるけど、動かないよりはだいぶまし。

2014年2月6日木曜日

cocos2dx2.xにluasocket

3beta2以降は標準で使えるようになったので不要です。

タイミング悪く2.2.2に無理やり組み込んだのでメモ。
とりあえず動けばいいと思って雑にやった。
ndkとcocosとluaの初心者なのでこんなやり方でいいのかはわからないけど一応動いた。


以下手順

luasocketに入ってる.cと.hをどっかにおく
luasocket/srcあたり
luasocket.cはluaopen_socket_coreをコピーしてluaopen_libluasocketにした。


luasocketに入ってる.luaをどっかにおく
scripts/socketあたり

socket.core.luaだけはscripts/socket.luaにして
local socket = require("socket.core")

local socket = require("libluasocket")
に変える。
cpathからsoファイル探すらしいので。




Android.mkに
include $(CLEAR_VARS)
LOCAL_MODULE := luasocket
LOCAL_SRC_FILES := .c全部

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../luasocket/src
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../../scripting/lua/luajit/LuaJIT-2.0.1/src/

LDFLAGS += -lgcc -lc

LOCAL_SHARED_LIBRARIES := hellolua_shared

include $(BUILD_SHARED_LIBRARY)

って感じでlibluasocket.soを作るようにさせる。


package.cpathに追加
/data/data/org.cocos2dx.hellolua/lib/?.so

package.pathにはscriptsに対応するところを追加


require("socket")すれば使えるはず。

2014年1月7日火曜日

cocos2dxとか

何か作ろうと思ってるけど下準備中、cocos2dxとlua使う予定。
だらだらといろいろ試したことのメモ。


エミュレータと実機つないでるので指定する方法
 adb devices でシリアル確認
 adbコマンドにANDROID_SERIAL=xxxでシリアルを指定する
 adb -s xxxでもいいけど、別のスクリプトとかからadbしてるときに微妙。
 エミュレータ、実機が1台ずつならadb -eとかadb -dでもいい。


cocos2dxのsamples/lua/HelloLuaをいじってみる。


apk内部のassetsにluaファイルを置いておくと
require "ファイル名"で読めるらしい

luaからファイルを作成してみる
    fh = io.open("/data/data/org.cocos2dx.hellolua/files/test.txt", "w")
    fh:write("abcde\n")
    fh:close()

Genymotionで動かすためにx86もビルドするようにする
jni/Application.mk

APP_ABI := x86 armeabi
を追加する。

lua言語慣れてないのでlua+cygwinでとりあえずインタラクティブなやつで試す
make mingw
cd src
lua -i

luaマニュアルを軽く見ておくといい
他の言語知っていれば簡単だと思う
PHPとjavascriptをくっつけてうさんくさい動作を省いたみたいな印象
http://milkpot.sakura.ne.jp/lua/lua51_manual_ja.html

スクリプトの中で作成したスクリプトを読み込んでみる
    fh = io.open("/data/data/org.cocos2dx.hellolua/files/test.lua", "w")
    fh:write("function myadd2(x, y)\n");
    fh:write("    return x + y + 1\n");
    fh:write("end\n");
    fh:close()

    package.path = "/data/data/org.cocos2dx.hellolua/files/?.lua"

    require("test");
    cclog("result2 is " .. myadd2(1, 1))
  スクリプトの中で作成しなくても、 adb pushで/data/data/org.cocos2dx.hellolua/files/におけば、 同じようにrequireできるのでそうすれば それなりに時間かかるAPKビルドを省略できるので結構楽そう。    rootじゃないと権限の問題でfilesにファイルを作成するのがちょっと面倒 adb shell "run-as org.cocos2dx.hellolua sh -c 'echo \"aaa\nbbb\nccc\" > /data/data/org.cocos2dx.hellolua/files/test.txt'" みたいな感じ。 echoに渡す文字列のエスケープがややこしい。 シングルクオートが'\'' ダブルクオートが\\\" adb pushでrun-asみたいのを指定する方法があればいいのだけど。


luaからc++を呼ぶには
tools/tolua++でmakeする
apt-get install tolua++しておく

scripting/lua/cocos2dx_support/LuaCocos2d.cppに作成される


自分で作った関数とかをtoluaするには
http://p-monster.hatenablog.com/entry/2012/12/12/170111
ここを参考にしました。

samples/Lua/HelloLua/tolua_glue/sample.pkgを作成
tolua++5.1 -n sample -o sample_glue.cpp -H sample_glue.h sample.pkg
でsample_glue.cppとsample_glue.hを作成。
同じディレクトリに参考記事のluasample.h, luasample.cppを作成

Android.mkの
LOCAL_SRC_FILESにluasample.cppとsample_glue.cppを追加
LOCAL_C_INCLUDESにtolua_glueとexternal/emscripten/tests/lua/srcを追加

AppDeletete.cppに
#include "lua.hpp"
#include "tolua++.h"
#include "sample_glue.h"
を追加。
applicationDidFinishLaunchingの中で 
lua_State* state = pEngine->getLuaStack()->getLuaState();
tolua_sample_open(state);
すると、以降でGetStringが呼べるようになる。

 

2013年6月17日月曜日

JSONと仲良くする

最近大量だったり巨大だったりなJSONファイルから必要な部分を探す必要に迫られたときにjqが便利だったので紹介。



http://stedolan.github.io/jq/
表示する範囲を絞り込めるので、繰り返し同じ場所を表示したいときとかに便利。
抽出結果がJSONになるので一部分を抽出したJSONを作成したりできる。
クエリがちょっと独特な気がする。

sample.json
{"1":{"name": "data1","point":1001,"optional":1},"2":{"name":"data2","point":1002},"3":{"name":"data3","point":1003,"optional":3}}

使い方例
・整形して表示する
jq '.' sample.json
・nameだけを抜き出す
jq '.[].name' sample.json
・nameとoptionalを抜き出す、どっちかがないやつはnullになる
jq '.[]|{name, optional}' sample.json
・トップレベルの"1"のオブジェクトだけを抽出する
jq '.["1"]' sample.json
・findとxargsと組み合わせたときにファイル名も付ける、特定の要素がnullになってる項目を含むファイルを探すときに便利
find -name '*.json' | xargs -I{} jq -c '.[]|{name,optional,filename: $filename}' --arg filename {} {}
・各要素の要素数を取得
jq '.[]|length' sample.json
・トップレベルの要素数を取得
jq 'keys|length' sample.json



jq以外の方法
JSONPath
プログラムからJson形式の検索や操作を行うためのライブラリというか仕様。
XPathをJSON用に変更したものらしい?
いろいろな言語用にライブラリがある、メジャーな言語にはほとんどありそう。
プログラムの中でJSONの一部を使うときとかは便利そうなんだけど、
ちょっと試して動かなかったのでわからない。

上のsample.jsonの1のnameを検索する場合はこんな感じだと思う。
"$..1.name"



行指向に変換してみる

jqは便利だけど独自クエリが思い出せなかったり、
コマンドラインツールとの相性がいまいち。


ということで、さっきのsample.jsonをこんな風に変換するスクリプトを作ってみた。
/1/name                                  => "data1"
/1/point                                 => 1001
/1/optional                              => 1
/2/name                                  => "data2"
/2/point                                 => 1002
/3/name                                  => "data3"
/3/point                                 => 1003
/3/optional                              => 3

こうなったら、grepとかで好きなように検索できる。


#!/usr/bin/php
<?php
function jr($data, $path) {
    if (is_array($data)) {
        foreach ($data as $key => $value) {
            jr($value, $path . '[' . $key . ']');
        }
    } elseif (is_object($data)) {
        foreach($data as $key => $value) {
            jr($value, $path . '/' . $key);
        }
    } else {
        $output = is_string($data) ? '"' . $data . '"' : $data;
        printf("%-40s => %s\n", $path, $output);
    }
}

$input = (count($argv) > 1) ? $argv[1] : 'php://stdin';
$all_data = json_decode(file_get_contents($input), false);
jr($all_data, '');



作ってはみたけど、jqとjr(上のスクリプトの仮称)で必要なコマンドを比較してみたら
jqの使いやすさを再確認するだけになった。
正規表現だとややこしくなる箇所もあるし。
でも、独自クエリがなかなか覚えられない人にはjr+grepも便利。

比較
トップレベルのキー一覧を取得する
$jq 'keys' ~/work/sample.json
$jr.php ~/work/sample.json | sed -e 's|^/\([^/]*\)/.*|\1|' | uniq

第二階層のnameの一覧を取得する
$jq '.[].name' ~/work/sample.json
$jr.php ~/work/sample.json | grep '/\w*/name\s' | sed -e 's/.*=> //'

どっかにあるnameがdata2のデータを探す
$jq '.[].name == "data2"' ~/work/sample.json
false
true
false

$jr.php ~/work/sample.json | grep "data2"
/2/name                                  => "data2"




その他
最近の言語はだいたいJSONにオブジェクトとか配列を保存できる機能があるので、
JSONをうまく扱えるとそういうのを読むのにも便利。

S式とかXMLとかyamlとかテキストの構造化データ形式が色々あるので、
自分が読み書きしやすいやつと相互変換させたりするのもいいかも。


clojureなら

(clojure.data.json/json-str
  {1 {:name "data1", :point 1001, "optional" 1}
   2 {:name "data2", :point 1002}
   3 {:name "data3", :point 1003, "optional" 3}})
で上のsample.jsonと同じのができる。
emacsだとS式編集用に便利な機能がいろいろあったり、pareditで括弧間違えなくて便利。


あとはJaqlとかJSONiqとかJSONをSQL風なクエリで検索したりするのもある。

2013年6月2日日曜日

nreplxmp作った

lispxmpをclojureで使うために移植してみた。



elispもclojureも初心者なので、
エラー処理とかnsの扱いとか実装も結構酷いけど一応動いた。
簡単なことでしか試してないので、ダメなとこ見つけたら直す予定。



https://github.com/wakala/nreplxmpから
nreplxmp.elをどっかにコピーして
(require 'nreplxmp)
  

cljファイルを1ファイルをまるごとevalして実行できるようにして、
nrepl-jack-inしたあとにM-x nreplxmpとかで動く。


lispxmpについてはここを参照
http://d.hatena.ne.jp/rubikitch/20090313/lispxmp

nreplについてはここを参照
https://github.com/kingtim/nrepl.el

2013年5月26日日曜日

LittleProxyでフィルターする。

http://wakalambda.blogspot.jp/2013/05/clojurejettyproxyservlet.html

をやったあとに、ホスト名とコンテントタイプが指定したものだったときだけ
コンテンツを表示するようにしようとしたらどこを拡張していいかわからなかった。

あきらめてLittleProxyでやってみたら簡単にできた。
(defproject littleproxy-filter-example "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.5.1"]
                 [org.littleshoot/littleproxy "0.5.1"]]
  )
(ns littleproxy-filter-example.core)

(import '(org.littleshoot.proxy DefaultHttpProxyServer
                                HttpResponseFilters
                                HttpRequestFilter
                                HttpFilter))

(use 'clojure.java.io)

(def ^:dynamic *log-file* "/tmp/proxy-log.txt")

(defn write-log [request response]
  (let [host (.getHeader request "Host")
        uri (.getUri request)
        content-type (.getHeader response "Content-Type")]
    (if (.startsWith (str content-type) "text/html")
      (try
        (spit *log-file*
              (str
               "new response  -----------------------------------------------------------\n"
               uri "\n"
               content-type "\n"
               (.toString (.getContent response) "UTF-8") "\n"
               )
              :append true)
        (catch Exception e
          (spit *log-file* (str e) :append true))
        ))))

(defn get-filter [host-and-port]
  (proxy [HttpFilter] []
    (filterResponses [request]
      true
      ;(.endsWith (.getHeader request "Host") "clojure.org")
      )
    (filterResponse [request response]
      (write-log request response)
      response)
    (getMaxResponseSize []
      Integer/MAX_VALUE)))

(defn create-response-filters []
  (proxy [HttpResponseFilters] []
    (getFilter [host-and-port]
      (get-filter host-and-port))))

(defn create-request-filter []
  (proxy [HttpRequestFilter] []
    (filter [http-request]
      ;; some ops
      )))

(def ^:dynamic *server* (DefaultHttpProxyServer. 8888 (create-request-filter) (create-response-filters)))
(.start *server*)
;; (.stop *server*)

2013年5月20日月曜日

swank-jsを動かしてみた

https://github.com/swank-js/swank-jsのREADMEを参考に。

nodejsはyum install nodejs

npmはgit clone https://github.com/isaacs/npm.git
でmake install

npm install -g swank-js
swank-jsで起動

js2-modeが上手く動かなかったので、横道にそれてemacs24にした。
color-themeみたいのとpackageが標準で入ってて便利になってた。

packageからslime, slime-js, js2-modeをいれた。

ウェブブラウザで
http://IP:8009/swank-js/test.htmlを開く


javascriptファイルを開いてjs2-modeとslime-js-minor-modeを実行。
slime-connect
, select-remoteでブラウザ選択

C-M-xで関数を送る。
slime-eval-regionでリージョンを送る。


$('head').append('<link rel="stylesheet" href="http://IP/a.css" type="text/css" />');
とかするとheadタグの中にcssを追加させられる。
 
cssファイルを変更してから、slime-js-refresh-cssで変更が反映される。

時間がないので、設定のメモだけ、使いこなせたらよさそうなのだけど。
swank-jsのREADMEに書いてあるキーバインドが使えないことがあったりして、
うまく設定できてない気もする。

http://emacsrocks.com/e11.html
みたいなことできたらかっこいい。