facebookでリクエストがあったので晒しておきます。
tableの値をdump出力したり、それを実機でコピペ可能状態なテキストフィールドにトレースしたりするクラスです。
ソースが長いので[ココ]
(https://dl.dropbox.com/u/67505768/qiita/corona/log.zip)にzipで固めておきます。
module(..., package.seeall)
local DEBUG = 1;
local INFO = 2;
local WARN = 4;
local ERROR = 8;
local RELEASE = 16;
--しきい値設定
local logLevel = DEBUG;
--デバッグディスプレイのボタンサイズ
local buttonsize = 30;
--Debug Display------------------------------------------------------------------------
--実機検証用
local displayObject = display.newGroup();
local disp;
local dispButton;
local delButton;
local displayEnable = false;
local function visibleDisplay( event )
disp.isVisible = not( disp.isVisible );
end;
local function deleteDisplay( event )
disp.text = "";
end;
-- 実機検証用のディスプレイを表示
-- colorObj { r ,g ,b ,a } ディスプレイの文字色設定(各0〜255)、設定があれば背景は透明/nil時は背景白、文字黒
function showDisplay( colorObj )
print( "showDisplay!!!!!" );
displayEnable = true;
dispButton = display.newRect(display.screenOriginX,display.screenOriginY,buttonsize,buttonsize);
dispButton.strokeWidth = 3;
dispButton:setFillColor(255, 0, 0);
dispButton:addEventListener( "tap" , visibleDisplay );
delButton = display.newRect(display.screenOriginX,display.screenOriginY+buttonsize+10,buttonsize,buttonsize);
delButton.strokeWidth = 3;
delButton:setFillColor(0, 0, 255);
delButton:addEventListener( "tap" , deleteDisplay );
disp = native.newTextBox( buttonsize, 0, display.contentWidth-buttonsize, display.contentHeight );
disp.font = native.newFont( native.systemFont , 12 );
disp.isVisible = false;
if colorObj and #colorObj==4 then
disp:setTextColor( colorObj[1], colorObj[2], colorObj[3], colorObj[4] );
disp.hasBackground = false;
end;
displayObject:insert( dispButton );
displayObject:insert( delButton );
displayObject:insert( disp );
end;
-- データのダンプ、ダンプした文字列を返す------------------------------------------------------------------------
-- (UserDataと循環参照を持つオブジェクトは入れてはいけません)
-- data ダンプするデータ
-- return ダンプした文字列
local function dump_data( data )
if type( data ) ~= "table" then
return tostring(data);
end;
dump_table = function( t, indent )
local str = "{\n";
for k, v in pairs( t ) do
if type( v ) == "table" then
str = string.format("%s%s%s%s = %s,\n", str, indent, "\t", tostring( k ),dump_table( v, indent .. "\t" ) );
elseif type( v ) == "string" then
str = string.format("%s%s%s%s = %q,\n", str, indent, "\t", tostring( k ), v );
else
str = string.format("%s%s%s%s = %s,\n", str, indent, "\t", tostring( k ), tostring( v ) );
end;
end;
str = str .. indent .. "}";
return str;
end;
return dump_table( data, "" );
end
-- NEW------------------------------------------------------------------------
-- _path 接頭でprintされる文字列、クラスパスを入れておくと便利
function new( _path )
local this = {};
if logLevel == RELEASE then
this = {
debug = function( value ) end;
info = function( value ) end;
warn = function( value ) end;
error = function( value ) end;
showDisplay = function( value ) end;
log_display = display.newGroup();
};
else
this = {
path = _path;
debug = function( value )
if logLevel <= DEBUG then
local debug_text = ( "[debug][".. _path .."] " .. dump_data( value ) );
if displayEnable then disp.text = disp.text .. "\n" .. debug_text; end;
print( debug_text );
end
end;
info = function( value )
if logLevel <= INFO then
local debug_text = ( "\t[info][".. _path .."] " .. dump_data( value ) );
if displayEnable then disp.text = disp.text .. "\n" .. debug_text; end;
print( debug_text );
end
end;
warn = function( value )
if logLevel <= WARN then
local debug_text = ( "\t\t[warn][".. _path .."] " .. dump_data( value ) );
if displayEnable then disp.text = disp.text .. "\n" .. debug_text; end;
print( debug_text );
end
end;
error = function( value )
if logLevel <= ERROR then
local debug_text = ( "\t\t\t[error][".. _path .."] " .. dump_data( value ) );
if displayEnable then disp.text = disp.text .. "\n" .. debug_text; end;
print( debug_text );
end
end;
showDisplay = function( colorObj ) showDisplay( colorObj ); end;
log_display = displayObject;
};
end;
return this;
end;
-- 初回トレース ------------------------------------------------------------------------
local startLog = new( "log" );
startLog.error ("\n\n\n\n\n\n\n\n------------------------------ DEBUG START at " .. os.date( "%c" ) .." ------------------------------\n\n");
startLog.debug ( "this is debug." );
startLog.info ( "this is info." );
startLog.warn ( "this is warn." );
startLog.error ( "this is error.\n\n" );
使用サンプル
で、以下が使用サンプルです。
local log = ( require "log" ).new( "main" );
--実機検証用にディスプレイを表示する場合に一回だけ実行
log.showDisplay();
--displayList最前面とかにする場合は以下な感じで
--container:insert( log.log_display );
--トレースサンプル
local dump_reference = { hoge="hoge" };
local obj = {
dump_string = "STRING";
dump_number = 65536;
dump_boolean = true;
dump_array = { 50 , 80+2.56 , "THREE" , false , dump_reference };
dump_function = function() end;
dump_nan = 0/0;
--dump_ng = display.newGroup(); --これは駄目よ
};
log.debug( obj.dump_string );
log.info ( obj.dump_number );
log.warn ( obj.dump_boolean );
log.error( obj.dump_array );
log.debug( obj );
出力結果はこんな感じ。
[debug][main] STRING
[info][main] 65536
[warn][main] true
[error][main] {
1 = 50,
2 = 82.56,
3 = "THREE",
4 = false,
5 = {
hoge = "hoge",
},
}
[debug][main] {
dump_string = "STRING",
dump_array = {
1 = 50,
2 = 82.56,
3 = "THREE",
4 = false,
5 = {
hoge = "hoge",
},
},
dump_nan = nan,
dump_number = 65536,
dump_function = function: 0x115f4d7a0,
dump_boolean = true,
}
つかいかた
- 読み込み
こんな感じでrequireしインスタンスを生成します。newの引数はログに接頭で付くので、クラス名をパッケージフルパスで入れておくと便利です。
local log = ( require "log" ).new( "main" );
- ログの出力
ログの出力はレベルに応じて4種設定され、それぞれ1つずつタブインデントが付いて出力されます。
循環参照やuserdataはオーバーフローするので入れないようにしてください。
log.debug( value ); --なんとなく見たい値とか
log.info( value ); --フロー追いかけ用とか
log.warn( value ); --ちょっとおっかない箇所の出力
log.error( value ); --エラー時用の出力
- ログレベルの振り分け
ログの出力レベルは、log.luaのlogLevelで変更出来ます。DEBUG/INFO/WARN/ERROR/RELEASEの5段階あり、しきい値以下のレベルは出力されなくなります。
RELEASEに設定すると、一切出力されません。(リリースビルド向け)
--しきい値設定
local logLevel = DEBUG;
- ログディスプレイ表示
実機でしか確認出来ない事項用(GameCenterとかStore関連等)向けに、テキストフィールドにログを出力します。
log.showDisplay()を実行すると、画面の左上に赤と青のボタンが並びます。
・赤ボタン - テキストフィールドの表示ON/OFF
・青ボタン - テキストフィールドの内容を消去(ログが溜まってくると重くなるので、そんな時に)
log.showDisplay(); --引数設定でカラー変化。詳しくはコード見て
--displayList最前面とかにする場合は以下な感じで
--group:insert( log.log_display );
Corona始めて一番最初に書いたコードなので、ちょっと汚いかもしれませんです。