Advertisement
lavalevel

loq_util.lua

Jan 9th, 2015
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 23.76 KB | None | 0 0
  1. -- Copyright 2011 Loqheart
  2.  
  3. --[[
  4.     Module: loq_util
  5.         Utility functions used by other modules.
  6.  
  7.     Usage:
  8.         require("loq_util")
  9. ]]
  10.  
  11. -- Some utilities for better debugging, print_r taken from Corona's CodeExchange
  12.  
  13. --[[
  14.     Group: Debugging
  15. ]]
  16.  
  17. --[[
  18.     Function: atrace
  19.         Prints a debugging message with a time stamp and stack trace.
  20.  
  21.     Parameters:
  22.         - _msg The message to display, can be a string, function, or table
  23.         - _depth The depth of the stack.  Defaults to 1.
  24. ]]
  25. function atrace(_msg, _depth)
  26.     if _msg == nil then
  27.         _msg = "nil"
  28.     else
  29.         if type(_msg) == 'function' then
  30.             _msg = functionInfo(_msg)
  31.         elseif type(_msg) == 'table' then
  32.             _msg = xinspect(_msg)
  33.         else
  34.             _msg = tostring(_msg)
  35.         end
  36.     end
  37.  
  38.     _depth = _depth or 1
  39.  
  40.     local sysTime = system and ("(" .. formatMS(system.getTimer()) .. ") ") or "- "
  41.     print(" = > atrace " .. sysTime .. _msg)
  42.     local res = debug.traceback():split("\n")
  43.  
  44.     local counter = 1
  45.     for i, v in ipairs(res) do
  46.         counter = counter + 1
  47.         if counter > 3 and counter < (3+_depth+1) then
  48.             print(tostring(v))
  49.         end
  50.  
  51.     end
  52.     --print(table.concat(res, "\n", 3, _depth + 2))
  53.     -- sometimes gets an error that some table values in res aren't strings
  54.     print()
  55. end
  56.  
  57. --[[
  58.     Function: formatMS
  59.         Format milliseconds into a string HH:MM:SS:MS
  60.  
  61.     Parameters:
  62.         - _ms Milliseconds from a call like system.getTimer()
  63.  
  64.     Returns:
  65.         A string in the format HH:MM:SS:MS where HH is hours, MM is minutes, SS is seconds, and MS is milliseconds
  66. ]]
  67. function formatMS(_ms)
  68.     if not _ms then
  69.         return ""
  70.     end
  71.  
  72.     local ms = _ms % 1000
  73.     local secs = math.floor(_ms / 1000)
  74.     local mins = math.floor(secs / 60)
  75.     local hours = math.floor(mins / 60)
  76.     secs = secs % 60
  77.     mins = mins % 60
  78.     hours = hours % 24
  79.     return string.format("%02d:%02d:%02d:%03d", hours, mins, secs, ms)
  80. end
  81.  
  82. --[[
  83.     Function: functionInfo
  84.         Returns the file and line numbers for a function's definition
  85.  
  86.     Parameters:
  87.         - _func The function
  88.  
  89.     Returns:
  90.         A string with the file and line numbers for the function's definition.  If not a valid function then returns nil.
  91. ]]
  92. function functionInfo(_func)
  93.     if type(_func) == 'function' then
  94.         local info = debug.getinfo(_func)
  95.         return 'function ' ..  info.source .. ':[' .. info.linedefined .. ', ' .. info.lastlinedefined .. ']'
  96.     else
  97.         return nil
  98.     end
  99. end
  100.  
  101. --[[
  102.     Function: loq_declare
  103.         Used to declare global values. If loq_DeclareGlobals is true before the loq_util module is loaded,
  104.         then global values used without loq_declare() throw an error.  From kam187 on the Corona Code Exchange
  105.  
  106.         Parameters:
  107.             - _name Name of the global variable.
  108.             - _initval Initial value of the variable.
  109.  
  110.         Usage:
  111.         (start code)
  112.             local loq_DeclareGlobals = true
  113.             require('loq_util')
  114.             loq_declare("MyGlobal", {})
  115.         (end)
  116. ]]
  117. function loq_declare (_name, _initval)
  118.     rawset(_G, _name, _initval or {})
  119. end
  120.  
  121. --[[
  122.     Function: loq_undeclared
  123.         Checks if a string name of a variable has been declared as a global.
  124.  
  125.     Parameters:
  126.         - _name Name of the global variable.
  127.  
  128.     Returns:
  129.         - true if the variable name is undeclared with loq_declare.
  130.         - false if the variable has been declared with loq_declare.
  131. ]]
  132. function loq_undeclared(_name)
  133.     return rawget(_G, _name) == nil
  134. end
  135.  
  136. --[[
  137.     Function: xinspect
  138.         Returns a nicely formated string with the properties and contents listed of the parameter passed in.
  139.    
  140.     Parameters:
  141.         - _t A value.
  142.    
  143.     Returns:
  144.         A nicely formated string with the properties and contents listed.
  145.  
  146.     Usage:
  147.     (start code)
  148.         local values = { a = 1, b = 'hello' }
  149.         atrace(xinspect(values))
  150.     (end)
  151. ]]
  152. function xinspect( _t )
  153.     local status, retval = pcall(print_r, _t)
  154.     return retval
  155. end
  156.  
  157. function print_r ( t )
  158.     local out = {}
  159.     local print_r_cache={}
  160.     local function sub_print_r(t,indent)
  161.         if (print_r_cache[tostring(t)]) then
  162.             table.insert(out, indent.."*"..tostring(t))
  163.         else
  164.             print_r_cache[tostring(t)]=true
  165.             if (type(t)=="table") then
  166.                 for pos,val in pairs(t) do
  167.                     if (type(val)=="table") then
  168.                         table.insert(out, indent.."["..pos.."] => "..tostring(t).." {")
  169.                         sub_print_r(val,indent..string.rep(" ",string.len(pos)+8))
  170.                         table.insert(out, indent..string.rep(" ",string.len(pos)+6).."}")
  171.                     elseif (type(val)=="string") then
  172.                         table.insert(out, indent.."["..pos..'] => "'..val..'"')
  173.                     else
  174.                         table.insert(out, indent.."["..pos.."] => "..tostring(val))
  175.                     end
  176.                 end
  177.             else
  178.                 table.insert(out, indent..tostring(t))
  179.             end
  180.         end
  181.     end
  182.  
  183.     if (t["__tostring"]) then
  184.         table.insert(out, tostring(t))
  185.     elseif (type(t)=="table") then
  186.         table.insert(out, tostring(t).." {")
  187.         sub_print_r(t,"  ")
  188.         table.insert(out, "}")
  189.     else
  190.         sub_print_r(t,"  ")
  191.     end
  192.  
  193.     return table.concat(out, "\n")
  194. end
  195.  
  196. --[[
  197.     Group: String
  198. ]]
  199.  
  200. --[[
  201.     Function: string:split
  202.         Splits the string using with a separator
  203.  
  204.     Parameters:
  205.         - sSeparator A string separator.
  206.  
  207.     Returns:
  208.         A table of strings.
  209. ]]
  210. function string:split(sSeparator, nMax, bRegexp)
  211.     --assert(sSeparator ~= '')
  212.     assert(nMax == nil or nMax >= 1)
  213.  
  214.     local aRecord = {}
  215.  
  216.     if sSeparator == '' then
  217.         for i = 1, #self do
  218.             aRecord[i] = self:sub(i, i)
  219.         end
  220.     elseif self:len() > 0 then
  221.         local bPlain = not bRegexp
  222.         nMax = nMax or -1
  223.  
  224.         local nField, nStart = 1, 1
  225.         local nFirst,nLast = self:find(sSeparator, nStart, bPlain)
  226.         while nFirst and nMax ~= 0 do
  227.             aRecord[nField] = self:sub(nStart, nFirst-1)
  228.             nField = nField+1
  229.             nStart = nLast+1
  230.             nFirst,nLast = self:find(sSeparator, nStart, bPlain)
  231.             nMax = nMax-1
  232.         end
  233.         aRecord[nField] = self:sub(nStart)
  234.     end
  235.  
  236.     return aRecord
  237. end
  238.  
  239. --[[
  240.     Group: Table
  241. ]]
  242.  
  243. -- supports older versions of Corona
  244. if not table.indexOf then
  245. --[[
  246.     Function: table.indexOf
  247.         Searches a table for an item and returns its index or nil if not found
  248.  
  249.     Parameters:
  250.         - _t The table.
  251.         - _item The item to find.
  252.  
  253.     Returns:
  254.         The index or nil if not found.
  255.  
  256.     NOTE: This is only defined if table.indexOf does not already exist in the runtime environment.  
  257.     It is added only for compatibility with older versions of the Corona SDK.
  258. ]]
  259.     function table.indexOf(_t, _item)
  260.         for i, v in ipairs(_t) do
  261.             if _item == v then
  262.                 return i
  263.             end
  264.         end
  265.         return nil
  266.     end
  267. end
  268.  
  269. -- supports older versions of Corona
  270. if not table.copy then
  271. --[[
  272.     Function: table.copy
  273.         Returns a shallow copy of array, i.e. the portion of the array (table) with integer keys.
  274.         A variable number of additional arrays can be passed in as optional arguments.
  275.         If an array has a hole (a nil entry), copying in a given source array stops at the
  276.         last consecutive item prior to the hole.
  277.  
  278.     Parameters:
  279.         - ... Optional, one or more tables.
  280.  
  281.     Returns:
  282.         Returns a shallow copy of combined arrays.
  283.  
  284.     NOTE: This is only defined if table.copy does not already exist in the runtime environment.  
  285.     It is added only for compatibility with older versions of the Corona SDK.
  286. ]]
  287.     function table.copy(...)
  288.         local t = {}
  289.          for adx, tb in ipairs(arg) do
  290.              for i = 1, #tb do
  291.                  table.insert(t, tb[i])
  292.              end
  293.          end
  294.          return t
  295.     end
  296. end
  297.  
  298. --[[
  299.     Function: table.removeItem
  300.         Searches a table for an item and removes it if present.
  301.  
  302.     Parameters:
  303.         - _t The table.
  304.         - _item The item to remove.
  305. ]]
  306. function table.removeItem(_t, _item)
  307.     local i = table.indexOf(_t, _item)
  308.     if i ~= nil then
  309.         table.remove(_t, i)
  310.     end
  311. end
  312.  
  313. --[[
  314.     Group: Math
  315. ]]
  316.  
  317. function bezierValue(_t, _a, _b, _c, _d)
  318.     return (_t*_t*(_d-_a) + 3*(1-_t)*(_t*(_c-_a) + (1-_t)*(_b-_a)))*_t + _a;
  319. end
  320.  
  321. --[[
  322.     Function: rotateVec2
  323.         Rotates vector components x, y through an angle.
  324.  
  325.     Parameters:
  326.         - _degrees The angle in degrees
  327.         - _x X component of 2D vector
  328.         - _y Y component of 2D vector
  329.  
  330.     Returns:
  331.         The rotated x and y values.
  332. ]]
  333. function rotateVec2(_degrees, _x, _y)
  334.     local angle = math.rad(_degrees)
  335.     local ct = math.cos(angle)
  336.     local st = math.sin(angle)
  337.     return (_x*ct - _y*st), (_x*st + _y*ct)
  338. end
  339.  
  340.  
  341. loq_declare('socket')
  342.  
  343. function testNetworkConnection(_url)
  344.     assert(_url, "URL cannon be nil")
  345.     local nc = require('socket').connect(_url, 80)
  346.     if nc == nil then
  347.         return false
  348.     end
  349.     nc:close()
  350.     return true
  351. end
  352.  
  353. function loq_addEventListener(self, _name, _listener)
  354.     self:_origAdd( _name, _listener )
  355.     if self.__listeners[_name] == nil then
  356.         self.__listeners[_name] = { _listener }
  357.     else
  358.         local index = table.indexOf(self.__listeners[_name], _listener)
  359.         if (index == nil) then
  360.             table.insert(self.__listeners[_name], _listener)
  361.         end
  362.     end
  363. end
  364.  
  365. function loq_removeEventListener(self, _name, _listener)
  366.     self:_origRemove( _name, _listener )
  367.     if self.__listeners[_name] ~= nil then
  368.         table.removeItem(self.__listeners[_name], _listener)
  369.     end
  370. end
  371.  
  372. function loq_clearListeners(self, _name)
  373.     if _name == nil then
  374.         self.__listeners = {}
  375.     elseif type(_name) == 'string' then
  376.         self.__listeners[_name] = nil
  377.     end
  378. end
  379.  
  380. function loq_dispatchEvent(self, _e)
  381.     local name = _e.name
  382.     local ret = false
  383.     if self.__listeners[name] ~= nil then
  384.         local listeners = self.__listeners[name]
  385.         for i = 1, #listeners do
  386.             local l = listeners[i]
  387.             if type(l) == 'function' then
  388.                 ret = l(_e)
  389.             elseif type(l) == 'table' and type(l[name]) == 'function' then
  390.                 local f = l[name]
  391.                 ret = f(l, _e)
  392.             end
  393.             if ret then
  394.                 break
  395.             end
  396.         end
  397.     end
  398.     return ret
  399. end
  400.  
  401. --[[
  402.     Group: Events
  403. ]]
  404.  
  405. --[[
  406.     Function: loq_listeners
  407.         Uses adds event dispatching to the object.  Can be used to replace the event dispatching
  408.         functions (addEventListener, removeEventListener, dispatchEvent) for display objects or
  409.         to add event dispatching to regular objects. Also adds clearListeners for remove all
  410.         event listeners or event listeners of a certain type.
  411.  
  412.     Parameters:
  413.         - _obj A table.
  414.  
  415.     NOTE: loq_listeners is used in SpriteGroups to replace the Corona display object event dispatching
  416.     system in order to prevent misbehavior in the Corona event dispatching API.
  417. ]]
  418. function loq_listeners(_obj)
  419.     _obj.__listeners = {}
  420.     if _obj.addEventListener then
  421.         _obj:addEventListener('collision', function() end)
  422.     end
  423.     _obj._origAdd = _obj.addEventListener
  424.     _obj._origRemove = _obj.removeEventListener
  425.     _obj.addEventListener = loq_addEventListener
  426.     _obj.removeEventListener = loq_removeEventListener
  427.     _obj.dispatchEvent = loq_dispatchEvent
  428.     _obj.clearListeners = loq_clearListeners
  429. end
  430.  
  431. --[[
  432.     Group: Graphics Optimization
  433. ]]
  434.  
  435. function loq_display_cache(_d, _x, _y, _rotation, _xScale, _yScale)
  436.     if _x then
  437.         _d.x, _d.cx = _x, _x
  438.     else
  439.         _d.cx = _d.x
  440.     end
  441.  
  442.     if _y then
  443.         _d.y, _d.cy = _y, _y
  444.     else
  445.         _d.cy = _d.y
  446.     end
  447.  
  448.     if _rotation then
  449.         _d.rotation, _d.crotation = _rotation, _rotation
  450.     else
  451.         _d.crotation = _d.rotation
  452.     end
  453.  
  454.     if _xScale then
  455.         _d.xScale, _d.cxScale = _xScale, _xScale
  456.     else
  457.         _d.cxScale = _d.xScale
  458.     end
  459.  
  460.     if _yScale then
  461.         _d.yScale, _d.cyScale = _yScale, _yScale
  462.     else
  463.         _d.cyScale = _d.yScale
  464.     end
  465.  
  466.     return _d
  467. end
  468.  
  469. function loq_translateTo(_d, _x, _y)
  470.     if _x == _d.cx and _y == _d.cy then
  471.         return _d
  472.     end
  473.  
  474.     local dx = _x - _d.cx
  475.     local dy = _y - _d.cy
  476.     _d:_ctranslate(dx, dy)
  477.     _d.cx = _x
  478.     _d.cy = _y
  479.     return _d
  480. end
  481.  
  482. function loq_rotateTo(_d, _w)
  483.     if _w == _d.crotation then
  484.         return _d
  485.     end
  486.  
  487.     local dw = _w - _d.crotation
  488.     _d:_crotate(dw)
  489.     _d.crotation = _w
  490.     return _d
  491. end
  492.  
  493. function loq_scaleTo(_d, _xScale, _yScale)
  494.     if _xScale == _d.cxScale and _yScale == _d.cyScale then
  495.         return _d
  496.     end
  497.  
  498.     local dxs = _xScale/_d.cxScale
  499.     local dys = _yScale/_d.cyScale
  500.  
  501.     _d:_cscale(dxs, dys)
  502.     _d.cxScale = _xScale
  503.     _d.cyScale = _yScale
  504.     return _d
  505. end
  506.  
  507. function loq_translate(_d, _dx, _dy)
  508.     _d.cx = _d.cx + _dx
  509.     _d.cy = _d.cy + _dy
  510.  
  511.     _d:_ctranslate(_dx, _dy)
  512. end
  513.  
  514. function loq_rotate(_d, _dw)
  515.     _d.crotation = _d.crotation + _dw
  516.  
  517.     _d:_crotate(_dw)
  518. end
  519.  
  520. function loq_scale(_d, _dxScale, _dyScale)
  521.     _d.cxScale = _d.cxScale * _dxScale
  522.     _d.cyScale = _d.cyScale * _dyScale
  523.  
  524.     _d:_cscale(_dxScale, _dyScale)
  525. end
  526.  
  527. --[[
  528.     Function: loq_display
  529.         Adds functions to the display object to optimize transformations: translating, rotating, scaling.
  530.         Use the methods translateTo, rotateTo and scaleTo to transform the display object, instead of directly
  531.         setting the x, y, rotation, xScale, and yScale values for higher performance.
  532.  
  533.         The speed up is due to caching the x, y, etc properties and using the translate, rotate, and scale
  534.         functions to operate on these cached values.
  535.        
  536.         The loq_display function also modifies translate, rotate, and scale to used cached values.
  537.  
  538.         You can directly access the cached values as cx, cy, crotation, cxScale, and cyScale.
  539.  
  540.         Methods:
  541.             - translateTo Takes x and y target values to position the object.
  542.             - scaleTo Takes xScale and yScale target values to scale the object.
  543.             - rotateTo Takes an rotation target value to rotate the object.
  544.             - cache Initialize the display object and its cache properties.  Optionally takes x, y, rotation, xScale, yScale.
  545.  
  546.         Cached Properties:
  547.             - cx Cached x value
  548.             - cy Cached y value
  549.             - crotation Cached rotation value
  550.             - cxScale Cached xScale value
  551.             - cyScale Cached yScale value
  552.  
  553.         You can use the cached properties for increased performance.
  554.  
  555.         Note: You should use the actual x, y, and rotation properties if the display object is a physics body.
  556.  
  557.         Check out the example below.
  558.  
  559.     Parameters:
  560.         - _d A display object
  561. ]]
  562. function loq_display(_d)
  563.     if not _d.cache then
  564.         _d.cache = loq_display_cache
  565.         _d:cache()
  566.  
  567.         -- save the Corona versions
  568.         _d._ctranslate = _d.translate
  569.         _d._crotate = _d.rotate
  570.         _d._cscale = _d.scale
  571.  
  572.         _d.translateTo = loq_translateTo
  573.         _d.rotateTo = loq_rotateTo
  574.         _d.scaleTo = loq_scaleTo
  575.  
  576.         _d.translate = loq_translate
  577.         _d.rotate = loq_rotate
  578.         _d.scale = loq_scale
  579.     end
  580.     return _d
  581. end
  582.  
  583.  
  584. --[[
  585.     Group: Modules
  586. ]]
  587.  
  588. --[[
  589.    Function: unrequire
  590.         Removes a required lua file from the loaded packages to free up application memory.
  591.  
  592.    Parameters:
  593.        - _filename The name of a lua file to be removed from the loaded packages to clear up application memory.
  594. ]]
  595.  
  596. function unrequire(m)
  597.     package.loaded[m] = nil
  598.     rawset(_G, m, nil)
  599.  
  600.     -- Search for the shared library handle in the registry and erase it
  601.     local registry = debug.getregistry()
  602.     local nMatches, mKey, mt = 0, nil, registry['_LOADLIB']
  603.  
  604.     for key, ud in pairs(registry) do
  605.         if type(key) == 'string' and type(ud) == 'userdata' and getmetatable(ud) == mt and string.find(key, "LOADLIB: .*" .. m) then
  606.             nMatches = nMatches + 1
  607.             if nMatches > 1 then
  608.                 return false, "More than one possible key for module '" .. m .. "'. Can't decide which one to erase."
  609.             end
  610.             mKey = key
  611.         end
  612.     end
  613.  
  614.     if mKey then
  615.         registry[mKey] = nil
  616.     end
  617.  
  618.     return true
  619. end
  620.  
  621.  
  622. if loq_DeclareGlobals then
  623.     setmetatable(_G, {
  624.         __newindex = function(_ENV, var, val)
  625.             if var ~= 'tableDict' then
  626.                 error(("attempt to set undeclared global\"%s\""):format(tostring(var)), 2)
  627.             else
  628.                 rawset(_ENV, var, val)
  629.             end
  630.         end,
  631.         __index = function(_ENV, var)
  632.             if var ~= 'tableDict' then
  633.                 error(("attempt to read undeclared global\"%s\""):format(tostring(var)), 2)
  634.             end
  635.         end,
  636.     })
  637. end
  638.  
  639. --[[
  640.     Section: Examples
  641.  
  642.     Example: Using atrace and xinspect for debugging
  643.  
  644.         Using atrace and xinspect for debugging.  You might use print to get debugging info from the Corona terminal.
  645.         You can use atrace where you would use print to get extra information like line numbers, timings, and a stack trace.
  646.  
  647.         atrace can check if the value passed in is a function or a table and attempt to print it out.  You can use xinspect
  648.         on tables and functionInfo on functions if you need to concatenate their values to a string.
  649.  
  650.     (start code)
  651.     require('loq_util')
  652.  
  653.     -- print out a message
  654.     atrace('This works like print, but you get a time, file, line number, and function')
  655.  
  656.     -- print out a value
  657.     local myvar = 10
  658.     atrace(myvar)
  659.  
  660.     local mytable = {a = 100}
  661.     atrace(mytable) -- that's better!
  662.  
  663.     --atrace('mytable ' .. mytable) -- Throws an error.  Can't convert a table to a string
  664.    
  665.     -- Use xinspect on mytable
  666.     atrace('mytable ' .. xinspect(mytable)) -- that's better
  667.  
  668.  
  669.     local function myfunc()
  670.         atrace('inside a function')
  671.        
  672.         local function anotherfunc()
  673.             atrace("notice that atrace prints the function you're in!")
  674.             atrace("let's print the stack 2 deep", 2)
  675.  
  676.             local function funcInFunc()
  677.                 atrace("let's print the stack 2 deep again", 2)
  678.                 atrace('now all the way', 10)
  679.             end
  680.  
  681.             funcInFunc()
  682.  
  683.             atrace('assigning the function to a variable in lua we lose the original name')
  684.             local renameMyFunc = funcInFunc
  685.             renameMyFunc()
  686.  
  687.             atrace("we can get some info about the function renameMyFunc points to")
  688.             atrace(renameMyFunc)
  689.         end
  690.  
  691.         anotherfunc()
  692.     end
  693.  
  694.     myfunc()
  695.     (end)
  696. ]]
  697.  
  698. --[[
  699.     Example: Global declaration of variables before usage
  700.    
  701.         Global declaration of variables before usage.
  702.  
  703.         If you want to force declarations of globals before usage set a variable loq_DeclareGlobals to true before requiring 'loq_util'.
  704.         Then you can use the loq_declare declare the global variable before using it.  You can also use loq_undeclared to check whether
  705.         a variable has been declare before accessing it.
  706.  
  707.         NOTE: With loq_DeclareGlobals enabled, some Corona modules you require must be declared first because they create globals (e.g. 'physics', 'sprite')
  708.  
  709.         main.lua -- using loq_DeclareGlobals in main.lua sets the option for you application
  710.     (start code)
  711.         loq_DeclareGlobals = true -- if nil or false then globals don't require declarations
  712.         require('loq_util')
  713.  
  714.         loq_declare('physics')
  715.         require('physics') -- The Corona physics module must be declared because it creates a global.
  716.        
  717.         loq_declare('myglobal')
  718.         myglobal = 10
  719.  
  720.         atrace(loq_undeclared('myUndeclaredGlobal'))
  721.  
  722.         atrace(myUndeclaredGlobal) -- throws an error
  723.     (end)
  724.  
  725.  
  726.         yourmodule.lua -- Using the module function creates a global value.  You need to declare the module if loq_DeclareGlobals is true.
  727.     (start code)
  728.         if loq_DeclareGlobals then
  729.             loq_declare('yourmodule')
  730.         end
  731.  
  732.         module(..., package.seeall) -- this globally defines your module when required
  733.         --  the rest of the module
  734.     (end)
  735. ]]
  736.  
  737. --[[
  738.     Example: Unloading modules from application memory with unrequire.
  739.        
  740.         Unloading modules from application memory with unrequire.  Loading a module with the standard 'require' function creates a global variable.
  741.         And loads the module into global memory.  If you're temporarily using a module, then this is basically a form of a memory leak.
  742.  
  743.         You can reclaim some of the application memory by calling 'unrequire' on the required module.  Try commmenting and uncommenting
  744.         your require and unrequire calls with the loq_profiler to see the difference in your application memory usage.
  745.  
  746.     (start code)
  747.     require('loq_util')        
  748.     -- instantiate to keep an eye on application memory
  749.     require('loq_profiler').createProfiler()
  750.  
  751.     local myModule = require('myModule')
  752.     -- ... some processing here, don't need the module anymore
  753.     unrequire('myModule') -- removes the module from the global packages and reclaims some app memory
  754.     (end)
  755. ]]
  756.  
  757. --[[
  758.     Example: Using loq_display to boost performance of transforming display objects
  759.  
  760.         Based on testing as of build 721, accessing the properties of a display object in Corona is very slow.
  761.         http://developer.anscamobile.com/forum/2011/12/03/tips-optimization-101#comment-71273
  762.  
  763.         Using the loq_display function on display objects is a workaround to speed up the performance of
  764.         transforming display objects.  By default, Spriteloq SpriteGroups use loq_display.
  765.  
  766.         With loq_display applied to a display object it gets these new methods and properties which can be used in place
  767.         of accessing the x, y, rotation, xScale, yScale for transforms.
  768.  
  769.         Methods:
  770.             - translateTo Takes x and y target values to position the object.
  771.             - scaleTo Takes xScale and yScale target values to scale the object.
  772.             - rotateTo Takes an rotation target value to rotate the object.
  773.             - cache Initialize the display object and its cache properties.  Optionally takes x, y, rotation, xScale, yScale.
  774.  
  775.         Cached Properties:
  776.             - cx Cached x value
  777.             - cy Cached y value
  778.             - crotation Cached rotation value
  779.             - cxScale Cached xScale value
  780.             - cyScale Cached yScale value
  781.  
  782.         You can use the cached properties for increased performance.
  783.  
  784.         Note: You should use the actual x, y, and rotation properties if the display object is a physics body.
  785.  
  786.     (start code)
  787.     require('loq_util')
  788.  
  789.     local rect = display.newRect(0, 0, 100, 100)
  790.     loq_display(rect)  -- gains performance transform methods and properties and caches the initial values
  791.  
  792.     rect:cache(200, 200, 45) -- sets the initial cached properties
  793.  
  794.     local angle = 45
  795.  
  796.     local x = 200
  797.     local y = 200
  798.  
  799.     local function enterFrame(_e)
  800.         -- accessing the x, y, rotation, xScale and yScale properties is slower
  801.         rect:rotateTo(angle)
  802.         angle = angle + 1
  803.    
  804.         rect:translateTo(x, y)
  805.         x = x + 1
  806.    
  807.         -- this access is fast
  808.         local cx = rect.cx
  809.  
  810.         -- this access is slow, but if rect is a physics body you must use x
  811.         cx = rect.x
  812.     end
  813.  
  814.     Runtime:addEventListener('enterFrame', enterFrame)
  815.     (end)
  816. ]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement