websocket を Lua から利用する時の注意
cocos2d-x-3.13 LuaでWebsocketを利用する際に、以前にはでてなかったと思うエラーが出た。
いつのバージョンからかは不明だが、3.6くらいの時は出てなかったと思う(曖昧な記憶)
local ws = cc.WebSocket:create("ws://example.com") ws:registerScriptHandler(function(msg) -- なんらかの処理... end, cc.WEBSOCKET_MESSAGE)
上記を実行すると、registerScriptHandler の第4の引数が無いとエラーが出る。
以下のbindingファイルがその該当箇所のようなので398行目 のエラーチェックに引っかかってたようだ。
# Lua_web_socket.cpp line 390 int tolua_Cocos2d_WebSocket_registerScriptHandler00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"cc.WebSocket",0,&tolua_err) || !toluafix_isfunction(tolua_S,2,"LUA_FUNCTION",0,&tolua_err) || !tolua_isnumber(tolua_S,3,0,&tolua_err) || !tolua_isnoobj(tolua_S,4,&tolua_err) // ここにひっかかってる ) goto tolua_lerror; else #endif { LuaWebSocket* self = (LuaWebSocket*) tolua_tousertype(tolua_S,1,0); if (NULL != self ) { int handler = ( toluafix_ref_function(tolua_S,2,0)); ScriptHandlerMgr::HandlerType handlerType = (ScriptHandlerMgr::HandlerType)((int)tolua_tonumber(tolua_S,3,0) + (int)ScriptHandlerMgr::HandlerType::WEBSOCKET_OPEN); ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, handlerType); } } return 0; #ifndef TOLUA_RELEASE tolua_lerror: tolua_error(tolua_S,"#ferror in function 'registerScriptHandler'.",&tolua_err); return 0; #endif }
ただ、tolua_toobject(tolua_S,4,0) と、この第4の引数を利用している箇所が関数内には存在しないので
このチェックは無視しても問題なさそう。
以下の部分をfalseに変更
- !tolua_isnoobj(tolua_S,4,&tolua_err) + false
エラーは出なくなりました。
AsyncTaskPoolが便利
バックで非同期実行する際などに利用。
AssetsManager とか Download 関係のソースに実装されてるので見様見真似で使ってみる。
Luaからも利用できるように luabinding もさせておくとなおよし。
# 自前のSQLを実行する関数に適用 void Wx::execSqlAsync(const std::string& sql, ResCallback callback) { struct AsyncData { bool res; std::string sql; }; AsyncData* asyncData = new AsyncData; asyncData->sql = sql; std::function<void(void*)> mainThread = [this, callback, sql](void* param) { auto asyncDataInner = reinterpret_cast<AsyncData*>(param); callback(asyncDataInner->res, sql); delete asyncDataInner; }; AsyncTaskPool::getInstance()->enqueue(AsyncTaskPool::TaskType::TASK_OTHER, mainThread, (void*)asyncData, [this, asyncData] { asyncData->res = execSql(asyncData->sql); }); }
static int lua_cocos2dx_Wx_execSqlAsync(lua_State* L) { if (nullptr == L) return 0; int argc = 0; Wx* self = nullptr; bool ok = true; #if COCOS2D_DEBUG >= 1 tolua_Error tolua_err; if (!tolua_isusertype(L, 1, "Wx", 0, &tolua_err)) goto tolua_lerror; #endif self = static_cast<Wx*>(tolua_tousertype(L, 1, 0)); #if COCOS2D_DEBUG >= 1 if (nullptr == self) { tolua_error(L, "invalid 'self' in function 'lua_cocos2dx_Wx_execSqlAsync'\n", NULL); return 0; } #endif argc = lua_gettop(L) - 1; if (2 == argc) { std::string arg0; ok &= luaval_to_std_string(L, 2, &arg0, "Wx:execSqlAsync"); if (!ok) { tolua_error(L, "invalid arguments in function 'lua_cocos2dx_custom_Wx_execSqlAsync'", nullptr); return 0; } #if COCOS2D_DEBUG >= 1 if (!toluafix_isfunction(L, 3, "LUA_FUNCTION", 0, &tolua_err)) { goto tolua_lerror; } #endif LUA_FUNCTION handler = (toluafix_ref_function(L, 3, 0)); std::function<void(bool b, const std::string sql)> callback = [L, handler](bool b, const std::string sql) { LuaStack* stack = LuaEngine::getInstance()->getLuaStack(); stack->pushBoolean(b); stack->pushString(sql.c_str()); stack->executeFunctionByHandler(handler, 2); }; self->execSqlAsync(arg0, callback); return 0; } luaL_error(L, "'execSqlAsync' function of Wx has wrong number of arguments: %d, was expecting %d\n", argc, 2); return 0; #if COCOS2D_DEBUG >= 1 tolua_lerror: tolua_error(L, "#ferror in function 'execSqlAsync'.", &tolua_err); return 0; #endif }
cocos2d-x アプリのバージョン取得
以前は、自前でネイティブコード実装してましたが、cocos2d-x 3.10 からは、標準装備になったみたい。
cc.Application:getInstance():getVersion()
備忘録
Google Playで課金テストをするときに、テストアカウントが認識されない
新しくテストアカウント(Googleアカウント)を作って課金テストをした時の失敗。
1.Google Play console で、APKファイルをアルファー版で公開。 2.クローズドアルファ版テストとして、テスターをリストに追加 3.オプトインURLを該当者に送付 4.メールに届いたURLをクリックしてインストール 5.起動
ここまでは、よかった。
この後、やりたかった課金テストに進むわけだが、どういうわけか課金処理に入ると
テストなのに、クレジット情報が表示されて正規の課金フローのように。。。
テスト課金なら「これはテスト用の注文です。。。」と表示されてくれるはず。。。
仕様が変わったのかなぁ。。と半信半疑でポチってしまったのが運の尽き。
普通に課金されてしまった。。。。
どうも、テスターの設定だけでなく、
DeveloperConsoleの設定 -> 「テスト用のアクセス権がある Gmail アカウント」
この設定が抜けていたのが問題だったらしい。
テスター登録だけでOKだと勘違いしていた。
以前作ったアプリではちゃんと登録していたみたいで、完全に忘却していました。
今回のように新しくテストアカウント作った時には注意が必要。
Xcodeでテストビルド用にパッケージを分ける方法
単純にSchemaとTargetに追加すると新しい設定が追加できるのでパッケージ名を変えた設定でビルドすると幸せになれる。
TARGETS [+]ボタンでターゲットの追加 Product -> Scheme -> ManageSchemes で、適当に編集
※Info.plist も別になるはずなので、設定に追加されているか確認すること