Inspecting the Simulator...

Hello!

A “work-in-progress” often leaves its documentation behind - Corona is certainly no exception from this rule…

Fortunately, however, Lua offers really useful introspection capabilities, which may also be used to inspect the Corona run-time environment.

The author has tried to inspect the “Corona-Terminal”, here are the results.

The code used was the following (unfortunately, the forum does no longer display any indentations - is there a special trick?) :

[code]
io.stdout:setvbuf(“no”);
io.stderr:setvbuf(“no”);


– inform[ln] writes the given arguments onto stdout –

function inform (…)
for i = 1,select(’#’,…) do – even “nil” is handled properly
io.stdout:write(tostring(select(i,…)));
end;
end;

function informln (…)
for i = 1,select(’#’,…) do – even “nil” is handled properly
io.stdout:write(tostring(select(i,…)));
end;
io.stdout:write("\n");
end;


– say[ln] just synonyms for inform[ln] –

say = inform;
sayln = informln;
local Label = display.newText("(see Terminal)", 60,50, nil, 28);
Label:setTextColor(255,255,255);


– Table Tracking (never inspect any table twice) –

local inspectedTables = {};
local pendingTables = {};


– inspectTable inspects a given table –

function inspectTable (TablePrefix, Table)
inspectedTables[Table] = TablePrefix; – mark this table as inspected

---- construct a sorted list with the keys of this table ----

local KeyTable = {}; local hasNonPrintableKeys = false;
for Key,Value in pairs(Table) do
if (type(Key) == “string”) then
KeyTable[#KeyTable+1] = Key;
elseif (type(Key) == “number”) then
KeyTable[#KeyTable+1] = tostring(Key); – not really fool-proof, I know
else
hasNonPrintableKeys = true; – just remember any non-printable keys
end;
end;
table.sort(KeyTable);

---- determine the length of the longest key ----

local maxKeyLength = 0;
for i = 1,#KeyTable do
if (#KeyTable[i] > maxKeyLength) then
maxKeyLength = #KeyTable[i]
end;
end;

---- finally print the list of global keys ----

sayln();
sayln(string.rep("-",80));
sayln(" Contents of “,TablePrefix);
sayln(string.rep(”-",80));
sayln();

if (#KeyTable == 0) then
if (hasNonPrintableKeys) then
sayln(" (this table seems to contain non-printable keys only)");
else
sayln(" (this table is empty)");
end;
end;

for i = 1,#KeyTable do
local currentKey = KeyTable[i]; – just a shortcut
say(" “, string.rep(” ",maxKeyLength-#currentKey), currentKey, ": ");

local currentType = type(Table[currentKey]);
if (currentType == “nil”) then
sayln(“nil”);
elseif (currentType == “boolean”) then
sayln(Table[currentKey]);
elseif (currentType == “number”) then
sayln(Table[currentKey]);
elseif (currentType == “string”) then
sayln("’",Table[currentKey],"’");
elseif (currentType == “table”) then
if (inspectedTables[Table[currentKey]] == nil) then
sayln("(table, will be inspected later)");
pendingTables[#pendingTables+1] = {
Prefix = TablePrefix…"[’"…currentKey…"’]",
Value = Table[currentKey]
};
else
sayln("(table, same as “…inspectedTables[Table[currentKey]]…”)");
end;
else
sayln("(",currentType,")");
end;
end;

if (hasNonPrintableKeys) then
sayln();
sayln(“this table also seems to contain non-printable keys!”)
end;
end;


– Inspection of the Corona Runtime Environment –

sayln("Lua Version: ", _VERSION);

inspectTable("_G",_G);
while (#pendingTables > 0) do
local nextTable = table.remove(pendingTables,1);
inspectTable(nextTable.Prefix,nextTable.Value);
end;
[/code] [import]uid: 4331 topic_id: 359 reply_id: 300359[/import]

Inspection of the global table “_G” yields:

Lua Version: Lua 5.1  
  
--------------------------------------------------------------------------------  
 Contents of \_G  
--------------------------------------------------------------------------------  
  
 BounceBehavior: (table, will be inspected later)  
 ButtonBehavior: (table, will be inspected later)  
 Generator: (table, will be inspected later)  
 Rotate3DBehavior: (table, will be inspected later)  
 Runtime: (table, will be inspected later)  
 \_G: (table, same as \_G)  
 \_VERSION: 'Lua 5.1'  
 assert: (function)  
 collectgarbage: (function)  
 complain: (function)  
 complainln: (function)  
 coroutine: (table, will be inspected later)  
 cry: (function)  
 cryln: (function)  
 debug: (table, will be inspected later)  
 display: (table, will be inspected later)  
 dofile: (function)  
 easing: (table, will be inspected later)  
 error: (function)  
 gcinfo: (function)  
 getfenv: (function)  
 getmetatable: (function)  
 inform: (function)  
 informln: (function)  
 inspectTable: (function)  
 io: (table, will be inspected later)  
 ipairs: (function)  
 load: (function)  
 loadfile: (function)  
 loadstring: (function)  
 math: (table, will be inspected later)  
 media: (table, will be inspected later)  
 module: (function)  
 native: (table, will be inspected later)  
 newproxy: (function)  
 next: (function)  
 os: (table, will be inspected later)  
 package: (table, will be inspected later)  
 pairs: (function)  
 pcall: (function)  
 print: (function)  
 rawequal: (function)  
 rawget: (function)  
 rawset: (function)  
 require: (function)  
 say: (function)  
 sayln: (function)  
 select: (function)  
 setfenv: (function)  
 setmetatable: (function)  
 string: (table, will be inspected later)  
 system: (table, will be inspected later)  
 table: (table, will be inspected later)  
 timer: (table, will be inspected later)  
 tonumber: (function)  
 tostring: (function)  
 transition: (table, will be inspected later)  
 type: (function)  
 unpack: (function)  
 xpcall: (function)  

Again, any indentations were lost - that’s bad…

Well, at a first glance:

  • the common lua functions and tables seem to be present (mind the load… and dofile functions, which do not work on the actual device!)
  • any Corona-specific functions seem to be found in their own tables (which is definitely a good idea) we will inspect them later
  • there is an additional function “newproxy” (was that mentioned in the docs?)
    [import]uid: 4331 topic_id: 359 reply_id: 593[/import]

The “Runtime” table contains functions for event listener management:

[code]

Contents of _G[‘Runtime’]

_proxy: (table, will be inspected later)
_stage: (table, will be inspected later)
_super: (table, will be inspected later)
addEventListener: (function)
removeEventListener: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 595[/import]

Many of the “display” functions have already been described in the docs - but what about the “newLine” function? When looking through the API Reference, the author expected line/polyline/polygon support - but could not find it. By inspecting the “display” table, however, it looks as if there would be some line/polyline functionality, at least.

[code]

Contents of _G[‘display’]

BottomCenterReferencePoint: (userdata)
BottomLeftReferencePoint: (userdata)
BottomRightReferencePoint: (userdata)
CenterLeftReferencePoint: (userdata)
CenterReferencePoint: (userdata)
CenterRightReferencePoint: (userdata)
DarkStatusBar: (userdata)
DefaultStatusBar: (userdata)
HiddenStatusBar: (userdata)
TopCenterReferencePoint: (userdata)
TopLeftReferencePoint: (userdata)
TopRightReferencePoint: (userdata)
TranslucentStatusBar: (userdata)
_getCurrentStage: (function)
_newCircle: (function)
_newContainer: (function)
_newGroup: (function)
_newImage: (function)
_newLine: (function)
_newRect: (function)
_newRoundedRect: (function)
_newText: (function)
captureScreen: (function)
getCurrentStage: (function)
newCircle: (function)
newContainer: (function)
newGroup: (function)
newImage: (function)
newLine: (function)
newRect: (function)
newRoundedRect: (function)
newText: (function)
save: (function)
setStatusBar: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 597[/import]

The “easing” table was only partially mentioned in the docs (but not really “described”):

[code]

Contents of _G[‘easing’]

inBounce: (function)
inExpo: (function)
inOutBounce: (function)
inOutExpo: (function)
inOutQuad: (function)
inQuad: (function)
linear: (function)
outBounce: (function)
outExpo: (function)
outQuad: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 598[/import]

“io” and “math” look complete:

[code]

Contents of _G[‘io’]

close: (function)
flush: (function)
input: (function)
lines: (function)
open: (function)
output: (function)
popen: (function)
read: (function)
stderr: (userdata)
stdin: (userdata)
stdout: (userdata)
tmpfile: (function)
type: (function)
write: (function)


Contents of _G[‘math’]

abs: (function)
acos: (function)
asin: (function)
atan: (function)
atan2: (function)
ceil: (function)
cos: (function)
cosh: (function)
deg: (function)
exp: (function)
floor: (function)
fmod: (function)
frexp: (function)
huge: inf
ldexp: (function)
log: (function)
log10: (function)
max: (function)
min: (function)
mod: (function)
modf: (function)
pi: 3.1415926535898
pow: (function)
rad: (function)
random: (function)
randomseed: (function)
sin: (function)
sinh: (function)
sqrt: (function)
tan: (function)
tanh: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 599[/import]

The “media” table has been extensively described in the docs:

[code]

Contents of _G[‘media’]

Camera: (userdata)
PhotoLibrary: (userdata)
SavedPhotosAlbum: (userdata)
newEventSound: (function)
pauseSound: (function)
playEventSound: (function)
playSound: (function)
playVideo: (function)
show: (function)
stopSound: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 600[/import]

The “os” table looks complete, the same applies to the “package” table:

[code]

Contents of _G[‘os’]

clock: (function)
date: (function)
difftime: (function)
execute: (function)
exit: (function)
getenv: (function)
remove: (function)
rename: (function)
setlocale: (function)
time: (function)
tmpname: (function)


Contents of _G[‘package’]

config: ‘/
;
?
!
-’
cpath: ‘/Applications/Corona/Corona Simulator.app/Contents/Resources/?.blu’
loaded: (table, will be inspected later)
loaders: (table, will be inspected later)
loadlib: (function)
path: ‘/Users/rozek/Corona/?.lua;/Applications/Corona/Corona Simulator.app/Contents/Resources/?.lua’
preload: (table, will be inspected later)
seeall: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 602[/import]

“string” support looks complete as well:

[code]

Contents of _G[‘string’]

byte: (function)
char: (function)
dump: (function)
find: (function)
format: (function)
gfind: (function)
gmatch: (function)
gsub: (function)
len: (function)
lower: (function)
match: (function)
rep: (function)
reverse: (function)
sub: (function)
upper: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 603[/import]

The “system” table contains two public looking functions “beginListener” and “endListener” - they should either be documented or have names starting with an underscore “_” in order to mark them “private” (at least - of course, Lua offers far better approaches to “hide” private table entries):

[code]

Contents of _G[‘system’]

DocumentsDirectory: (userdata)
ResourceDirectory: (userdata)
SystemResourceDirectory: (userdata)
TemporaryDirectory: (userdata)
__proxyindex: (function)
__proxynewindex: (function)
__proxyregister: (function)
beginListener: (function)
endListener: (function)
getInfo: (function)
getTimer: (function)
openURL: (function)
pathForFile: (function)
setAccelerometerInterval: (function)
setIdleTimer: (function)
vibrate: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 604[/import]

The “table” table seems to contain a few additional methods (“foreach”, “foreachi” and “getn”, “setn”):

[code]

Contents of _G[‘table’]

concat: (function)
foreach: (function)
foreachi: (function)
getn: (function)
insert: (function)
maxn: (function)
remove: (function)
setn: (function)
sort: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 605[/import]

The “timer” table seems to additionally offer a function “cancel” which sounds very promising!

[code]

Contents of _G[‘timer’]

_insert: (function)
_runlist: (table, will be inspected later)
cancel: (function)
enterFrame: (function)
performWithDelay: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 606[/import]

The “transition” table also seems to offer more functions than described:

[code]

Contents of _G[‘transition’]

_activeTweens: (table, will be inspected later)
_add: (function)
_createSlideParameters: (function)
_dissolvePrepareDst: (function)
_dissolvePrepareSrc: (function)
_initTween: (function)
_nonPropertyKeys: (table, will be inspected later)
_setInvisible: (function)
cancel: (function)
dissolve: (function)
enterFrame: (function)
from: (function)
slide: (function)
to: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 607[/import]

The following tables are only mentioned to be complete:

[code]

Contents of _G[‘BounceBehavior’][’_target’]

(this table is empty)


Contents of _G[‘BounceBehavior’][‘container’]

_class: (table, will be inspected later)
_proxy: (userdata)


Contents of _G[‘Rotate3DBehavior’][’_target’]

(this table is empty)


Contents of _G[‘Runtime’][’_proxy’]

__index: (function)
__newindex: (function)


Contents of _G[‘Runtime’][’_stage’]

_class: (table, will be inspected later)
_proxy: (userdata)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 608[/import]

The following table looks like the metatable of “Runtime”:

[code]

Contents of _G[‘Runtime’][’_super’]

__index: (table, same as _G[‘Runtime’][’_super’])
_indexForType: (table, will be inspected later)
_super: (table, will be inspected later)
addEventListener: (function)
dispatchEvent: (function)
getOrCreateTable: (function)
removeEventListener: (function)
respondsToEvent: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 609[/import]

Here comes the list of loaded and “preloaded” packages:

[code]

Contents of _G[‘package’][‘loaded’]

_G: (table, same as _G)
coroutine: (table, same as _G[‘coroutine’])
debug: (table, same as _G[‘debug’])
display: (table, same as _G[‘display’])
io: (table, same as _G[‘io’])
math: (table, same as _G[‘math’])
media: (table, same as _G[‘media’])
native: (table, same as _G[‘native’])
os: (table, same as _G[‘os’])
package: (table, same as _G[‘package’])
string: (table, same as _G[‘string’])
system: (table, same as _G[‘system’])
table: (table, same as _G[‘table’])


Contents of _G[‘package’][‘loaders’]

1: nil
2: nil
3: nil
4: nil


Contents of _G[‘package’][‘preload’]

ltn12: (function)
mime: (function)
mime.core: (function)
socket: (function)
socket.core: (function)
socket.ftp: (function)
socket.http: (function)
socket.smtp: (function)
socket.tp: (function)
socket.url: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 610[/import]

The interpretation of the following tables is left to the user:

[code]

Contents of _G[‘timer’][’_runlist’]

(this table is empty)


Contents of _G[‘transition’][’_activeTweens’]

(this table is empty)


Contents of _G[‘transition’][’_nonPropertyKeys’]

delay: true
delta: true
onComplete: true
onStart: true
time: true
transition: true


Contents of _G[‘BounceBehavior’][‘container’][’_class’]

__index: (table, same as _G[‘BounceBehavior’][‘container’][’_class’])
addBehavior: (function)
hasBehavior: (function)
initProxy: (function)
removeBehavior: (function)


Contents of _G[‘Runtime’][’_stage’][’_class’]

__index: (table, same as _G[‘Runtime’][’_stage’][’_class’])
addBehavior: (function)
hasBehavior: (function)
initProxy: (function)
removeBehavior: (function)


Contents of _G[‘Runtime’][’_super’][’_indexForType’]

function: ‘_functionListeners’
table: ‘_tableListeners’


Contents of _G[‘Runtime’][’_super’][’_super’]

__index: (table, same as _G[‘Runtime’][’_super’][’_super’])
new: (function)
newClass: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 611[/import]

The next tables sound interesting, but there is not yet any description in the docs:

[code]

Contents of _G[‘BounceBehavior’]

_name: ‘Bounce’
_numTargets: 0
_target: (table, will be inspected later)
container: (table, will be inspected later)
enterFrame: (function)
orientation: (function)
register: (function)
setAutoRotate: (function)
setOrientation: (function)
vx: 0
vy: 0


Contents of _G[‘ButtonBehavior’]

_eventName: ‘touch’
_name: ‘Button’
register: (function)


Contents of _G[‘Generator’]

random: (function)


Contents of _G[‘Rotate3DBehavior’]

_name: ‘Rotate3D’
_numTargets: 0
_target: (table, will be inspected later)
_vRotation: 0
enterFrame: (function)
register: (function)
reset: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 594[/import]

The “coroutine” and “debug” tables seem to be complete (they *look* so, at least):

[code]

Contents of _G[‘coroutine’]

create: (function)
resume: (function)
running: (function)
status: (function)
wrap: (function)
yield: (function)


Contents of _G[‘debug’]

debug: (function)
getfenv: (function)
gethook: (function)
getinfo: (function)
getlocal: (function)
getmetatable: (function)
getregistry: (function)
getupvalue: (function)
setfenv: (function)
sethook: (function)
setlocal: (function)
setmetatable: (function)
setupvalue: (function)
traceback: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 596[/import]

The “native” table has also been completely described in the docs. Unfortunately, there are no “hidden” functions for text input (which still seems to be missing!):

[code]

Contents of _G[‘native’]

cancelAlert: (function)
showAlert: (function)
[/code] [import]uid: 4331 topic_id: 359 reply_id: 601[/import]