lua framework 修改为3.7.

This commit is contained in:
u0u0
2020-01-29 10:22:58 +08:00
parent 957dc96f03
commit 2bf3d2ef54
75 changed files with 6594 additions and 3614 deletions

View File

@@ -653,10 +653,15 @@ int LuaStack::luaLoadChunksFromZIP(lua_State *L)
unsigned char *zbuffer = zip->getFileData(filename.c_str(), &bufferSize);
if (bufferSize) {
if (luaLoadBuffer(L, (char*)zbuffer, (int)bufferSize, filename.c_str()) == 0) {
lua_setfield(L, -3, filename.c_str());
// special fix for protobuf find path in zip.
int offset = 0;
if (filename.find("framework.protobuf.") != std::string::npos) {
offset = 19;
}
lua_setfield(L, -3, filename.c_str() + offset);
// clear loaded, make the next require run the new module.
lua_pushnil(L);
lua_setfield(L, -2, filename.c_str());
lua_setfield(L, -2, filename.c_str() + offset);
++count;
}
free(zbuffer);

View File

@@ -1,632 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
function printLog(tag, fmt, ...)
local t = {
"[",
string.upper(tostring(tag)),
"] ",
string.format(tostring(fmt), ...)
}
print(table.concat(t))
end
function printError(fmt, ...)
printLog("ERR", fmt, ...)
print(debug.traceback("", 2))
end
function printInfo(fmt, ...)
if type(DEBUG) ~= "number" or DEBUG < 2 then return end
printLog("INFO", fmt, ...)
end
local function dump_value_(v)
if type(v) == "string" then
v = "\"" .. v .. "\""
end
return tostring(v)
end
function dump(value, description, nesting)
if type(nesting) ~= "number" then nesting = 3 end
local lookupTable = {}
local result = {}
local traceback = string.split(debug.traceback("", 2), "\n")
print("dump from: " .. string.trim(traceback[3]))
local function dump_(value, description, indent, nest, keylen)
description = description or "<var>"
local spc = ""
if type(keylen) == "number" then
spc = string.rep(" ", keylen - string.len(dump_value_(description)))
end
if type(value) ~= "table" then
result[#result +1 ] = string.format("%s%s%s = %s", indent, dump_value_(description), spc, dump_value_(value))
elseif lookupTable[tostring(value)] then
result[#result +1 ] = string.format("%s%s%s = *REF*", indent, dump_value_(description), spc)
else
lookupTable[tostring(value)] = true
if nest > nesting then
result[#result +1 ] = string.format("%s%s = *MAX NESTING*", indent, dump_value_(description))
else
result[#result +1 ] = string.format("%s%s = {", indent, dump_value_(description))
local indent2 = indent.." "
local keys = {}
local keylen = 0
local values = {}
for k, v in pairs(value) do
keys[#keys + 1] = k
local vk = dump_value_(k)
local vkl = string.len(vk)
if vkl > keylen then keylen = vkl end
values[k] = v
end
table.sort(keys, function(a, b)
if type(a) == "number" and type(b) == "number" then
return a < b
else
return tostring(a) < tostring(b)
end
end)
for i, k in ipairs(keys) do
dump_(values[k], k, indent2, nest + 1, keylen)
end
result[#result +1] = string.format("%s}", indent)
end
end
end
dump_(value, description, "- ", 1)
for i, line in ipairs(result) do
print(line)
end
end
function printf(fmt, ...)
print(string.format(tostring(fmt), ...))
end
function checknumber(value, base)
return tonumber(value, base) or 0
end
function checkint(value)
return math.round(checknumber(value))
end
function checkbool(value)
return (value ~= nil and value ~= false)
end
function checktable(value)
if type(value) ~= "table" then value = {} end
return value
end
function isset(hashtable, key)
local t = type(hashtable)
return (t == "table" or t == "userdata") and hashtable[key] ~= nil
end
local setmetatableindex_
setmetatableindex_ = function(t, index)
if type(t) == "userdata" then
local peer = tolua.getpeer(t)
if not peer then
peer = {}
tolua.setpeer(t, peer)
end
setmetatableindex_(peer, index)
else
local mt = getmetatable(t)
if not mt then mt = {} end
if not mt.__index then
mt.__index = index
setmetatable(t, mt)
elseif mt.__index ~= index then
setmetatableindex_(mt, index)
end
end
end
setmetatableindex = setmetatableindex_
function clone(object)
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local newObject = {}
lookup_table[object] = newObject
for key, value in pairs(object) do
newObject[_copy(key)] = _copy(value)
end
return setmetatable(newObject, getmetatable(object))
end
return _copy(object)
end
function class(classname, ...)
local cls = {__cname = classname}
local supers = {...}
for _, super in ipairs(supers) do
local superType = type(super)
assert(superType == "nil" or superType == "table" or superType == "function",
string.format("class() - create class \"%s\" with invalid super class type \"%s\"",
classname, superType))
if superType == "function" then
assert(cls.__create == nil,
string.format("class() - create class \"%s\" with more than one creating function",
classname));
-- if super is function, set it to __create
cls.__create = super
elseif superType == "table" then
if super[".isclass"] then
-- super is native class
assert(cls.__create == nil,
string.format("class() - create class \"%s\" with more than one creating function or native class",
classname));
cls.__create = function() return super:create() end
else
-- super is pure lua class
cls.__supers = cls.__supers or {}
cls.__supers[#cls.__supers + 1] = super
if not cls.super then
-- set first super pure lua class as class.super
cls.super = super
end
end
else
error(string.format("class() - create class \"%s\" with invalid super type",
classname), 0)
end
end
cls.__index = cls
if not cls.__supers or #cls.__supers == 1 then
setmetatable(cls, {__index = cls.super})
else
setmetatable(cls, {__index = function(_, key)
local supers = cls.__supers
for i = 1, #supers do
local super = supers[i]
if super[key] then return super[key] end
end
end})
end
if not cls.ctor then
-- add default constructor
cls.ctor = function() end
end
cls.new = function(...)
local instance
if cls.__create then
instance = cls.__create(...)
else
instance = {}
end
setmetatableindex(instance, cls)
instance.class = cls
instance:ctor(...)
return instance
end
cls.create = function(_, ...)
return cls.new(...)
end
return cls
end
local iskindof_
iskindof_ = function(cls, name)
local __index = rawget(cls, "__index")
if type(__index) == "table" and rawget(__index, "__cname") == name then return true end
if rawget(cls, "__cname") == name then return true end
local __supers = rawget(__index, "__supers")
if not __supers then return false end
for _, super in ipairs(__supers) do
if iskindof_(super, name) then return true end
end
return false
end
function iskindof(obj, classname)
local t = type(obj)
if t ~= "table" and t ~= "userdata" then return false end
local mt
if t == "userdata" then
if tolua.iskindof(obj, classname) then return true end
mt = getmetatable(tolua.getpeer(obj))
else
mt = getmetatable(obj)
end
if mt then
return iskindof_(mt, classname)
end
return false
end
function import(moduleName, currentModuleName)
local currentModuleNameParts
local moduleFullName = moduleName
local offset = 1
while true do
if string.byte(moduleName, offset) ~= 46 then -- .
moduleFullName = string.sub(moduleName, offset)
if currentModuleNameParts and #currentModuleNameParts > 0 then
moduleFullName = table.concat(currentModuleNameParts, ".") .. "." .. moduleFullName
end
break
end
offset = offset + 1
if not currentModuleNameParts then
if not currentModuleName then
local n,v = debug.getlocal(3, 1)
currentModuleName = v
end
currentModuleNameParts = string.split(currentModuleName, ".")
end
table.remove(currentModuleNameParts, #currentModuleNameParts)
end
return require(moduleFullName)
end
function handler(obj, method)
return function(...)
return method(obj, ...)
end
end
function math.newrandomseed()
local ok, socket = pcall(function()
return require("socket")
end)
if ok then
math.randomseed(socket.gettime() * 1000)
else
math.randomseed(os.time())
end
math.random()
math.random()
math.random()
math.random()
end
function math.round(value)
value = checknumber(value)
return math.floor(value + 0.5)
end
local pi_div_180 = math.pi / 180
function math.angle2radian(angle)
return angle * pi_div_180
end
function math.radian2angle(radian)
return radian * 180 / math.pi
end
function io.exists(path)
local file = io.open(path, "r")
if file then
io.close(file)
return true
end
return false
end
function io.readfile(path)
local file = io.open(path, "r")
if file then
local content = file:read("*a")
io.close(file)
return content
end
return nil
end
function io.writefile(path, content, mode)
mode = mode or "w+b"
local file = io.open(path, mode)
if file then
if file:write(content) == nil then return false end
io.close(file)
return true
else
return false
end
end
function io.pathinfo(path)
local pos = string.len(path)
local extpos = pos + 1
while pos > 0 do
local b = string.byte(path, pos)
if b == 46 then -- 46 = char "."
extpos = pos
elseif b == 47 then -- 47 = char "/"
break
end
pos = pos - 1
end
local dirname = string.sub(path, 1, pos)
local filename = string.sub(path, pos + 1)
extpos = extpos - pos
local basename = string.sub(filename, 1, extpos - 1)
local extname = string.sub(filename, extpos)
return {
dirname = dirname,
filename = filename,
basename = basename,
extname = extname
}
end
function io.filesize(path)
local size = false
local file = io.open(path, "r")
if file then
local current = file:seek()
size = file:seek("end")
file:seek("set", current)
io.close(file)
end
return size
end
function table.nums(t)
local count = 0
for k, v in pairs(t) do
count = count + 1
end
return count
end
function table.keys(hashtable)
local keys = {}
for k, v in pairs(hashtable) do
keys[#keys + 1] = k
end
return keys
end
function table.values(hashtable)
local values = {}
for k, v in pairs(hashtable) do
values[#values + 1] = v
end
return values
end
function table.merge(dest, src)
for k, v in pairs(src) do
dest[k] = v
end
end
function table.insertto(dest, src, begin)
begin = checkint(begin)
if begin <= 0 then
begin = #dest + 1
end
local len = #src
for i = 0, len - 1 do
dest[i + begin] = src[i + 1]
end
end
function table.indexof(array, value, begin)
for i = begin or 1, #array do
if array[i] == value then return i end
end
return false
end
function table.keyof(hashtable, value)
for k, v in pairs(hashtable) do
if v == value then return k end
end
return nil
end
function table.removebyvalue(array, value, removeall)
local c, i, max = 0, 1, #array
while i <= max do
if array[i] == value then
table.remove(array, i)
c = c + 1
i = i - 1
max = max - 1
if not removeall then break end
end
i = i + 1
end
return c
end
function table.map(t, fn)
for k, v in pairs(t) do
t[k] = fn(v, k)
end
end
function table.walk(t, fn)
for k,v in pairs(t) do
fn(v, k)
end
end
function table.filter(t, fn)
for k, v in pairs(t) do
if not fn(v, k) then t[k] = nil end
end
end
function table.unique(t, bArray)
local check = {}
local n = {}
local idx = 1
for k, v in pairs(t) do
if not check[v] then
if bArray then
n[idx] = v
idx = idx + 1
else
n[k] = v
end
check[v] = true
end
end
return n
end
string._htmlspecialchars_set = {}
string._htmlspecialchars_set["&"] = "&amp;"
string._htmlspecialchars_set["\""] = "&quot;"
string._htmlspecialchars_set["'"] = "&#039;"
string._htmlspecialchars_set["<"] = "&lt;"
string._htmlspecialchars_set[">"] = "&gt;"
function string.htmlspecialchars(input)
for k, v in pairs(string._htmlspecialchars_set) do
input = string.gsub(input, k, v)
end
return input
end
function string.restorehtmlspecialchars(input)
for k, v in pairs(string._htmlspecialchars_set) do
input = string.gsub(input, v, k)
end
return input
end
function string.nl2br(input)
return string.gsub(input, "\n", "<br />")
end
function string.text2html(input)
input = string.gsub(input, "\t", " ")
input = string.htmlspecialchars(input)
input = string.gsub(input, " ", "&nbsp;")
input = string.nl2br(input)
return input
end
function string.split(input, delimiter)
input = tostring(input)
delimiter = tostring(delimiter)
if (delimiter=='') then return false end
local pos,arr = 0, {}
-- for each divider found
for st,sp in function() return string.find(input, delimiter, pos, true) end do
table.insert(arr, string.sub(input, pos, st - 1))
pos = sp + 1
end
table.insert(arr, string.sub(input, pos))
return arr
end
function string.ltrim(input)
return string.gsub(input, "^[ \t\n\r]+", "")
end
function string.rtrim(input)
return string.gsub(input, "[ \t\n\r]+$", "")
end
function string.trim(input)
input = string.gsub(input, "^[ \t\n\r]+", "")
return string.gsub(input, "[ \t\n\r]+$", "")
end
function string.ucfirst(input)
return string.upper(string.sub(input, 1, 1)) .. string.sub(input, 2)
end
local function urlencodechar(char)
return "%" .. string.format("%02X", string.byte(char))
end
function string.urlencode(input)
-- convert line endings
input = string.gsub(tostring(input), "\n", "\r\n")
-- escape all characters but alphanumeric, '.' and '-'
input = string.gsub(input, "([^%w%.%- ])", urlencodechar)
-- convert spaces to "+" symbols
return string.gsub(input, " ", "+")
end
function string.urldecode(input)
input = string.gsub (input, "+", " ")
input = string.gsub (input, "%%(%x%x)", function(h) return string.char(checknumber(h,16)) end)
input = string.gsub (input, "\r\n", "\n")
return input
end
function string.utf8len(input)
local len = string.len(input)
local left = len
local cnt = 0
local arr = {0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}
while left ~= 0 do
local tmp = string.byte(input, -left)
local i = #arr
while arr[i] do
if tmp >= arr[i] then
left = left - i
break
end
i = i - 1
end
cnt = cnt + 1
end
return cnt
end
function string.formatnumberthousands(num)
local formatted = tostring(checknumber(num))
local k
while true do
formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')
if k == 0 then break end
end
return formatted
end

View File

@@ -1,376 +0,0 @@
-----------------------------------------------------------------------------
-- JSON4Lua: JSON encoding / decoding support for the Lua language.
-- json Module.
-- Author: Craig Mason-Jones
-- Homepage: http://json.luaforge.net/
-- Version: 0.9.40
-- This module is released under the MIT License (MIT).
-- Please see LICENCE.txt for details.
--
-- USAGE:
-- This module exposes two functions:
-- encode(o)
-- Returns the table / string / boolean / number / nil / json.null value as a JSON-encoded string.
-- decode(json_string)
-- Returns a Lua object populated with the data encoded in the JSON string json_string.
--
-- REQUIREMENTS:
-- compat-5.1 if using Lua 5.0
--
-- CHANGELOG
-- 0.9.20 Introduction of local Lua functions for private functions (removed _ function prefix).
-- Fixed Lua 5.1 compatibility issues.
-- Introduced json.null to have null values in associative arrays.
-- encode() performance improvement (more than 50%) through table.concat rather than ..
-- Introduced decode ability to ignore /**/ comments in the JSON string.
-- 0.9.10 Fix to array encoding / decoding to correctly manage nil/null values in arrays.
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Imports and dependencies
-----------------------------------------------------------------------------
local math = require('math')
local string = require("string")
local table = require("table")
local base = _G
-----------------------------------------------------------------------------
-- Module declaration
-----------------------------------------------------------------------------
module("json")
-- Public functions
-- Private functions
local decode_scanArray
local decode_scanComment
local decode_scanConstant
local decode_scanNumber
local decode_scanObject
local decode_scanString
local decode_scanWhitespace
local encodeString
local isArray
local isEncodable
-----------------------------------------------------------------------------
-- PUBLIC FUNCTIONS
-----------------------------------------------------------------------------
--- Encodes an arbitrary Lua object / variable.
-- @param v The Lua object / variable to be JSON encoded.
-- @return String containing the JSON encoding in internal Lua string format (i.e. not unicode)
function encode (v)
-- Handle nil values
if v==nil then
return "null"
end
local vtype = base.type(v)
-- Handle strings
if vtype=='string' then
return '"' .. encodeString(v) .. '"' -- Need to handle encoding in string
end
-- Handle booleans
if vtype=='number' or vtype=='boolean' then
return base.tostring(v)
end
-- Handle tables
if vtype=='table' then
local rval = {}
-- Consider arrays separately
local bArray, maxCount = isArray(v)
if bArray then
for i = 1,maxCount do
table.insert(rval, encode(v[i]))
end
else -- An object, not an array
for i,j in base.pairs(v) do
if isEncodable(i) and isEncodable(j) then
table.insert(rval, '"' .. encodeString(i) .. '":' .. encode(j))
end
end
end
if bArray then
return '[' .. table.concat(rval,',') ..']'
else
return '{' .. table.concat(rval,',') .. '}'
end
end
-- Handle null values
if vtype=='function' and v==null then
return 'null'
end
base.assert(false,'encode attempt to encode unsupported type ' .. vtype .. ':' .. base.tostring(v))
end
--- Decodes a JSON string and returns the decoded value as a Lua data structure / value.
-- @param s The string to scan.
-- @param [startPos] Optional starting position where the JSON string is located. Defaults to 1.
-- @param Lua object, number The object that was scanned, as a Lua table / string / number / boolean or nil,
-- and the position of the first character after
-- the scanned JSON object.
function decode(s, startPos)
startPos = startPos and startPos or 1
startPos = decode_scanWhitespace(s,startPos)
base.assert(startPos<=string.len(s), 'Unterminated JSON encoded object found at position in [' .. s .. ']')
local curChar = string.sub(s,startPos,startPos)
-- Object
if curChar=='{' then
return decode_scanObject(s,startPos)
end
-- Array
if curChar=='[' then
return decode_scanArray(s,startPos)
end
-- Number
if string.find("+-0123456789.e", curChar, 1, true) then
return decode_scanNumber(s,startPos)
end
-- String
if curChar==[["]] or curChar==[[']] then
return decode_scanString(s,startPos)
end
if string.sub(s,startPos,startPos+1)=='/*' then
return decode(s, decode_scanComment(s,startPos))
end
-- Otherwise, it must be a constant
return decode_scanConstant(s,startPos)
end
--- The null function allows one to specify a null value in an associative array (which is otherwise
-- discarded if you set the value with 'nil' in Lua. Simply set t = { first=json.null }
function null()
return null -- so json.null() will also return null ;-)
end
-----------------------------------------------------------------------------
-- Internal, PRIVATE functions.
-- Following a Python-like convention, I have prefixed all these 'PRIVATE'
-- functions with an underscore.
-----------------------------------------------------------------------------
--- Scans an array from JSON into a Lua object
-- startPos begins at the start of the array.
-- Returns the array and the next starting position
-- @param s The string being scanned.
-- @param startPos The starting position for the scan.
-- @return table, int The scanned array as a table, and the position of the next character to scan.
function decode_scanArray(s,startPos)
local array = {} -- The return value
local stringLen = string.len(s)
base.assert(string.sub(s,startPos,startPos)=='[','decode_scanArray called but array does not start at position ' .. startPos .. ' in string:\n'..s )
startPos = startPos + 1
-- Infinite loop for array elements
repeat
startPos = decode_scanWhitespace(s,startPos)
base.assert(startPos<=stringLen,'JSON String ended unexpectedly scanning array.')
local curChar = string.sub(s,startPos,startPos)
if (curChar==']') then
return array, startPos+1
end
if (curChar==',') then
startPos = decode_scanWhitespace(s,startPos+1)
end
base.assert(startPos<=stringLen, 'JSON String ended unexpectedly scanning array.')
object, startPos = decode(s,startPos)
table.insert(array,object)
until false
end
--- Scans a comment and discards the comment.
-- Returns the position of the next character following the comment.
-- @param string s The JSON string to scan.
-- @param int startPos The starting position of the comment
function decode_scanComment(s, startPos)
base.assert( string.sub(s,startPos,startPos+1)=='/*', "decode_scanComment called but comment does not start at position " .. startPos)
local endPos = string.find(s,'*/',startPos+2)
base.assert(endPos~=nil, "Unterminated comment in string at " .. startPos)
return endPos+2
end
--- Scans for given constants: true, false or null
-- Returns the appropriate Lua type, and the position of the next character to read.
-- @param s The string being scanned.
-- @param startPos The position in the string at which to start scanning.
-- @return object, int The object (true, false or nil) and the position at which the next character should be
-- scanned.
function decode_scanConstant(s, startPos)
local consts = { ["true"] = true, ["false"] = false, ["null"] = nil }
local constNames = {"true","false","null"}
for i,k in base.pairs(constNames) do
--print ("[" .. string.sub(s,startPos, startPos + string.len(k) -1) .."]", k)
if string.sub(s,startPos, startPos + string.len(k) -1 )==k then
return consts[k], startPos + string.len(k)
end
end
base.assert(nil, 'Failed to scan constant from string ' .. s .. ' at starting position ' .. startPos)
end
--- Scans a number from the JSON encoded string.
-- (in fact, also is able to scan numeric +- eqns, which is not
-- in the JSON spec.)
-- Returns the number, and the position of the next character
-- after the number.
-- @param s The string being scanned.
-- @param startPos The position at which to start scanning.
-- @return number, int The extracted number and the position of the next character to scan.
function decode_scanNumber(s,startPos)
local endPos = startPos+1
local stringLen = string.len(s)
local acceptableChars = "+-0123456789.e"
while (string.find(acceptableChars, string.sub(s,endPos,endPos), 1, true)
and endPos<=stringLen
) do
endPos = endPos + 1
end
local stringValue = 'return ' .. string.sub(s,startPos, endPos-1)
local stringEval = base.loadstring(stringValue)
base.assert(stringEval, 'Failed to scan number [ ' .. stringValue .. '] in JSON string at position ' .. startPos .. ' : ' .. endPos)
return stringEval(), endPos
end
--- Scans a JSON object into a Lua object.
-- startPos begins at the start of the object.
-- Returns the object and the next starting position.
-- @param s The string being scanned.
-- @param startPos The starting position of the scan.
-- @return table, int The scanned object as a table and the position of the next character to scan.
function decode_scanObject(s,startPos)
local object = {}
local stringLen = string.len(s)
local key, value
base.assert(string.sub(s,startPos,startPos)=='{','decode_scanObject called but object does not start at position ' .. startPos .. ' in string:\n' .. s)
startPos = startPos + 1
repeat
startPos = decode_scanWhitespace(s,startPos)
base.assert(startPos<=stringLen, 'JSON string ended unexpectedly while scanning object.')
local curChar = string.sub(s,startPos,startPos)
if (curChar=='}') then
return object,startPos+1
end
if (curChar==',') then
startPos = decode_scanWhitespace(s,startPos+1)
end
base.assert(startPos<=stringLen, 'JSON string ended unexpectedly scanning object.')
-- Scan the key
key, startPos = decode(s,startPos)
base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
startPos = decode_scanWhitespace(s,startPos)
base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
base.assert(string.sub(s,startPos,startPos)==':','JSON object key-value assignment mal-formed at ' .. startPos)
startPos = decode_scanWhitespace(s,startPos+1)
base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
value, startPos = decode(s,startPos)
object[key]=value
until false -- infinite loop while key-value pairs are found
end
--- Scans a JSON string from the opening inverted comma or single quote to the
-- end of the string.
-- Returns the string extracted as a Lua string,
-- and the position of the next non-string character
-- (after the closing inverted comma or single quote).
-- @param s The string being scanned.
-- @param startPos The starting position of the scan.
-- @return string, int The extracted string as a Lua string, and the next character to parse.
function decode_scanString(s,startPos)
base.assert(startPos, 'decode_scanString(..) called without start position')
local startChar = string.sub(s,startPos,startPos)
base.assert(startChar==[[']] or startChar==[["]],'decode_scanString called for a non-string')
local escaped = false
local endPos = startPos + 1
local bEnded = false
local stringLen = string.len(s)
repeat
local curChar = string.sub(s,endPos,endPos)
if not escaped then
if curChar==[[\]] then
escaped = true
else
bEnded = curChar==startChar
end
else
-- If we're escaped, we accept the current character come what may
escaped = false
end
endPos = endPos + 1
base.assert(endPos <= stringLen+1, "String decoding failed: unterminated string at position " .. endPos)
until bEnded
local stringValue = 'return ' .. string.sub(s, startPos, endPos-1)
local stringEval = base.loadstring(stringValue)
base.assert(stringEval, 'Failed to load string [ ' .. stringValue .. '] in JSON4Lua.decode_scanString at position ' .. startPos .. ' : ' .. endPos)
return stringEval(), endPos
end
--- Scans a JSON string skipping all whitespace from the current start position.
-- Returns the position of the first non-whitespace character, or nil if the whole end of string is reached.
-- @param s The string being scanned
-- @param startPos The starting position where we should begin removing whitespace.
-- @return int The first position where non-whitespace was encountered, or string.len(s)+1 if the end of string
-- was reached.
function decode_scanWhitespace(s,startPos)
local whitespace=" \n\r\t"
local stringLen = string.len(s)
while ( string.find(whitespace, string.sub(s,startPos,startPos), 1, true) and startPos <= stringLen) do
startPos = startPos + 1
end
return startPos
end
--- Encodes a string to be JSON-compatible.
-- This just involves back-quoting inverted commas, back-quotes and newlines, I think ;-)
-- @param s The string to return as a JSON encoded (i.e. backquoted string)
-- @return The string appropriately escaped.
function encodeString(s)
s = string.gsub(s,'\\','\\\\')
s = string.gsub(s,'"','\\"')
s = string.gsub(s,"'","\\'")
s = string.gsub(s,'\n','\\n')
s = string.gsub(s,'\t','\\t')
return s
end
-- Determines whether the given Lua type is an array or a table / dictionary.
-- We consider any table an array if it has indexes 1..n for its n items, and no
-- other data in the table.
-- I think this method is currently a little 'flaky', but can't think of a good way around it yet...
-- @param t The table to evaluate as an array
-- @return boolean, number True if the table can be represented as an array, false otherwise. If true,
-- the second returned value is the maximum
-- number of indexed elements in the array.
function isArray(t)
-- Next we count all the elements, ensuring that any non-indexed elements are not-encodable
-- (with the possible exception of 'n')
local maxIndex = 0
for k,v in base.pairs(t) do
if (base.type(k)=='number' and math.floor(k)==k and 1<=k) then -- k,v is an indexed pair
if (not isEncodable(v)) then return false end -- All array elements must be encodable
maxIndex = math.max(maxIndex,k)
else
if (k=='n') then
if v ~= table.getn(t) then return false end -- False if n does not hold the number of elements
else -- Else of (k=='n')
if isEncodable(v) then return false end
end -- End of (k~='n')
end -- End of k,v not an indexed pair
end -- End of loop across all pairs
return true, maxIndex
end
--- Determines whether the given Lua object / table / variable can be JSON encoded. The only
-- types that are JSON encodable are: string, boolean, number, nil, table and json.null.
-- In this implementation, all other types are ignored.
-- @param o The object to examine.
-- @return boolean True if the object should be JSON encoded, false if it should be ignored.
function isEncodable(o)
local t = base.type(o)
return (t=='string' or t=='boolean' or t=='number' or t=='nil' or t=='table') or (t=='function' and o==null)
end

View File

@@ -1,34 +0,0 @@
local luaj = {}
local callJavaStaticMethod = LuaJavaBridge.callStaticMethod
local function checkArguments(args, sig)
if type(args) ~= "table" then args = {} end
if sig then return args, sig end
sig = {"("}
for i, v in ipairs(args) do
local t = type(v)
if t == "number" then
sig[#sig + 1] = "F"
elseif t == "boolean" then
sig[#sig + 1] = "Z"
elseif t == "function" then
sig[#sig + 1] = "I"
else
sig[#sig + 1] = "Ljava/lang/String;"
end
end
sig[#sig + 1] = ")V"
return args, table.concat(sig)
end
function luaj.callStaticMethod(className, methodName, args, sig)
local args, sig = checkArguments(args, sig)
--echoInfo("luaj.callStaticMethod(\"%s\",\n\t\"%s\",\n\targs,\n\t\"%s\"", className, methodName, sig)
return callJavaStaticMethod(className, methodName, args, sig)
end
return luaj

View File

@@ -1,28 +0,0 @@
local luaoc = {}
local callStaticMethod = LuaObjcBridge.callStaticMethod
function luaoc.callStaticMethod(className, methodName, args)
local ok, ret = callStaticMethod(className, methodName, args)
if not ok then
local msg = string.format("luaoc.callStaticMethod(\"%s\", \"%s\", \"%s\") - error: [%s] ",
className, methodName, tostring(args), tostring(ret))
if ret == -1 then
print(msg .. "INVALID PARAMETERS")
elseif ret == -2 then
print(msg .. "CLASS NOT FOUND")
elseif ret == -3 then
print(msg .. "METHOD NOT FOUND")
elseif ret == -4 then
print(msg .. "EXCEPTION OCCURRED")
elseif ret == -5 then
print(msg .. "INVALID METHOD SIGNATURE")
else
print(msg .. "UNKNOWN")
end
end
return ok, ret
end
return luaoc

View File

@@ -1,389 +0,0 @@
if nil == ccs then
return
end
if not json then
require "cocos.cocos2d.json"
end
require "cocos.cocostudio.StudioConstants"
function ccs.sendTriggerEvent(event)
local triggerObjArr = ccs.TriggerMng.getInstance():get(event)
if nil == triggerObjArr then
return
end
for i = 1, table.getn(triggerObjArr) do
local triObj = triggerObjArr[i]
if nil ~= triObj and triObj:detect() then
triObj:done()
end
end
end
function ccs.registerTriggerClass(className, createFunc)
ccs.TInfo.new(className,createFunc)
end
ccs.TInfo = class("TInfo")
ccs.TInfo._className = ""
ccs.TInfo._fun = nil
function ccs.TInfo:ctor(c,f)
-- @param {String|ccs.TInfo}c
-- @param {Function}f
if nil ~= f then
self._className = c
self._fun = f
else
self._className = c._className
self._fun = c._fun
end
ccs.ObjectFactory.getInstance():registerType(self)
end
ccs.ObjectFactory = class("ObjectFactory")
ccs.ObjectFactory._typeMap = nil
ccs.ObjectFactory._instance = nil
function ccs.ObjectFactory:ctor()
self._typeMap = {}
end
function ccs.ObjectFactory.getInstance()
if nil == ccs.ObjectFactory._instance then
ccs.ObjectFactory._instance = ccs.ObjectFactory.new()
end
return ccs.ObjectFactory._instance
end
function ccs.ObjectFactory.destroyInstance()
ccs.ObjectFactory._instance = nil
end
function ccs.ObjectFactory:createObject(classname)
local obj = nil
local t = self._typeMap[classname]
if nil ~= t then
obj = t._fun()
end
return obj
end
function ccs.ObjectFactory:registerType(t)
self._typeMap[t._className] = t
end
ccs.TriggerObj = class("TriggerObj")
ccs.TriggerObj._cons = {}
ccs.TriggerObj._acts = {}
ccs.TriggerObj._enable = false
ccs.TriggerObj._id = 0
ccs.TriggerObj._vInt = {}
function ccs.TriggerObj.extend(target)
local t = tolua.getpeer(target)
if not t then
t = {}
tolua.setpeer(target, t)
end
setmetatable(t, TriggerObj)
return target
end
function ccs.TriggerObj:ctor()
self:init()
end
function ccs.TriggerObj:init()
self._id = 0
self._enable = true
self._cons = {}
self._acts = {}
self._vInt = {}
end
function ccs.TriggerObj:detect()
if (not self._enable) or (table.getn(self._cons) == 0) then
return true
end
local ret = true
local obj = nil
for i = 1 , table.getn(self._cons) do
obj = self._cons[i]
if nil ~= obj and nil ~= obj.detect then
ret = ret and obj:detect()
end
end
return ret
end
function ccs.TriggerObj:done()
if (not self._enable) or (table.getn(self._acts) == 0) then
return
end
local obj = nil
for i = 1, table.getn(self._acts) do
obj = self._acts[i]
if nil ~= obj and obj.done then
obj:done()
end
end
end
function ccs.TriggerObj:removeAll()
local obj = nil
for i=1, table.getn(self._cons) do
obj = self._cons[i]
if nil ~= obj then
obj:removeAll()
end
end
self._cons = {}
for i=1, table.getn(self._acts) do
obj = self._acts[i]
if nil ~= obj then
obj:removeAll()
end
end
self._acts = {}
end
function ccs.TriggerObj:serialize(jsonValue)
self._id = jsonValue["id"]
local count = 0
--condition
local cons = jsonValue["conditions"]
if nil ~= cons then
count = table.getn(cons)
for i = 1, count do
local subDict = cons[i]
local className = subDict["classname"]
if nil ~= className then
local obj = ccs.ObjectFactory.getInstance():createObject(className)
assert(nil ~= obj, string.format("class named %s can not implement!",className))
obj:serialize(subDict)
obj:init()
table.insert(self._cons, obj)
end
end
end
local actions = jsonValue["actions"]
if nil ~= actions then
count = table.getn(actions)
for i = 1,count do
local subAction = actions[i]
local className = subAction["classname"]
if nil ~= className then
local act = ccs.ObjectFactory.getInstance():createObject(className)
assert(nil ~= act ,string.format("class named %s can not implement!",className))
act:serialize(subAction)
act:init()
table.insert(self._acts,act)
end
end
end
local events = jsonValue["events"]
if nil ~= events then
count = table.getn(events)
for i = 1, count do
local subEveent = events[i]
local eventID = subEveent["id"]
if eventID >= 0 then
table.insert(self._vInt,eventID)
end
end
end
end
function ccs.TriggerObj:getId()
return self._id
end
function ccs.TriggerObj:setEnable(enable)
self._enable = enable
end
function ccs.TriggerObj:getEvents()
return self._vInt
end
ccs.TriggerMng = class("TriggerMng")
ccs.TriggerMng._eventTriggers = nil
ccs.TriggerMng._triggerObjs = nil
ccs.TriggerMng._movementDispatches = nil
ccs.TriggerMng._instance = nil
function ccs.TriggerMng:ctor()
self._triggerObjs = {}
self._movementDispatches = {}
self._eventTriggers = {}
end
function ccs.TriggerMng.getInstance()
if ccs.TriggerMng._instance == nil then
ccs.TriggerMng._instance = ccs.TriggerMng.new()
end
return ccs.TriggerMng._instance
end
function ccs.TriggerMng.destroyInstance()
if ccs.TriggerMng._instance ~= nil then
ccs.TriggerMng._instance:removeAll()
ccs.TriggerMng._instance = nil
end
end
function ccs.TriggerMng:triggerMngVersion()
return "1.0.0.0"
end
function ccs.TriggerMng:parse(jsonStr)
local parseTable = json.decode(jsonStr,1)
if nil == parseTable then
return
end
local count = table.getn(parseTable)
for i = 1, count do
local subDict = parseTable[i]
local triggerObj = ccs.TriggerObj.new()
triggerObj:serialize(subDict)
local events = triggerObj:getEvents()
for j = 1, table.getn(events) do
local event = events[j]
self:add(event, triggerObj)
end
self._triggerObjs[triggerObj:getId()] = triggerObj
end
end
function ccs.TriggerMng:get(event)
return self._eventTriggers[event]
end
function ccs.TriggerMng:getTriggerObj(id)
return self._triggerObjs[id]
end
function ccs.TriggerMng:add(event,triggerObj)
local eventTriggers = self._eventTriggers[event]
if nil == eventTriggers then
eventTriggers = {}
end
local exist = false
for i = 1, table.getn(eventTriggers) do
if eventTriggers[i] == triggers then
exist = true
break
end
end
if not exist then
table.insert(eventTriggers,triggerObj)
self._eventTriggers[event] = eventTriggers
end
end
function ccs.TriggerMng:removeAll( )
for k in pairs(self._eventTriggers) do
local triObjArr = self._eventTriggers[k]
for j = 1, table.getn(triObjArr) do
local obj = triObjArr[j]
obj:removeAll()
end
end
self._eventTriggers = {}
end
function ccs.TriggerMng:remove(event, obj)
if nil ~= obj then
return self:removeObjByEvent(event, obj)
end
assert(event >= 0,"event must be larger than 0")
if nil == self._eventTriggers then
return false
end
local triObjects = self._eventTriggers[event]
if nil == triObjects then
return false
end
for i = 1, table.getn(triObjects) do
local triObject = triggers[i]
if nil ~= triObject then
triObject:remvoeAll()
end
end
self._eventTriggers[event] = nil
return true
end
function ccs.TriggerMng:removeObjByEvent(event, obj)
assert(event >= 0,"event must be larger than 0")
if nil == self._eventTriggers then
return false
end
local triObjects = self._eventTriggers[event]
if nil == triObjects then
return false
end
for i = 1,table.getn(triObjects) do
local triObject = triObjects[i]
if nil ~= triObject and triObject == obj then
triObject:remvoeAll()
table.remove(triObjects, i)
return true
end
end
end
function ccs.TriggerMng:removeTriggerObj(id)
local obj = self.getTriggerObj(id)
if nil == obj then
return false
end
local events = obj:getEvents()
for i = 1, table.getn(events) do
self:remove(events[i],obj)
end
return true
end
function ccs.TriggerMng:isEmpty()
return (not (nil == self._eventTriggers)) or table.getn(self._eventTriggers) <= 0
end
function __onParseConfig(configType,jasonStr)
if configType == cc.ConfigType.COCOSTUDIO then
ccs.TriggerMng.getInstance():parse(jasonStr)
end
end
function ccs.AnimationInfo(_name, _startIndex, _endIndex)
assert(nil ~= _name and type(_name) == "string" and _startIndex ~= nil and type(_startIndex) == "number" and _endIndex ~= nil and type(_endIndex) == "number", "ccs.AnimationInfo() - invalid input parameters")
return { name = _name, startIndex = _startIndex, endIndex = _endIndex}
end

View File

@@ -1,15 +0,0 @@
if nil == ccs then
return
end
ccs.MovementEventType = {
start = 0,
complete = 1,
loopComplete = 2,
}
ccs.InnerActionType = {
LoopAction = 0,
NoLoopAction = 1,
SingleFrame = 2,
}

View File

@@ -1,157 +0,0 @@
local Event = class("Event")
local EXPORTED_METHODS = {
"addEventListener",
"dispatchEvent",
"removeEventListener",
"removeEventListenersByTag",
"removeEventListenersByEvent",
"removeAllEventListeners",
"hasEventListener",
"dumpAllEventListeners",
}
function Event:init_()
self.target_ = nil
self.listeners_ = {}
self.nextListenerHandleIndex_ = 0
end
function Event:bind(target)
self:init_()
cc.setmethods(target, self, EXPORTED_METHODS)
self.target_ = target
end
function Event:unbind(target)
cc.unsetmethods(target, EXPORTED_METHODS)
self:init_()
end
function Event:on(eventName, listener, tag)
assert(type(eventName) == "string" and eventName ~= "",
"Event:addEventListener() - invalid eventName")
eventName = string.upper(eventName)
if self.listeners_[eventName] == nil then
self.listeners_[eventName] = {}
end
self.nextListenerHandleIndex_ = self.nextListenerHandleIndex_ + 1
local handle = tostring(self.nextListenerHandleIndex_)
tag = tag or ""
self.listeners_[eventName][handle] = {listener, tag}
if DEBUG > 1 then
printInfo("%s [Event] addEventListener() - event: %s, handle: %s, tag: \"%s\"",
tostring(self.target_), eventName, handle, tostring(tag))
end
return self.target_, handle
end
Event.addEventListener = Event.on
function Event:dispatchEvent(event)
event.name = string.upper(tostring(event.name))
local eventName = event.name
if DEBUG > 1 then
printInfo("%s [Event] dispatchEvent() - event %s", tostring(self.target_), eventName)
end
if self.listeners_[eventName] == nil then return end
event.target = self.target_
event.stop_ = false
event.stop = function(self)
self.stop_ = true
end
for handle, listener in pairs(self.listeners_[eventName]) do
if DEBUG > 1 then
printInfo("%s [Event] dispatchEvent() - dispatching event %s to listener %s", tostring(self.target_), eventName, handle)
end
-- listener[1] = listener
-- listener[2] = tag
event.tag = listener[2]
listener[1](event)
if event.stop_ then
if DEBUG > 1 then
printInfo("%s [Event] dispatchEvent() - break dispatching for event %s", tostring(self.target_), eventName)
end
break
end
end
return self.target_
end
function Event:removeEventListener(handleToRemove)
for eventName, listenersForEvent in pairs(self.listeners_) do
for handle, _ in pairs(listenersForEvent) do
if handle == handleToRemove then
listenersForEvent[handle] = nil
if DEBUG > 1 then
printInfo("%s [Event] removeEventListener() - remove listener [%s] for event %s", tostring(self.target_), handle, eventName)
end
return self.target_
end
end
end
return self.target_
end
function Event:removeEventListenersByTag(tagToRemove)
for eventName, listenersForEvent in pairs(self.listeners_) do
for handle, listener in pairs(listenersForEvent) do
-- listener[1] = listener
-- listener[2] = tag
if listener[2] == tagToRemove then
listenersForEvent[handle] = nil
if DEBUG > 1 then
printInfo("%s [Event] removeEventListener() - remove listener [%s] for event %s", tostring(self.target_), handle, eventName)
end
end
end
end
return self.target_
end
function Event:removeEventListenersByEvent(eventName)
self.listeners_[string.upper(eventName)] = nil
if DEBUG > 1 then
printInfo("%s [Event] removeAllEventListenersForEvent() - remove all listeners for event %s", tostring(self.target_), eventName)
end
return self.target_
end
function Event:removeAllEventListeners()
self.listeners_ = {}
if DEBUG > 1 then
printInfo("%s [Event] removeAllEventListeners() - remove all listeners", tostring(self.target_))
end
return self.target_
end
function Event:hasEventListener(eventName)
eventName = string.upper(tostring(eventName))
local t = self.listeners_[eventName]
for _, __ in pairs(t) do
return true
end
return false
end
function Event:dumpAllEventListeners()
print("---- Event:dumpAllEventListeners() ----")
for name, listeners in pairs(self.listeners_) do
printf("-- event: %s", name)
for handle, listener in pairs(listeners) do
printf("-- listener: %s, handle: %s", tostring(listener[1]), tostring(handle))
end
end
return self.target_
end
return Event

View File

@@ -1,107 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local device = {}
device.platform = "unknown"
device.model = "unknown"
local app = cc.Application:getInstance()
local target = app:getTargetPlatform()
if target == cc.PLATFORM_OS_WINDOWS then
device.platform = "windows"
elseif target == cc.PLATFORM_OS_MAC then
device.platform = "mac"
elseif target == cc.PLATFORM_OS_ANDROID then
device.platform = "android"
elseif target == cc.PLATFORM_OS_IPHONE or target == cc.PLATFORM_OS_IPAD then
device.platform = "ios"
local director = cc.Director:getInstance()
local view = director:getOpenGLView()
local framesize = view:getFrameSize()
local w, h = framesize.width, framesize.height
if w == 640 and h == 960 then
device.model = "iphone 4"
elseif w == 640 and h == 1136 then
device.model = "iphone 5"
elseif w == 750 and h == 1334 then
device.model = "iphone 6"
elseif w == 1242 and h == 2208 then
device.model = "iphone 6 plus"
elseif w == 768 and h == 1024 then
device.model = "ipad"
elseif w == 1536 and h == 2048 then
device.model = "ipad retina"
end
elseif target == cc.PLATFORM_OS_WINRT then
device.platform = "winrt"
elseif target == cc.PLATFORM_OS_WP8 then
device.platform = "wp8"
end
local language_ = app:getCurrentLanguage()
if language_ == cc.LANGUAGE_CHINESE then
language_ = "cn"
elseif language_ == cc.LANGUAGE_FRENCH then
language_ = "fr"
elseif language_ == cc.LANGUAGE_ITALIAN then
language_ = "it"
elseif language_ == cc.LANGUAGE_GERMAN then
language_ = "gr"
elseif language_ == cc.LANGUAGE_SPANISH then
language_ = "sp"
elseif language_ == cc.LANGUAGE_RUSSIAN then
language_ = "ru"
elseif language_ == cc.LANGUAGE_KOREAN then
language_ = "kr"
elseif language_ == cc.LANGUAGE_JAPANESE then
language_ = "jp"
elseif language_ == cc.LANGUAGE_HUNGARIAN then
language_ = "hu"
elseif language_ == cc.LANGUAGE_PORTUGUESE then
language_ = "pt"
elseif language_ == cc.LANGUAGE_ARABIC then
language_ = "ar"
else
language_ = "en"
end
device.language = language_
device.writablePath = cc.FileUtils:getInstance():getWritablePath()
device.directorySeparator = "/"
device.pathSeparator = ":"
if device.platform == "windows" then
device.directorySeparator = "\\"
device.pathSeparator = ";"
end
printInfo("# device.platform = " .. device.platform)
printInfo("# device.model = " .. device.model)
printInfo("# device.language = " .. device.language)
printInfo("# device.writablePath = " .. device.writablePath)
printInfo("# device.directorySeparator = " .. device.directorySeparator)
printInfo("# device.pathSeparator = " .. device.pathSeparator)
printInfo("#")
return device

View File

@@ -1,542 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local display = {}
local director = cc.Director:getInstance()
local view = director:getOpenGLView()
if not view then
local width = 960
local height = 640
if CC_DESIGN_RESOLUTION then
if CC_DESIGN_RESOLUTION.width then
width = CC_DESIGN_RESOLUTION.width
end
if CC_DESIGN_RESOLUTION.height then
height = CC_DESIGN_RESOLUTION.height
end
end
view = cc.GLViewImpl:createWithRect("Cocos2d-Lua", cc.rect(0, 0, width, height))
director:setOpenGLView(view)
end
local framesize = view:getFrameSize()
local textureCache = director:getTextureCache()
local spriteFrameCache = cc.SpriteFrameCache:getInstance()
local animationCache = cc.AnimationCache:getInstance()
-- auto scale
local function checkResolution(r)
r.width = checknumber(r.width)
r.height = checknumber(r.height)
r.autoscale = string.upper(r.autoscale)
assert(r.width > 0 and r.height > 0,
string.format("display - invalid design resolution size %d, %d", r.width, r.height))
end
local function setDesignResolution(r, framesize)
if r.autoscale == "FILL_ALL" then
view:setDesignResolutionSize(framesize.width, framesize.height, cc.ResolutionPolicy.FILL_ALL)
else
local scaleX, scaleY = framesize.width / r.width, framesize.height / r.height
local width, height = framesize.width, framesize.height
if r.autoscale == "FIXED_WIDTH" then
width = framesize.width / scaleX
height = framesize.height / scaleX
view:setDesignResolutionSize(width, height, cc.ResolutionPolicy.NO_BORDER)
elseif r.autoscale == "FIXED_HEIGHT" then
width = framesize.width / scaleY
height = framesize.height / scaleY
view:setDesignResolutionSize(width, height, cc.ResolutionPolicy.NO_BORDER)
elseif r.autoscale == "EXACT_FIT" then
view:setDesignResolutionSize(r.width, r.height, cc.ResolutionPolicy.EXACT_FIT)
elseif r.autoscale == "NO_BORDER" then
view:setDesignResolutionSize(r.width, r.height, cc.ResolutionPolicy.NO_BORDER)
elseif r.autoscale == "SHOW_ALL" then
view:setDesignResolutionSize(r.width, r.height, cc.ResolutionPolicy.SHOW_ALL)
else
printError(string.format("display - invalid r.autoscale \"%s\"", r.autoscale))
end
end
end
local function setConstants()
local sizeInPixels = view:getFrameSize()
display.sizeInPixels = {width = sizeInPixels.width, height = sizeInPixels.height}
local viewsize = director:getWinSize()
display.contentScaleFactor = director:getContentScaleFactor()
display.size = {width = viewsize.width, height = viewsize.height}
display.width = display.size.width
display.height = display.size.height
display.cx = display.width / 2
display.cy = display.height / 2
display.c_left = -display.width / 2
display.c_right = display.width / 2
display.c_top = display.height / 2
display.c_bottom = -display.height / 2
display.left = 0
display.right = display.width
display.top = display.height
display.bottom = 0
display.center = cc.p(display.cx, display.cy)
display.left_top = cc.p(display.left, display.top)
display.left_bottom = cc.p(display.left, display.bottom)
display.left_center = cc.p(display.left, display.cy)
display.right_top = cc.p(display.right, display.top)
display.right_bottom = cc.p(display.right, display.bottom)
display.right_center = cc.p(display.right, display.cy)
display.top_center = cc.p(display.cx, display.top)
display.top_bottom = cc.p(display.cx, display.bottom)
printInfo(string.format("# display.sizeInPixels = {width = %0.2f, height = %0.2f}", display.sizeInPixels.width, display.sizeInPixels.height))
printInfo(string.format("# display.size = {width = %0.2f, height = %0.2f}", display.size.width, display.size.height))
printInfo(string.format("# display.contentScaleFactor = %0.2f", display.contentScaleFactor))
printInfo(string.format("# display.width = %0.2f", display.width))
printInfo(string.format("# display.height = %0.2f", display.height))
printInfo(string.format("# display.cx = %0.2f", display.cx))
printInfo(string.format("# display.cy = %0.2f", display.cy))
printInfo(string.format("# display.left = %0.2f", display.left))
printInfo(string.format("# display.right = %0.2f", display.right))
printInfo(string.format("# display.top = %0.2f", display.top))
printInfo(string.format("# display.bottom = %0.2f", display.bottom))
printInfo(string.format("# display.c_left = %0.2f", display.c_left))
printInfo(string.format("# display.c_right = %0.2f", display.c_right))
printInfo(string.format("# display.c_top = %0.2f", display.c_top))
printInfo(string.format("# display.c_bottom = %0.2f", display.c_bottom))
printInfo(string.format("# display.center = {x = %0.2f, y = %0.2f}", display.center.x, display.center.y))
printInfo(string.format("# display.left_top = {x = %0.2f, y = %0.2f}", display.left_top.x, display.left_top.y))
printInfo(string.format("# display.left_bottom = {x = %0.2f, y = %0.2f}", display.left_bottom.x, display.left_bottom.y))
printInfo(string.format("# display.left_center = {x = %0.2f, y = %0.2f}", display.left_center.x, display.left_center.y))
printInfo(string.format("# display.right_top = {x = %0.2f, y = %0.2f}", display.right_top.x, display.right_top.y))
printInfo(string.format("# display.right_bottom = {x = %0.2f, y = %0.2f}", display.right_bottom.x, display.right_bottom.y))
printInfo(string.format("# display.right_center = {x = %0.2f, y = %0.2f}", display.right_center.x, display.right_center.y))
printInfo(string.format("# display.top_center = {x = %0.2f, y = %0.2f}", display.top_center.x, display.top_center.y))
printInfo(string.format("# display.top_bottom = {x = %0.2f, y = %0.2f}", display.top_bottom.x, display.top_bottom.y))
printInfo("#")
end
function display.setAutoScale(configs)
if type(configs) ~= "table" then return end
checkResolution(configs)
if type(configs.callback) == "function" then
local c = configs.callback(framesize)
for k, v in pairs(c or {}) do
configs[k] = v
end
checkResolution(configs)
end
setDesignResolution(configs, framesize)
printInfo(string.format("# design resolution size = {width = %0.2f, height = %0.2f}", configs.width, configs.height))
printInfo(string.format("# design resolution autoscale = %s", configs.autoscale))
setConstants()
end
if type(CC_DESIGN_RESOLUTION) == "table" then
display.setAutoScale(CC_DESIGN_RESOLUTION)
end
display.COLOR_WHITE = cc.c3b(255, 255, 255)
display.COLOR_BLACK = cc.c3b(0, 0, 0)
display.COLOR_RED = cc.c3b(255, 0, 0)
display.COLOR_GREEN = cc.c3b(0, 255, 0)
display.COLOR_BLUE = cc.c3b(0, 0, 255)
display.AUTO_SIZE = 0
display.FIXED_SIZE = 1
display.LEFT_TO_RIGHT = 0
display.RIGHT_TO_LEFT = 1
display.TOP_TO_BOTTOM = 2
display.BOTTOM_TO_TOP = 3
display.CENTER = cc.p(0.5, 0.5)
display.LEFT_TOP = cc.p(0, 1)
display.LEFT_BOTTOM = cc.p(0, 0)
display.LEFT_CENTER = cc.p(0, 0.5)
display.RIGHT_TOP = cc.p(1, 1)
display.RIGHT_BOTTOM = cc.p(1, 0)
display.RIGHT_CENTER = cc.p(1, 0.5)
display.CENTER_TOP = cc.p(0.5, 1)
display.CENTER_BOTTOM = cc.p(0.5, 0)
display.SCENE_TRANSITIONS = {
CROSSFADE = {cc.TransitionCrossFade},
FADE = {cc.TransitionFade, cc.c3b(0, 0, 0)},
FADEBL = {cc.TransitionFadeBL},
FADEDOWN = {cc.TransitionFadeDown},
FADETR = {cc.TransitionFadeTR},
FADEUP = {cc.TransitionFadeUp},
FLIPANGULAR = {cc.TransitionFlipAngular, cc.TRANSITION_ORIENTATION_LEFT_OVER},
FLIPX = {cc.TransitionFlipX, cc.TRANSITION_ORIENTATION_LEFT_OVER},
FLIPY = {cc.TransitionFlipY, cc.TRANSITION_ORIENTATION_UP_OVER},
JUMPZOOM = {cc.TransitionJumpZoom},
MOVEINB = {cc.TransitionMoveInB},
MOVEINL = {cc.TransitionMoveInL},
MOVEINR = {cc.TransitionMoveInR},
MOVEINT = {cc.TransitionMoveInT},
PAGETURN = {cc.TransitionPageTurn, false},
ROTOZOOM = {cc.TransitionRotoZoom},
SHRINKGROW = {cc.TransitionShrinkGrow},
SLIDEINB = {cc.TransitionSlideInB},
SLIDEINL = {cc.TransitionSlideInL},
SLIDEINR = {cc.TransitionSlideInR},
SLIDEINT = {cc.TransitionSlideInT},
SPLITCOLS = {cc.TransitionSplitCols},
SPLITROWS = {cc.TransitionSplitRows},
TURNOFFTILES = {cc.TransitionTurnOffTiles},
ZOOMFLIPANGULAR = {cc.TransitionZoomFlipAngular},
ZOOMFLIPX = {cc.TransitionZoomFlipX, cc.TRANSITION_ORIENTATION_LEFT_OVER},
ZOOMFLIPY = {cc.TransitionZoomFlipY, cc.TRANSITION_ORIENTATION_UP_OVER},
}
display.TEXTURES_PIXEL_FORMAT = {}
display.DEFAULT_TTF_FONT = "Arial"
display.DEFAULT_TTF_FONT_SIZE = 32
local PARAMS_EMPTY = {}
local RECT_ZERO = cc.rect(0, 0, 0, 0)
local sceneIndex = 0
function display.newScene(name, params)
params = params or PARAMS_EMPTY
sceneIndex = sceneIndex + 1
local scene
if not params.physics then
scene = cc.Scene:create()
else
scene = cc.Scene:createWithPhysics()
end
scene.name_ = string.format("%s:%d", name or "<unknown-scene>", sceneIndex)
if params.transition then
scene = display.wrapSceneWithTransition(scene, params.transition, params.time, params.more)
end
return scene
end
function display.wrapScene(scene, transition, time, more)
local key = string.upper(tostring(transition))
if key == "RANDOM" then
local keys = table.keys(display.SCENE_TRANSITIONS)
key = keys[math.random(1, #keys)]
end
if display.SCENE_TRANSITIONS[key] then
local t = display.SCENE_TRANSITIONS[key]
local cls = t[1]
time = time or 0.2
more = more or t[2]
if more ~= nil then
scene = cls:create(time, scene, more)
else
scene = cls:create(time, scene)
end
else
error(string.format("display.wrapScene() - invalid transition %s", tostring(transition)))
end
return scene
end
function display.runScene(newScene, transition, time, more)
if director:getRunningScene() then
if transition then
newScene = display.wrapScene(newScene, transition, time, more)
end
director:replaceScene(newScene)
else
director:runWithScene(newScene)
end
end
function display.getRunningScene()
return director:getRunningScene()
end
function display.newNode()
return cc.Node:create()
end
function display.newLayer(...)
local params = {...}
local c = #params
local layer
if c == 0 then
-- /** creates a fullscreen black layer */
-- static Layer *create();
layer = cc.Layer:create()
elseif c == 1 then
-- /** creates a Layer with color. Width and height are the window size. */
-- static LayerColor * create(const Color4B& color);
layer = cc.LayerColor:create(cc.convertColor(params[1], "4b"))
elseif c == 2 then
-- /** creates a Layer with color, width and height in Points */
-- static LayerColor * create(const Color4B& color, const Size& size);
--
-- /** Creates a full-screen Layer with a gradient between start and end. */
-- static LayerGradient* create(const Color4B& start, const Color4B& end);
local color1 = cc.convertColor(params[1], "4b")
local p2 = params[2]
assert(type(p2) == "table" and (p2.width or p2.r), "display.newLayer() - invalid paramerter 2")
if p2.r then
layer = cc.LayerGradient:create(color1, cc.convertColor(p2, "4b"))
else
layer = cc.LayerColor:create(color1, p2.width, p2.height)
end
elseif c == 3 then
-- /** creates a Layer with color, width and height in Points */
-- static LayerColor * create(const Color4B& color, GLfloat width, GLfloat height);
--
-- /** Creates a full-screen Layer with a gradient between start and end in the direction of v. */
-- static LayerGradient* create(const Color4B& start, const Color4B& end, const Vec2& v);
local color1 = cc.convertColor(params[1], "4b")
local p2 = params[2]
local p2type = type(p2)
if p2type == "table" then
layer = cc.LayerGradient:create(color1, cc.convertColor(p2, "4b"), params[3])
else
layer = cc.LayerColor:create(color1, p2, params[3])
end
end
return layer
end
function display.newSprite(source, x, y, params)
local spriteClass = cc.Sprite
local scale9 = false
if type(x) == "table" and not x.x then
-- x is params
params = x
x = nil
y = nil
end
local params = params or PARAMS_EMPTY
if params.scale9 or params.capInsets then
spriteClass = ccui.Scale9Sprite
scale9 = true
params.capInsets = params.capInsets or RECT_ZERO
params.rect = params.rect or RECT_ZERO
end
local sprite
while true do
-- create sprite
if not source then
sprite = spriteClass:create()
break
end
local sourceType = type(source)
if sourceType == "string" then
if string.byte(source) == 35 then -- first char is #
-- create sprite from spriteFrame
if not scale9 then
sprite = spriteClass:createWithSpriteFrameName(string.sub(source, 2))
else
sprite = spriteClass:createWithSpriteFrameName(string.sub(source, 2), params.capInsets)
end
break
end
-- create sprite from image file
if display.TEXTURES_PIXEL_FORMAT[source] then
cc.Texture2D:setDefaultAlphaPixelFormat(display.TEXTURES_PIXEL_FORMAT[source])
end
if not scale9 then
sprite = spriteClass:create(source)
else
sprite = spriteClass:create(source, params.rect, params.capInsets)
end
if display.TEXTURES_PIXEL_FORMAT[source] then
cc.Texture2D:setDefaultAlphaPixelFormat(cc.TEXTURE2_D_PIXEL_FORMAT_BGR_A8888)
end
break
elseif sourceType ~= "userdata" then
error(string.format("display.newSprite() - invalid source type \"%s\"", sourceType), 0)
else
sourceType = tolua.type(source)
if sourceType == "cc.SpriteFrame" then
if not scale9 then
sprite = spriteClass:createWithSpriteFrame(source)
else
sprite = spriteClass:createWithSpriteFrame(source, params.capInsets)
end
elseif sourceType == "cc.Texture2D" then
sprite = spriteClass:createWithTexture(source)
else
error(string.format("display.newSprite() - invalid source type \"%s\"", sourceType), 0)
end
end
break
end
if sprite then
if x and y then sprite:setPosition(x, y) end
if params.size then sprite:setContentSize(params.size) end
else
error(string.format("display.newSprite() - create sprite failure, source \"%s\"", tostring(source)), 0)
end
return sprite
end
function display.newSpriteFrame(source, ...)
local frame
if type(source) == "string" then
if string.byte(source) == 35 then -- first char is #
source = string.sub(source, 2)
end
frame = spriteFrameCache:getSpriteFrame(source)
if not frame then
error(string.format("display.newSpriteFrame() - invalid frame name \"%s\"", tostring(source)), 0)
end
elseif tolua.type(source) == "cc.Texture2D" then
frame = cc.SpriteFrame:createWithTexture(source, ...)
else
error("display.newSpriteFrame() - invalid parameters", 0)
end
return frame
end
function display.newFrames(pattern, begin, length, isReversed)
local frames = {}
local step = 1
local last = begin + length - 1
if isReversed then
last, begin = begin, last
step = -1
end
for index = begin, last, step do
local frameName = string.format(pattern, index)
local frame = spriteFrameCache:getSpriteFrame(frameName)
if not frame then
error(string.format("display.newFrames() - invalid frame name %s", tostring(frameName)), 0)
end
frames[#frames + 1] = frame
end
return frames
end
local function newAnimation(frames, time)
local count = #frames
assert(count > 0, "display.newAnimation() - invalid frames")
time = time or 1.0 / count
return cc.Animation:createWithSpriteFrames(frames, time),
cc.Sprite:createWithSpriteFrame(frames[1])
end
function display.newAnimation(...)
local params = {...}
local c = #params
if c == 2 then
-- frames, time
return newAnimation(params[1], params[2])
elseif c == 4 then
-- pattern, begin, length, time
local frames = display.newFrames(params[1], params[2], params[3])
return newAnimation(frames, params[4])
elseif c == 5 then
-- pattern, begin, length, isReversed, time
local frames = display.newFrames(params[1], params[2], params[3], params[4])
return newAnimation(frames, params[5])
else
error("display.newAnimation() - invalid parameters")
end
end
function display.loadImage(imageFilename, callback)
if not callback then
return textureCache:addImage(imageFilename)
else
textureCache:addImageAsync(imageFilename, callback)
end
end
local fileUtils = cc.FileUtils:getInstance()
function display.getImage(imageFilename)
local fullpath = fileUtils:fullPathForFilename(imageFilename)
return textureCache:getTextureForKey(fullpath)
end
function display.removeImage(imageFilename)
textureCache:removeTextureForKey(imageFilename)
end
function display.loadSpriteFrames(dataFilename, imageFilename, callback)
if display.TEXTURES_PIXEL_FORMAT[imageFilename] then
cc.Texture2D:setDefaultAlphaPixelFormat(display.TEXTURES_PIXEL_FORMAT[imageFilename])
end
if not callback then
spriteFrameCache:addSpriteFrames(dataFilename, imageFilename)
else
spriteFrameCache:addSpriteFramesAsync(dataFilename, imageFilename, callback)
end
if display.TEXTURES_PIXEL_FORMAT[imageFilename] then
cc.Texture2D:setDefaultAlphaPixelFormat(cc.TEXTURE2_D_PIXEL_FORMAT_BGR_A8888)
end
end
function display.removeSpriteFrames(dataFilename, imageFilename)
spriteFrameCache:removeSpriteFramesFromFile(dataFilename)
if imageFilename then
display.removeImage(imageFilename)
end
end
function display.removeSpriteFrame(imageFilename)
spriteFrameCache:removeSpriteFrameByName(imageFilename)
end
function display.setTexturePixelFormat(imageFilename, format)
display.TEXTURES_PIXEL_FORMAT[imageFilename] = format
end
function display.setAnimationCache(name, animation)
animationCache:addAnimation(animation, name)
end
function display.getAnimationCache(name)
return animationCache:getAnimation(name)
end
function display.removeAnimationCache(name)
animationCache:removeAnimation(name)
end
function display.removeUnusedSpriteFrames()
spriteFrameCache:removeUnusedSpriteFrames()
textureCache:removeUnusedTextures()
end
return display

View File

@@ -1,228 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local Node = cc.Node
function Node:add(child, zorder, tag)
if tag then
self:addChild(child, zorder, tag)
elseif zorder then
self:addChild(child, zorder)
else
self:addChild(child)
end
return self
end
function Node:addTo(parent, zorder, tag)
if tag then
parent:addChild(self, zorder, tag)
elseif zorder then
parent:addChild(self, zorder)
else
parent:addChild(self)
end
return self
end
function Node:removeSelf()
self:removeFromParent()
return self
end
function Node:align(anchorPoint, x, y)
self:setAnchorPoint(anchorPoint)
return self:move(x, y)
end
function Node:show()
self:setVisible(true)
return self
end
function Node:hide()
self:setVisible(false)
return self
end
function Node:move(x, y)
if y then
self:setPosition(x, y)
else
self:setPosition(x)
end
return self
end
function Node:moveTo(args)
transition.moveTo(self, args)
return self
end
function Node:moveBy(args)
transition.moveBy(self, args)
return self
end
function Node:fadeIn(args)
transition.fadeIn(self, args)
return self
end
function Node:fadeOut(args)
transition.fadeOut(self, args)
return self
end
function Node:fadeTo(args)
transition.fadeTo(self, args)
return self
end
function Node:rotate(rotation)
self:setRotation(rotation)
return self
end
function Node:rotateTo(args)
transition.rotateTo(self, args)
return self
end
function Node:rotateBy(args)
transition.rotateBy(self, args)
return self
end
function Node:scaleTo(args)
transition.scaleTo(self, args)
return self
end
function Node:onUpdate(callback)
self:scheduleUpdateWithPriorityLua(callback, 0)
return self
end
Node.scheduleUpdate = Node.onUpdate
function Node:onNodeEvent(eventName, callback)
if "enter" == eventName then
self.onEnterCallback_ = callback
elseif "exit" == eventName then
self.onExitCallback_ = callback
elseif "enterTransitionFinish" == eventName then
self.onEnterTransitionFinishCallback_ = callback
elseif "exitTransitionStart" == eventName then
self.onExitTransitionStartCallback_ = callback
elseif "cleanup" == eventName then
self.onCleanupCallback_ = callback
end
self:enableNodeEvents()
end
function Node:enableNodeEvents()
if self.isNodeEventEnabled_ then
return self
end
self:registerScriptHandler(function(state)
if state == "enter" then
self:onEnter_()
elseif state == "exit" then
self:onExit_()
elseif state == "enterTransitionFinish" then
self:onEnterTransitionFinish_()
elseif state == "exitTransitionStart" then
self:onExitTransitionStart_()
elseif state == "cleanup" then
self:onCleanup_()
end
end)
self.isNodeEventEnabled_ = true
return self
end
function Node:disableNodeEvents()
self:unregisterScriptHandler()
self.isNodeEventEnabled_ = false
return self
end
function Node:onEnter()
end
function Node:onExit()
end
function Node:onEnterTransitionFinish()
end
function Node:onExitTransitionStart()
end
function Node:onCleanup()
end
function Node:onEnter_()
self:onEnter()
if not self.onEnterCallback_ then
return
end
self:onEnterCallback_()
end
function Node:onExit_()
self:onExit()
if not self.onExitCallback_ then
return
end
self:onExitCallback_()
end
function Node:onEnterTransitionFinish_()
self:onEnterTransitionFinish()
if not self.onEnterTransitionFinishCallback_ then
return
end
self:onEnterTransitionFinishCallback_()
end
function Node:onExitTransitionStart_()
self:onExitTransitionStart()
if not self.onExitTransitionStartCallback_ then
return
end
self:onExitTransitionStartCallback_()
end
function Node:onCleanup_()
self:onCleanup()
if not self.onCleanupCallback_ then
return
end
self:onCleanupCallback_()
end

View File

@@ -1,67 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local Sprite = cc.Sprite
function Sprite:playAnimationOnce(animation, args)
local actions = {}
local showDelay = args.showDelay
if showDelay then
self:setVisible(false)
actions[#actions + 1] = cc.DelayTime:create(showDelay)
actions[#actions + 1] = cc.Show:create()
end
local delay = args.delay or 0
if delay > 0 then
actions[#actions + 1] = cc.DelayTime:create(delay)
end
actions[#actions + 1] = cc.Animate:create(animation)
if args.removeSelf then
actions[#actions + 1] = cc.RemoveSelf:create()
end
if args.onComplete then
actions[#actions + 1] = cc.CallFunc:create(args.onComplete)
end
local action
if #actions > 1 then
action = cc.Sequence:create(actions)
else
action = actions[1]
end
self:runAction(action)
return action
end
function Sprite:playAnimationForever(animation)
local animate = cc.Animate:create(animation)
local action = cc.RepeatForever:create(animate)
self:runAction(action)
return action
end

View File

@@ -1,40 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local CheckBox = ccui.CheckBox
function CheckBox:onEvent(callback)
self:addEventListener(function(sender, eventType)
local event = {}
if eventType == 0 then
event.name = "selected"
else
event.name = "unselected"
end
event.target = sender
callback(event)
end)
return self
end

View File

@@ -1,41 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local EditBox = ccui.EditBox
function EditBox:onEditHandler(callback)
self:registerScriptEditBoxHandler(function(name, sender)
local event = {}
event.name = name
event.target = sender
callback(event)
end)
return self
end
function EditBox:removeEditHandler()
self:unregisterScriptEditBoxHandler()
return self
end

View File

@@ -1,72 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local ListView = ccui.ListView
function ListView:onEvent(callback)
self:addEventListener(function(sender, eventType)
local event = {}
if eventType == 0 then
event.name = "ON_SELECTED_ITEM_START"
else
event.name = "ON_SELECTED_ITEM_END"
end
event.target = sender
callback(event)
end)
return self
end
function ListView:onScroll(callback)
self:addScrollViewEventListener(function(sender, eventType)
local event = {}
if eventType == 0 then
event.name = "SCROLL_TO_TOP"
elseif eventType == 1 then
event.name = "SCROLL_TO_BOTTOM"
elseif eventType == 2 then
event.name = "SCROLL_TO_LEFT"
elseif eventType == 3 then
event.name = "SCROLL_TO_RIGHT"
elseif eventType == 4 then
event.name = "SCROLLING"
elseif eventType == 5 then
event.name = "BOUNCE_TOP"
elseif eventType == 6 then
event.name = "BOUNCE_BOTTOM"
elseif eventType == 7 then
event.name = "BOUNCE_LEFT"
elseif eventType == 8 then
event.name = "BOUNCE_RIGHT"
elseif eventType == 9 then
event.name = "CONTAINER_MOVED"
elseif eventType == 10 then
event.name = "AUTOSCROLL_ENDED"
end
event.target = sender
callback(event)
end)
return self
end

View File

@@ -1,38 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local PageView = ccui.PageView
function PageView:onEvent(callback)
self:addEventListener(function(sender, eventType)
local event = {}
if eventType == 0 then
event.name = "TURNING"
end
event.target = sender
callback(event)
end)
return self
end

View File

@@ -1,60 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local ScrollView = ccui.ScrollView
function ScrollView:onEvent(callback)
self:addEventListener(function(sender, eventType)
local event = {}
if eventType == 0 then
event.name = "SCROLL_TO_TOP"
elseif eventType == 1 then
event.name = "SCROLL_TO_BOTTOM"
elseif eventType == 2 then
event.name = "SCROLL_TO_LEFT"
elseif eventType == 3 then
event.name = "SCROLL_TO_RIGHT"
elseif eventType == 4 then
event.name = "SCROLLING"
elseif eventType == 5 then
event.name = "BOUNCE_TOP"
elseif eventType == 6 then
event.name = "BOUNCE_BOTTOM"
elseif eventType == 7 then
event.name = "BOUNCE_LEFT"
elseif eventType == 8 then
event.name = "BOUNCE_RIGHT"
elseif eventType == 9 then
event.name = "CONTAINER_MOVED"
elseif eventType == 10 then
event.name = "AUTOSCROLL_ENDED"
end
event.target = sender
callback(event)
end)
return self
end
ScrollView.onScroll = ScrollView.onEvent

View File

@@ -1,38 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local Slider = ccui.Slider
function Slider:onEvent(callback)
self:addEventListener(function(sender, eventType)
local event = {}
if eventType == 0 then
event.name = "ON_PERCENTAGE_CHANGED"
end
event.target = sender
callback(event)
end)
return self
end

View File

@@ -1,44 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local TextField = ccui.TextField
function TextField:onEvent(callback)
self:addEventListener(function(sender, eventType)
local event = {}
if eventType == 0 then
event.name = "ATTACH_WITH_IME"
elseif eventType == 1 then
event.name = "DETACH_WITH_IME"
elseif eventType == 2 then
event.name = "INSERT_TEXT"
elseif eventType == 3 then
event.name = "DELETE_BACKWARD"
end
event.target = sender
callback(event)
end)
return self
end

View File

@@ -1,43 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local Widget = ccui.Widget
function Widget:onTouch(callback)
self:addTouchEventListener(function(sender, state)
local event = {x = 0, y = 0}
if state == 0 then
event.name = "began"
elseif state == 1 then
event.name = "moved"
elseif state == 2 then
event.name = "ended"
else
event.name = "cancelled"
end
event.target = sender
callback(event)
end)
return self
end

View File

@@ -1,79 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
if type(DEBUG) ~= "number" then DEBUG = 0 end
-- load framework
printInfo("")
printInfo("# DEBUG = " .. DEBUG)
printInfo("#")
device = require("cocos.framework.device")
display = require("cocos.framework.display")
transition = require("cocos.framework.transition")
require("cocos.framework.extends.NodeEx")
require("cocos.framework.extends.SpriteEx")
if ccui then
require("cocos.framework.extends.UIWidget")
require("cocos.framework.extends.UICheckBox")
require("cocos.framework.extends.UIEditBox")
require("cocos.framework.extends.UIListView")
require("cocos.framework.extends.UIPageView")
require("cocos.framework.extends.UIScrollView")
require("cocos.framework.extends.UISlider")
require("cocos.framework.extends.UITextField")
end
require("cocos.framework.package_support")
-- register the build-in packages
cc.register("event", require("cocos.framework.components.event"))
-- export global variable
local __g = _G
cc.exports = {}
setmetatable(cc.exports, {
__newindex = function(_, name, value)
rawset(__g, name, value)
end,
__index = function(_, name)
return rawget(__g, name)
end
})
-- disable create unexpected global variable
function cc.disable_global()
setmetatable(__g, {
__newindex = function(_, name, value)
error(string.format("USE \" cc.exports.%s = value \" INSTEAD OF SET GLOBAL VARIABLE", name), 0)
end
})
end
if CC_DISABLE_GLOBAL then
cc.disable_global()
end

View File

@@ -1,113 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
-- Cocos2d-Lua core functions
cc.loaded_packages = {}
local loaded_packages = cc.loaded_packages
function cc.register(name, package)
cc.loaded_packages[name] = package
end
function cc.load(...)
local names = {...}
assert(#names > 0, "cc.load() - invalid package names")
local packages = {}
for _, name in ipairs(names) do
assert(type(name) == "string", string.format("cc.load() - invalid package name \"%s\"", tostring(name)))
if not loaded_packages[name] then
local packageName = string.format("packages.%s.init", name)
local cls = require(packageName)
assert(cls, string.format("cc.load() - package class \"%s\" load failed", packageName))
loaded_packages[name] = cls
if DEBUG > 1 then
printInfo("cc.load() - load module \"packages.%s.init\"", name)
end
end
packages[#packages + 1] = loaded_packages[name]
end
return unpack(packages)
end
local load_ = cc.load
local bind_
bind_ = function(target, ...)
local t = type(target)
assert(t == "table" or t == "userdata", string.format("cc.bind() - invalid target, expected is object, actual is %s", t))
local names = {...}
assert(#names > 0, "cc.bind() - package names expected")
load_(...)
if not target.components_ then target.components_ = {} end
for _, name in ipairs(names) do
assert(type(name) == "string" and name ~= "", string.format("cc.bind() - invalid package name \"%s\"", name))
if not target.components_[name] then
local cls = loaded_packages[name]
for __, depend in ipairs(cls.depends or {}) do
if not target.components_[depend] then
bind_(target, depend)
end
end
local component = cls:create()
target.components_[name] = component
component:bind(target)
end
end
return target
end
cc.bind = bind_
function cc.unbind(target, ...)
if not target.components_ then return end
local names = {...}
assert(#names > 0, "cc.unbind() - invalid package names")
for _, name in ipairs(names) do
assert(type(name) == "string" and name ~= "", string.format("cc.unbind() - invalid package name \"%s\"", name))
local component = target.components_[name]
assert(component, string.format("cc.unbind() - component \"%s\" not found", tostring(name)))
component:unbind(target)
target.components_[name] = nil
end
return target
end
function cc.setmethods(target, component, methods)
for _, name in ipairs(methods) do
local method = component[name]
target[name] = function(__, ...)
return method(component, ...)
end
end
end
function cc.unsetmethods(target, methods)
for _, name in ipairs(methods) do
target[name] = nil
end
end

View File

@@ -1,213 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
local transition = {}
local ACTION_EASING = {}
ACTION_EASING["BACKIN"] = {cc.EaseBackIn, 1}
ACTION_EASING["BACKINOUT"] = {cc.EaseBackInOut, 1}
ACTION_EASING["BACKOUT"] = {cc.EaseBackOut, 1}
ACTION_EASING["BOUNCE"] = {cc.EaseBounce, 1}
ACTION_EASING["BOUNCEIN"] = {cc.EaseBounceIn, 1}
ACTION_EASING["BOUNCEINOUT"] = {cc.EaseBounceInOut, 1}
ACTION_EASING["BOUNCEOUT"] = {cc.EaseBounceOut, 1}
ACTION_EASING["ELASTIC"] = {cc.EaseElastic, 2, 0.3}
ACTION_EASING["ELASTICIN"] = {cc.EaseElasticIn, 2, 0.3}
ACTION_EASING["ELASTICINOUT"] = {cc.EaseElasticInOut, 2, 0.3}
ACTION_EASING["ELASTICOUT"] = {cc.EaseElasticOut, 2, 0.3}
ACTION_EASING["EXPONENTIALIN"] = {cc.EaseExponentialIn, 1}
ACTION_EASING["EXPONENTIALINOUT"] = {cc.EaseExponentialInOut, 1}
ACTION_EASING["EXPONENTIALOUT"] = {cc.EaseExponentialOut, 1}
ACTION_EASING["IN"] = {cc.EaseIn, 2, 1}
ACTION_EASING["INOUT"] = {cc.EaseInOut, 2, 1}
ACTION_EASING["OUT"] = {cc.EaseOut, 2, 1}
ACTION_EASING["RATEACTION"] = {cc.EaseRateAction, 2, 1}
ACTION_EASING["SINEIN"] = {cc.EaseSineIn, 1}
ACTION_EASING["SINEINOUT"] = {cc.EaseSineInOut, 1}
ACTION_EASING["SINEOUT"] = {cc.EaseSineOut, 1}
local actionManager = cc.Director:getInstance():getActionManager()
function transition.newEasing(action, easingName, more)
local key = string.upper(tostring(easingName))
local easing
if ACTION_EASING[key] then
local cls, count, default = unpack(ACTION_EASING[key])
if count == 2 then
easing = cls:create(action, more or default)
else
easing = cls:create(action)
end
end
return easing or action
end
function transition.create(action, args)
args = checktable(args)
if args.easing then
if type(args.easing) == "table" then
action = transition.newEasing(action, unpack(args.easing))
else
action = transition.newEasing(action, args.easing)
end
end
local actions = {}
local delay = checknumber(args.delay)
if delay > 0 then
actions[#actions + 1] = cc.DelayTime:create(delay)
end
actions[#actions + 1] = action
local onComplete = args.onComplete
if type(onComplete) ~= "function" then onComplete = nil end
if onComplete then
actions[#actions + 1] = cc.CallFunc:create(onComplete)
end
if args.removeSelf then
actions[#actions + 1] = cc.RemoveSelf:create()
end
if #actions > 1 then
return transition.sequence(actions)
else
return actions[1]
end
end
function transition.execute(target, action, args)
assert(not tolua.isnull(target), "transition.execute() - target is not cc.Node")
local action = transition.create(action, args)
target:runAction(action)
return action
end
function transition.moveTo(target, args)
assert(not tolua.isnull(target), "transition.moveTo() - target is not cc.Node")
local x = args.x or target:getPositionX()
local y = args.y or target:getPositionY()
local action = cc.MoveTo:create(args.time, cc.p(x, y))
return transition.execute(target, action, args)
end
function transition.moveBy(target, args)
assert(not tolua.isnull(target), "transition.moveBy() - target is not cc.Node")
local x = args.x or 0
local y = args.y or 0
local action = cc.MoveBy:create(args.time, cc.p(x, y))
return transition.execute(target, action, args)
end
function transition.fadeIn(target, args)
assert(not tolua.isnull(target), "transition.fadeIn() - target is not cc.Node")
local action = cc.FadeIn:create(args.time)
return transition.execute(target, action, args)
end
function transition.fadeOut(target, args)
assert(not tolua.isnull(target), "transition.fadeOut() - target is not cc.Node")
local action = cc.FadeOut:create(args.time)
return transition.execute(target, action, args)
end
function transition.fadeTo(target, args)
assert(not tolua.isnull(target), "transition.fadeTo() - target is not cc.Node")
local opacity = checkint(args.opacity)
if opacity < 0 then
opacity = 0
elseif opacity > 255 then
opacity = 255
end
local action = cc.FadeTo:create(args.time, opacity)
return transition.execute(target, action, args)
end
function transition.scaleTo(target, args)
assert(not tolua.isnull(target), "transition.scaleTo() - target is not cc.Node")
local action
if args.scale then
action = cc.ScaleTo:create(checknumber(args.time), checknumber(args.scale))
elseif args.scaleX or args.scaleY then
local scaleX, scaleY
if args.scaleX then
scaleX = checknumber(args.scaleX)
else
scaleX = target:getScaleX()
end
if args.scaleY then
scaleY = checknumber(args.scaleY)
else
scaleY = target:getScaleY()
end
action = cc.ScaleTo:create(checknumber(args.time), scaleX, scaleY)
end
return transition.execute(target, action, args)
end
function transition.rotateTo(target, args)
assert(not tolua.isnull(target), "transition.rotateTo() - target is not cc.Node")
local rotation = args.rotation or target:getRotation()
local action = cc.RotateTo:create(args.time, rotation)
return transition.execute(target, action, args)
end
function transition.rotateBy(target, args)
assert(not tolua.isnull(target), "transition.rotateTo() - target is not cc.Node")
local rotation = args.rotation or 0
local action = cc.RotateBy:create(args.time, rotation)
return transition.execute(target, action, args)
end
function transition.sequence(actions)
if #actions < 1 then return end
if #actions < 2 then return actions[1] end
return cc.Sequence:create(actions)
end
function transition.removeAction(action)
if not tolua.isnull(action) then
actionManager:removeAction(action)
end
end
function transition.stopTarget(target)
if not tolua.isnull(target) then
actionManager:removeAllActionsFromTarget(target)
end
end
function transition.pauseTarget(target)
if not tolua.isnull(target) then
actionManager:pauseTarget(target)
end
end
function transition.resumeTarget(target)
if not tolua.isnull(target) then
actionManager:resumeTarget(target)
end
end
return transition

View File

@@ -1,54 +0,0 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
require "cocos.cocos2d.Cocos2d"
require "cocos.cocos2d.Cocos2dConstants"
require "cocos.cocos2d.functions"
__G__TRACKBACK__ = function(msg)
local msg = debug.traceback(msg, 3)
print(msg)
return msg
end
-- cocosstudio
if nil ~= ccs then
require "cocos.cocostudio.CocoStudio"
end
-- ui
if nil ~= ccui then
require "cocos.ui.GuiConstants"
end
-- network
require "cocos.network.NetworkConstants"
-- Spine
if nil ~= sp then
require "cocos.spine.SpineConstants"
end
-- physics3d
require "cocos.physics3d.physics3d-constants"
require "cocos.framework.init"

View File

@@ -57,6 +57,16 @@ static int register_all_packages()
bool AppDelegate::applicationDidFinishLaunching()
{
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if (!glview) {
string title = "__PROJECT_COCOS_NAME__";
glview = cocos2d::GLViewImpl::create(title.c_str());
director->setOpenGLView(glview);
director->startAnimation();
}
// set default FPS
Director::getInstance()->setAnimationInterval(1.0 / 60.0f);
@@ -73,14 +83,9 @@ bool AppDelegate::applicationDidFinishLaunching()
//register_custom_function(stack->getLuaState());
#if CC_64BITS
FileUtils::getInstance()->addSearchPath("src/64bit");
// FileUtils::getInstance()->addSearchPath("src/64bit");
#endif
FileUtils::getInstance()->addSearchPath("src");
FileUtils::getInstance()->addSearchPath("res");
if (engine->executeScriptFile("main.lua"))
{
return false;
}
engine->executeScriptFile("src/main.lua");
return true;
}

View File

@@ -1,8 +1,19 @@
local MyApp = class("MyApp", cc.load("mvc").AppBase)
require("config")
require("cocos.init")
require("framework.init")
function MyApp:onCreate()
math.randomseed(os.time())
local AppBase = require("framework.AppBase")
local MyApp = class("MyApp", AppBase)
function MyApp:ctor()
MyApp.super.ctor(self)
cc.disable_global()
end
function MyApp:run()
cc.FileUtils:getInstance():addSearchPath("res/")
self:enterScene("MainScene")
end
return MyApp

View File

@@ -0,0 +1,21 @@
local MainScene = class("MainScene", function()
return display.newScene("MainScene")
end)
function MainScene:ctor()
display.newSprite("HelloWorld.png")
:addTo(self)
:center()
display.newTTFLabel({text = "Hello, World", size = 64})
:align(display.CENTER, display.cx, display.cy)
:addTo(self)
end
function MainScene:onEnter()
end
function MainScene:onExit()
end
return MainScene

View File

@@ -1,17 +0,0 @@
local MainScene = class("MainScene", cc.load("mvc").ViewBase)
function MainScene:onCreate()
-- add background image
display.newSprite("HelloWorld.png")
:move(display.center)
:addTo(self)
-- add HelloWorld label
cc.Label:createWithSystemFont("Hello World", "Arial", 40)
:move(display.cx, display.cy + 200)
:addTo(self)
end
return MainScene

View File

@@ -0,0 +1,15 @@
-- 2d
require "cocos.cocos2d.Cocos2d"
require "cocos.cocos2d.Cocos2dConstants"
-- 3d
require "cocos.3d.3dConstants"
-- controller
require "cocos.controller.ControllerConstants"
-- ui
require "cocos.ui.GuiConstants"
-- network
require "cocos.network.NetworkConstants"
-- Spine
require "cocos.spine.SpineConstants"
-- physics3d
require "cocos.physics3d.physics3d-constants"

View File

@@ -1,23 +1,15 @@
-- 0 - disable debug info, 1 - less debug info, 2 - verbose debug info
DEBUG = 2
DEBUG = 1
-- show FPS on screen
CC_SHOW_FPS = true
-- display FPS stats on screen
DEBUG_FPS = true
-- disable create unexpected global variable
CC_DISABLE_GLOBAL = true
-- dump memory info every 10 seconds
DEBUG_MEM = false
-- for module display
CC_DESIGN_RESOLUTION = {
width = __SCREEN_WIDTH__,
height = __SCREEN_HEIGHT__,
autoscale = "FIXED_HEIGHT",
callback = function(framesize)
local ratio = framesize.width / framesize.height
if ratio <= 1.34 then
-- iPad 768*1024(1536*2048) is 4:3 screen
return {autoscale = "FIXED_WIDTH"}
end
end
}
-- design resolution
CONFIG_SCREEN_WIDTH = 640
CONFIG_SCREEN_HEIGHT = 960
-- auto scale mode
CONFIG_SCREEN_AUTOSCALE = "FIXED_WIDTH"

View File

@@ -0,0 +1,52 @@
local AppBase = class("AppBase")
function AppBase:ctor()
local eventDispatcher = cc.Director:getInstance():getEventDispatcher()
local customListenerBg = cc.EventListenerCustom:create("APP_ENTER_BACKGROUND_EVENT", function()
audio.pauseAll()
self:onEnterBackground()
end)
eventDispatcher:addEventListenerWithFixedPriority(customListenerBg, 1)
local customListenerFg = cc.EventListenerCustom:create("APP_ENTER_FOREGROUND_EVENT", function()
audio.resumeAll()
self:onEnterForeground()
end)
eventDispatcher:addEventListenerWithFixedPriority(customListenerFg, 1)
-- set global app
app = self
end
function AppBase:run()
end
function AppBase:exit()
cc.Director:getInstance():endToLua()
if device.platform == "windows" or device.platform == "mac" then
os.exit()
end
end
function AppBase:enterScene(sceneName, transitionType, time, more, ...)
local scenePackageName = "app.scenes." .. sceneName
local sceneClass = require(scenePackageName)
local scene = sceneClass.new(...)
display.replaceScene(scene, transitionType, time, more)
end
function AppBase:createView(viewName, ...)
local viewPackageName = "app.views." .. viewName
local viewClass = require(viewPackageName)
return viewClass.new(...)
end
-- override me
function AppBase:onEnterBackground()
end
-- override me
function AppBase:onEnterForeground()
end
return AppBase

View File

@@ -0,0 +1,378 @@
--[[
Copyright (c) 2011-2014 chukong-inc.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
--[[--
针对 cc.Node 的扩展
]]
local c = cc
local Node = c.Node
-- cocos2dx events
c.NODE_EVENT = 1
c.NODE_ENTER_FRAME_EVENT = 2
c.NODE_TOUCH_EVENT = 3
c.KEYPAD_EVENT = 4
c.ACCELEROMETER_EVENT = 5
-- touch
c.TOUCH_MODE_ALL_AT_ONCE = cc.TOUCHES_ALL_AT_ONCE
c.TOUCH_MODE_ONE_BY_ONE = cc.TOUCHES_ONE_BY_ONE
local function isPointIn( rc, pt )
local rect = c.rect(rc.x, rc.y, rc.width, rc.height)
return c.rectContainsPoint(rect, pt)
end
function Node:align(anchorPoint, x, y)
self:setAnchorPoint(display.ANCHOR_POINTS[anchorPoint])
if x and y then self:setPosition(x, y) end
return self
end
function Node:schedule(callback, interval)
local seq = c.Sequence:create(
c.DelayTime:create(interval),
c.CallFunc:create(callback)
)
local action = c.RepeatForever:create(seq)
self:runAction(action)
return action
end
function Node:performWithDelay(callback, delay)
local action = c.Sequence:create(
c.DelayTime:create(delay),
c.CallFunc:create(callback)
)
self:runAction(action)
return action
end
--[[--
测试一个点是否在当前结点区域中
@param tabel point cc.p的点位置,世界坐标
@return boolean 是否在结点区域中
]]
function Node:hitTest(point)
local nsp = self:convertToNodeSpace(point)
local rect = self:getContentSize()
rect.x = 0
rect.y = 0
if c.rectContainsPoint(rect, nsp) then
return true
end
return false
end
function Node:removeSelf()
self:removeFromParent(true)
end
-- override me for setNodeEventEnabled(true)
function Node:onEnter()
end
-- override me for setNodeEventEnabled(true)
function Node:onExit()
end
-- override me for setNodeEventEnabled(true)
function Node:onEnterTransitionFinish()
end
-- override me for setNodeEventEnabled(true)
function Node:onExitTransitionStart()
end
-- override me for setNodeEventEnabled(true)
function Node:onCleanup()
end
function Node:setAccelerometerEnabled(enabled)
cc.Device:setAccelerometerEnabled(enabled)
if not enabled then
return
end
local listener = cc.EventListenerAcceleration:create(function(event, x, y, z, timestamp)
-- call listener
self._LuaListeners[c.ACCELEROMETER_EVENT]{
x = x,
y = y,
z = z,
timestamp = timestamp
}
end)
self:getEventDispatcher():addEventListenerWithSceneGraphPriority(listener, self)
end
function Node:setNodeEventEnabled(enabled)
if enabled then
local listener = function(event)
local name = event.name
if name == "enter" then
self:onEnter()
elseif name == "exit" then
self:onExit()
elseif name == "enterTransitionFinish" then
self:onEnterTransitionFinish()
elseif name == "exitTransitionStart" then
self:onExitTransitionStart()
elseif name == "cleanup" then
self:onCleanup()
end
end
self:addNodeEventListener(c.NODE_EVENT, listener)
else
self:removeNodeEventListener(c.NODE_EVENT)
end
return self
end
local function KeypadEventCodeConvert(code)
local key
if code == 6 then
key = "back"
elseif code == 16 then
key = "menu"
else
key = tostring(code)
end
return key
end
function Node:setKeypadEnabled(enable)
if enable == self:isKeypadEnabled() then
return self
end
local eventDispatcher = self:getEventDispatcher()
if enable then
local onKeyPressed = function(keycode, event)
-- call listener
self._LuaListeners[c.KEYPAD_EVENT]{
code = keycode,
key = KeypadEventCodeConvert(keycode),
type = "Pressed"
}
end
local onKeyReleased = function(keycode, event)
-- call listener
self._LuaListeners[c.KEYPAD_EVENT]{
code = keycode,
key = KeypadEventCodeConvert(keycode),
type = "Released"
}
end
local listener = c.EventListenerKeyboard:create()
listener:registerScriptHandler(onKeyPressed, c.Handler.EVENT_KEYBOARD_PRESSED)
listener:registerScriptHandler(onKeyReleased, c.Handler.EVENT_KEYBOARD_RELEASED)
eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self)
self.__key_event_handle__ = listener
else
eventDispatcher:removeEventListener(self.__key_event_handle__)
self.__key_event_handle__ = nil
end
return self
end
function Node:isKeypadEnabled()
if self.__key_event_handle__ then
return true
end
return false
end
function Node:scheduleUpdate()
local listener = function (dt)
-- call listener
self._LuaListeners[c.NODE_ENTER_FRAME_EVENT](dt)
end
self:scheduleUpdateWithPriorityLua(listener, 0)
return self
end
function Node:setTouchMode(mode)
if mode ~= c.TOUCH_MODE_ALL_AT_ONCE and mode ~= c.TOUCHES_ONE_BY_ONE then
print("== wrong mode", mode)
return
end
self._luaTouchMode = mode
end
function Node:setTouchEnabled(enable)
-- remove old
local eventDispatcher = self:getEventDispatcher()
if self._luaTouchListener then
eventDispatcher:removeEventListener(self._luaTouchListener)
self._luaTouchListener = nil
end
if not enable then
return
end
assert(self._LuaListeners, "Error: addNodeEventListener(cc.NODE_TOUCH_EVENT, func) first!")
assert(self._LuaListeners[c.NODE_TOUCH_EVENT], "Error: addNodeEventListener(cc.NODE_TOUCH_EVENT, func) first!")
local isSingle = true
if self._luaTouchMode and self._luaTouchMode == c.TOUCH_MODE_ALL_AT_ONCE then
isSingle = false
end
-- add new
if isSingle then
self._luaTouchListener = c.EventListenerTouchOneByOne:create()
self._luaTouchListener:setSwallowTouches(true)
local dealFunc = function(touch, name)
local tp = touch:getLocation()
local sp = touch:getStartLocation()
local pp = touch:getPreviousLocation()
if name == "began" then
if not self:isVisible(true) or not self:hitTest(tp) then
return false
end
elseif name == "ended" then
if not self:hitTest(tp) then -- out of touch area
name = "cancelled"
end
end
-- call listener
return self._LuaListeners[c.NODE_TOUCH_EVENT]{
name = name,
x = tp.x,
y = tp.y,
startX = sp.x,
startY = sp.y,
prevX = pp.x,
prevY = pp.y,
}
end
self._luaTouchListener:registerScriptHandler(function(touch, event)
return dealFunc(touch, "began")
end, c.Handler.EVENT_TOUCH_BEGAN)
self._luaTouchListener:registerScriptHandler(function(touch, event)
dealFunc(touch, "moved")
end, c.Handler.EVENT_TOUCH_MOVED)
self._luaTouchListener:registerScriptHandler(function(touch, event)
dealFunc(touch, "ended")
end, c.Handler.EVENT_TOUCH_ENDED)
self._luaTouchListener:registerScriptHandler(function(touch, event)
dealFunc(touch, "cancelled")
end, c.Handler.EVENT_TOUCH_CANCELLED)
else
self._luaTouchListener = c.EventListenerTouchAllAtOnce:create()
local dealFunc = function(touchs, name)
local points = {}
for _, touch in pairs(touchs) do
local tp = touch:getLocation()
local sp = touch:getStartLocation()
local pp = touch:getPreviousLocation()
points[touch:getId()] = {
x = tp.x,
y = tp.y,
startX = sp.x,
startY = sp.y,
prevX = pp.x,
prevY = pp.y,
}
end
-- call listener
self._LuaListeners[c.NODE_TOUCH_EVENT]{
name = name,
points = points,
}
end
self._luaTouchListener:registerScriptHandler(function(touchs, event)
dealFunc(touchs, "began")
end, c.Handler.EVENT_TOUCHES_BEGAN)
self._luaTouchListener:registerScriptHandler(function(touchs, event)
dealFunc(touchs, "moved")
end, c.Handler.EVENT_TOUCHES_MOVED)
self._luaTouchListener:registerScriptHandler(function(touchs, event)
dealFunc(touchs, "ended")
end, c.Handler.EVENT_TOUCHES_ENDED)
self._luaTouchListener:registerScriptHandler(function(touchs, event)
dealFunc(touchs, "cancelled")
end, c.Handler.EVENT_TOUCHES_CANCELLED)
end
eventDispatcher:addEventListenerWithSceneGraphPriority(self._luaTouchListener, self)
end
function Node:setTouchSwallowEnabled(enable)
if self._luaTouchListener then
self._luaTouchListener:setSwallowTouches(enable)
end
end
function Node:addNodeEventListener(evt, hdl)
self._LuaListeners = self._LuaListeners or {}
if evt == c.NODE_EVENT then
self:registerScriptHandler(function(evt)
-- call listener
self._LuaListeners[c.NODE_EVENT]{name = evt}
end)
end
self._LuaListeners[evt] = hdl
end
function Node:removeNodeEventListener(evt)
if not self._LuaListeners then return end
if evt == c.KEYPAD_EVENT then
self:setKeypadEnabled(false)
elseif evt == c.NODE_EVENT then
self:unregisterScriptHandler()
elseif evt == c.NODE_ENTER_FRAME_EVENT then
self:unscheduleUpdate()
elseif evt == c.NODE_TOUCH_EVENT then
self:setTouchEnabled(false)
elseif evt == c.ACCELEROMETER_EVENT then
cc.Device:setAccelerometerEnabled(false)
end
self._LuaListeners[evt] = nil
end
function Node:removeAllNodeEventListeners()
self:removeNodeEventListener(c.NODE_EVENT)
self:removeNodeEventListener(c.NODE_ENTER_FRAME_EVENT)
self:removeNodeEventListener(c.NODE_TOUCH_EVENT)
self:removeNodeEventListener(c.KEYPAD_EVENT)
self:removeNodeEventListener(c.ACCELEROMETER_EVENT)
end

View File

@@ -0,0 +1,174 @@
--[[
Design for Quick-Cocos2dx-Community
First Write at 2017.2.17 by u0u0
]]
local socket = require "socket"
if not socket then return end
local scheduler = require("framework.scheduler")
local SimpleTCP = class("SimpleTCP")
local string = string
local pairs = pairs
local print = print
local assert = assert
--------- class var and method --------------
SimpleTCP._VERSION = socket._VERSION
SimpleTCP._DEBUG = socket._DEBUG
SimpleTCP.CONNECT_TIMEOUT = 15 -- second
SimpleTCP.STAT_CONNECTING = 1
SimpleTCP.STAT_FAILED = 2
SimpleTCP.STAT_CONNECTED = 3
SimpleTCP.STAT_CLOSED = 4
SimpleTCP.EVENT_CONNECTING = "Connecting"
SimpleTCP.EVENT_FAILED = "Failed"
SimpleTCP.EVENT_CONNECTED = "Connected"
SimpleTCP.EVENT_CLOSED = "Closed"
SimpleTCP.EVENT_DATA = "Data"
function SimpleTCP.getTime()
return socket.gettime()
end
-------- instant var and public method -------------
function SimpleTCP:ctor(host, port, callback)
if not host then print("Worning SimpleTCP:ctor() host is nil") end
if not port then print("Worning SimpleTCP:ctor() port is nil") end
self.host = host
self.port = port
self.tcp = nil
self.callback = callback
end
--[[
start connect by user
]]
function SimpleTCP:connect()
if (self.stat == SimpleTCP.STAT_CONNECTING or self.stat == SimpleTCP.STAT_CONNECTED) then
print("Error: SimpleTCP:connect() call at wrong stat:", self.stat)
return
end
self.stat = SimpleTCP.STAT_CONNECTING
self.callback(SimpleTCP.EVENT_CONNECTING)
self.connectingTime = 0
if self.tcp then
self:_connectAndCheck()
-- start global scheduler
assert(not self.globalUpdateHandler, "SimpleTCP:connect status wrong, need reviewing!")
self.globalUpdateHandler = scheduler.scheduleUpdateGlobal(handler(self, self._update))
else
-- if "closed", create a new LuaSocket
socket.dns.isIpv6(self.host, function(err, isIpv6)
assert(err == nil, "Error in socket.dns.isIpv6")
-- get a master socket
if isIpv6 then
self.tcp = socket.tcp6()
else
self.tcp = socket.tcp()
end
-- make LuaSocket work like Asynchronously
self.tcp:settimeout(0)
self:_connectAndCheck()
-- start global scheduler
assert(not self.globalUpdateHandler, "SimpleTCP:connect status wrong, need reviewing!")
self.globalUpdateHandler = scheduler.scheduleUpdateGlobal(handler(self, self._update))
end)
end
end
--[[
send data to server by user
]]
function SimpleTCP:send(data)
if self.stat ~= SimpleTCP.STAT_CONNECTED then
print("Error: SimpleTCP is not connected.")
return
end
self.tcp:send(data)
end
--[[
close by user, but SimpleTCP.EVENT_CLOSED will waiting for server's response
]]
function SimpleTCP:close()
if self.stat == SimpleTCP.STAT_CONNECTING then
print("Error: SimpleTCP is connecting, wait it end then you can call close()")
return
end
-- set self.tcp = nil in _update()
self.tcp:close()
end
------- private methods ------------
--[[
In asynchronous LuaSocket useage, use connect() return for stat checking
Return true for SimpleTCP.STAT_CONNECTED
]]
function SimpleTCP:_connectAndCheck()
local rtn, err = self.tcp:connectAsyn(self.host, self.port)
-- err in case of "already connected" is special fix for LuaSocket working on windows
-- refer to: http://lua-users.org/lists/lua-l/2009-10/msg00584.html
return rtn == 1 or err == "already connected"
end
function SimpleTCP:_update(dt)
if self.stat == SimpleTCP.STAT_CONNECTED then
local body, status, partial = self.tcp:receive("*a") -- receive mode: get all data
-- 1. If receive successful
if body and string.len(body) > 0 then
self.callback(SimpleTCP.EVENT_DATA, body)
return
end
-- 2. If got an error. Firstly, transfer partial data.
if partial and string.len(partial) > 0 then
self.callback(SimpleTCP.EVENT_DATA, partial)
-- Not return here, continue to check the error type
end
-- 3. Error type "timeout" will be ignored; but "closed" need handling.
if status == "closed" or status == "Socket is not connected" then
-- if close from server, safty free LuaSocket resource
self.tcp:close()
self.tcp = nil
-- stop scheduler
scheduler.unscheduleGlobal(self.globalUpdateHandler)
self.globalUpdateHandler = nil
-- notification
self.stat = SimpleTCP.STAT_CLOSED
self.callback(SimpleTCP.EVENT_CLOSED)
end
return
end
if self.stat == SimpleTCP.STAT_CONNECTING then
if self:_connectAndCheck() then
self.stat = SimpleTCP.STAT_CONNECTED
self.callback(SimpleTCP.EVENT_CONNECTED)
return
else
self.connectingTime = self.connectingTime + dt
if self.connectingTime >= SimpleTCP.CONNECT_TIMEOUT then
-- stop scheduler
scheduler.unscheduleGlobal(self.globalUpdateHandler)
self.globalUpdateHandler = nil
-- notification
self.stat = SimpleTCP.STAT_FAILED
self.callback(SimpleTCP.EVENT_FAILED)
end
return
end
end
end
return SimpleTCP

View File

@@ -0,0 +1,25 @@
--[[--
针对 ccui.Widget 的扩展
]]
local Widget = ccui.Widget
--[[
wapper ccui.Widget:setTouchEnabled to make it support Node:addNodeEventListener(cc.NODE_TOUCH_EVENT)
Normally, ccui.Widget have it own touch dealing in cpp code.
This wapper help you have chance to deal touch in lua code.
]]--
function Widget:setTouchEnabled(enable)
local cfunc = tolua.getcfunction(self, "setTouchEnabled")
if self._LuaListeners and self._LuaListeners[cc.NODE_TOUCH_EVENT] then
cc.Node.setTouchEnabled(self, enable)
-- widget's cpp listener may enable from csb setting.
-- In some cases, dispatch may not send to lua created listener
-- Remove cpp listener to avoid uncertain TouchEvent dispatch
cfunc(self, false)
else
cfunc(self, enable)
end
end

View File

@@ -0,0 +1,226 @@
--[[
Copyright 2017 KeNan Liu
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]
-- Singleton class
local audio = {}
audio._buffers = {}
audio._sources = {}
audio._scheduler = nil -- global schedule hander
-- pos 1 is for BGM
audio._sources[1] = Rapid2D_CAudio.newSource()
if not (audio._sources[1]) then
print("Error: init BGM source fail, check if have OpenAL init error above!")
-- fake function, disable audio output when init failed
audio.loadFile = function(path, callback)
callback(path, true)
end
audio.unloadFile = function(path) end
audio.unloadAllFile = function() end
audio.playBGMSync = function(path, isLoop) end
audio.playBGM = function(path, isLoop) end
audio.stopBGM = function() end
audio.setBGMVolume = function(vol) end
audio.playEffectSync = function(path, isLoop) end
audio.playEffect = function(path, isLoop) end
audio.setEffectVolume = function(vol) end
audio.stopEffect = function() end
audio.stopAll = function() end
audio.pauseAll = function() end
audio.resumeAll = function() end
return audio
end
audio._BGMVolume = 1.0
audio._effectVolume = 1.0
local scheduler = require("framework.scheduler")
-- INTERNAL API, recircle source from effects, call by director
local function update(dt)
local sources = audio._sources
local total = #sources
local index = 2
while index <= total do
local stat = sources[index]:getStat()
if 4 == stat then
sources[index]:__gc() -- free OpenAL resource
table.remove(sources, index)
total = total - 1
else
index = index + 1
end
end
if 1 == total then
scheduler.unscheduleGlobal(audio._scheduler)
audio._scheduler = nil
end
end
--------------- buffer -------------------
function audio.loadFile(path, callback)
if audio._buffers[path] then
callback(path, true)
else
assert(callback, "ONLY support asyn load file, please set callback!")
Rapid2D_CAudio.newBuffer(path, function(buffID)
if buffID then
audio._buffers[path] = buffID
callback(path, true)
else
callback(path, false)
end
end)
end
end
function audio.unloadFile(path)
local buffer = audio._buffers[path]
if buffer then
buffer:__gc()
end
audio._buffers[path] = nil
end
function audio.unloadAllFile()
for path, buffer in pairs(audio._buffers) do
buffer:__gc()
end
audio._buffers = {}
end
--[[
function for CSource
play2d(buffer, isLoop)
pause()
resume()
stop()
setVolume(vol)
getStat()
]]--
--------------- BGM 2D API -------------------
-- no need preload file
function audio.playBGMSync(path, isLoop)
audio.loadFile(path, function(pn, isSuccess)
if isSuccess then
audio.playBGM(pn, isLoop)
end
end)
end
-- need preload file
function audio.playBGM(path, isLoop)
local buffer = audio._buffers[path]
if not buffer then
print(path .. " have not loaded!!")
return
end
isLoop = isLoop ~= false and true or false
audio._sources[1]:stop()
audio._sources[1]:play2d(buffer, isLoop)
audio._sources[1]:setVolume(audio._BGMVolume)
end
function audio.stopBGM()
audio._sources[1]:stop()
end
function audio.setBGMVolume(vol)
if vol > 1.0 then
vol = 1.0
end
if vol < 0.0 then
vol = 0.0
end
audio._sources[1]:setVolume(vol)
audio._BGMVolume = vol
end
--------------- Effect 2D API -------------------
-- no need preload file
function audio.playEffectSync(path, isLoop)
audio.loadFile(path, function(pn, isSuccess)
if isSuccess then
audio.playEffect(pn, isLoop)
end
end)
end
-- need preload file
function audio.playEffect(path, isLoop)
local buffer = audio._buffers[path]
if not buffer then
print(path .. " have not loaded!!")
return
end
local source = Rapid2D_CAudio.newSource()
if source then
isLoop = isLoop == true and true or false
table.insert(audio._sources, source)
source:setVolume(audio._effectVolume)
source:play2d(buffer, isLoop)
-- start recircle scheduler
if not audio._scheduler then
audio._scheduler = scheduler.scheduleGlobal(update, 0.1)
end
end
return source
end
function audio.setEffectVolume(vol)
if vol > 1.0 then
vol = 1.0
end
if vol < 0.0 then
vol = 0.0
end
audio._effectVolume = vol
for i = 2, #audio._sources do
audio._sources[i]:setVolume(vol)
end
end
function audio.stopEffect()
for i = 2, #audio._sources do
audio._sources[i]:stop()
end
end
--------------- work both on BGM and Effects -------------------
function audio.stopAll()
for i = 1, #audio._sources do
audio._sources[i]:stop()
end
end
function audio.pauseAll()
for i = 1, #audio._sources do
audio._sources[i]:pause()
end
end
function audio.resumeAll()
for i = 1, #audio._sources do
audio._sources[i]:resume()
end
end
return audio

View File

@@ -0,0 +1,172 @@
--[[
Copyright (c) 2011-2014 chukong-inc.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
--------------------------------
-- @module crypto
--[[--
加解密、数据编码
]]
local crypto = {}
-- start --
--------------------------------
-- 使用 AES256 算法加密内容
-- @function [parent=#crypto] encryptAES256
-- @param string plaintext 明文字符串
-- @param string key 密钥字符串
-- @return string#string ret (return value: string) 加密后的字符串
-- end --
function crypto.encryptAES256(plaintext, key)
plaintext = tostring(plaintext)
key = tostring(key)
return cc.Crypto:encryptAES256(plaintext, string.len(plaintext), key, string.len(key))
end
-- start --
--------------------------------
-- 使用 AES256 算法解密内容
-- @function [parent=#crypto] decryptAES256
-- @param string ciphertext 加密后的字符串
-- @param string key 密钥字符串
-- @return string#string ret (return value: string) 明文字符串
-- end --
function crypto.decryptAES256(ciphertext, key)
ciphertext = tostring(ciphertext)
key = tostring(key)
return cc.Crypto:decryptAES256(ciphertext, string.len(ciphertext), key, string.len(key))
end
-- start --
--------------------------------
-- 使用 XXTEA 算法加密内容
-- @function [parent=#crypto] encryptXXTEA
-- @param string plaintext 明文字符串
-- @param string key 密钥字符串
-- @return string#string ret (return value: string) 加密后的字符串
-- end --
function crypto.encryptXXTEA(plaintext, key)
plaintext = tostring(plaintext)
key = tostring(key)
return cc.Crypto:encryptXXTEA(plaintext, string.len(plaintext), key, string.len(key))
end
-- start --
--------------------------------
-- 使用 XXTEA 算法解密内容
-- @function [parent=#crypto] decryptXXTEA
-- @param string ciphertext 加密后的字符串
-- @param string key 密钥字符串
-- @return string#string ret (return value: string) 明文字符串
-- end --
function crypto.decryptXXTEA(ciphertext, key)
ciphertext = tostring(ciphertext)
key = tostring(key)
return cc.Crypto:decryptXXTEA(ciphertext, string.len(ciphertext), key, string.len(key))
end
-- start --
--------------------------------
-- 使用 BASE64 算法编码内容
-- @function [parent=#crypto] encodeBase64
-- @param string plaintext 原文字符串
-- @return string#string ret (return value: string) 编码后的字符串
-- end --
function crypto.encodeBase64(plaintext)
plaintext = tostring(plaintext)
return cc.Crypto:encodeBase64(plaintext, string.len(plaintext))
end
-- start --
--------------------------------
-- 使用 BASE64 算法解码内容
-- @function [parent=#crypto] decodeBase64
-- @param string ciphertext 编码后的字符串
-- @return string#string ret (return value: string) 原文字符串
-- end --
function crypto.decodeBase64(ciphertext)
ciphertext = tostring(ciphertext)
return cc.Crypto:decodeBase64(ciphertext)
end
-- start --
--------------------------------
-- 计算内容的 MD5 码
-- @function [parent=#crypto] md5
-- @param string input 内容字符串
-- @param boolean isRawOutput 是否返回二进制 MD5 码
-- @return string#string ret (return value: string) MD5 字符串
-- end --
function crypto.md5(input, isRawOutput)
input = tostring(input)
if type(isRawOutput) ~= "boolean" then isRawOutput = false end
return cc.Crypto:MD5(input, isRawOutput)
end
-- start --
--------------------------------
-- 计算文件的 MD5 码
-- @function [parent=#crypto] md5file
-- @param string path 文件路径
-- @return string#string ret (return value: string) MD5 字符串
-- end --
function crypto.md5file(path)
if not path then
printError("crypto.md5file() - invalid filename")
return nil
end
path = tostring(path)
if DEBUG > 1 then
printInfo("crypto.md5file() - filename: %s", path)
end
return cc.Crypto:MD5File(path)
end
return crypto

View File

@@ -0,0 +1,203 @@
--[[
Copyright (c) 2011-2014 chukong-inc.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
--------------------------------
-- @module debug
--[[--
提供调试接口
]]
if ngx and ngx.log then
-- 如果运行在
print = function(...)
local arg = {...}
for k,v in pairs(arg) do
arg[k] = tostring(v)
end
ngx.log(ngx.ERR, table.concat(arg, "\t"))
end
end
--[[--
定义一个作废的接口
]]
function DEPRECATED(newfunction, oldname, newname)
return function(...)
PRINT_DEPRECATED(string.format("%s() is deprecated, please use %s()", oldname, newname))
return newfunction(...)
end
end
--[[--
显示作废信息
]]
function PRINT_DEPRECATED(msg)
if not DISABLE_DEPRECATED_WARNING then
printf("[DEPRECATED] %s", msg)
end
end
--[[--
打印调试信息
### 用法示例
~~~ lua
printLog("WARN", "Network connection lost at %d", os.time())
~~~
@param string tag 调试信息的 tag
@param string fmt 调试信息格式
@param [mixed ...] 更多参数
]]
function printLog(tag, fmt, ...)
local t = {
"[",
string.upper(tostring(tag)),
"] ",
string.format(tostring(fmt), ...)
}
print(table.concat(t))
end
--[[--
输出 tag 为 ERR 的调试信息
@param string fmt 调试信息格式
@param [mixed ...] 更多参数
]]
function printError(fmt, ...)
printLog("ERR", fmt, ...)
print(debug.traceback("", 2))
end
--[[--
输出 tag 为 INFO 的调试信息
@param string fmt 调试信息格式
@param [mixed ...] 更多参数
]]
function printInfo(fmt, ...)
printLog("INFO", fmt, ...)
end
--[[--
输出值的内容
### 用法示例
~~~ lua
local t = {comp = "chukong", engine = "quick"}
dump(t)
~~~
@param mixed value 要输出的值
@param [string desciption] 输出内容前的文字描述
@parma [integer nesting] 输出时的嵌套层级,默认为 3
]]
function dump(value, desciption, nesting)
if type(nesting) ~= "number" then nesting = 3 end
local lookupTable = {}
local result = {}
local function _v(v)
if type(v) == "string" then
v = "\"" .. v .. "\""
end
return tostring(v)
end
local traceback = string.split(debug.traceback("", 2), "\n")
print("dump from: " .. string.trim(traceback[3]))
local function _dump(value, desciption, indent, nest, keylen)
desciption = desciption or "<var>"
local spc = ""
if type(keylen) == "number" then
spc = string.rep(" ", keylen - string.len(_v(desciption)))
end
if type(value) ~= "table" then
result[#result +1 ] = string.format("%s%s%s = %s", indent, _v(desciption), spc, _v(value))
elseif lookupTable[value] then
result[#result +1 ] = string.format("%s%s%s = *REF*", indent, desciption, spc)
else
lookupTable[value] = true
if nest > nesting then
result[#result +1 ] = string.format("%s%s = *MAX NESTING*", indent, desciption)
else
result[#result +1 ] = string.format("%s%s = {", indent, _v(desciption))
local indent2 = indent.." "
local keys = {}
local keylen = 0
local values = {}
for k, v in pairs(value) do
keys[#keys + 1] = k
local vk = _v(k)
local vkl = string.len(vk)
if vkl > keylen then keylen = vkl end
values[k] = v
end
table.sort(keys, function(a, b)
if type(a) == "number" and type(b) == "number" then
return a < b
else
return tostring(a) < tostring(b)
end
end)
for i, k in ipairs(keys) do
_dump(values[k], k, indent2, nest + 1, keylen)
end
result[#result +1] = string.format("%s}", indent)
end
end
end
_dump(value, desciption, "- ", 1)
for i, line in ipairs(result) do
print(line)
end
end

View File

@@ -0,0 +1,348 @@
--[[
Copyright (c) 2011-2014 chukong-inc.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
--------------------------------
-- @module device
--[[--
提供设备相关属性的查询,以及设备功能的访问
当框架初始完成后device 模块提供下列属性:
- device.platform 返回当前运行平台的名字,可用值: ios, android, mac, windows.
- device.model 返回设备型号,可用值: unknown, iphone, ipad
- device.language 返回设备当前使用的语言,可用值:
- cn中文
- fr法语
- it意大利语
- gr德语
- sp西班牙语
- ru俄语
- jp日语
- en英语
- device.writablePath 返回设备上可以写入数据的首选路径:
- iOS 上返回应用程序所在的 Documents 目录
- Android 上返回存储卡的根目录
- 其他平台的返回值由 quick-x-player 决定
- device.cachePath 返回设备上可以写入数据的缓存目录:
- iOS 上返回应用程序所在的 Library/Caches 目录
- 其他平台的返回值同 device.writablePath
- device.directorySeparator 目录分隔符,在 Windows 平台上是 “\”,其他平台都是 “/”
- device.pathSeparator 路径分隔符,在 Windows 平台上是 “;”,其他平台都是 “:”
]]
local device = {}
device.platform = "unknown"
device.model = "unknown"
local sharedApplication = cc.Application:getInstance()
local target = sharedApplication:getTargetPlatform()
if target == cc.PLATFORM_OS_WINDOWS then
device.platform = "windows"
elseif target == cc.PLATFORM_OS_MAC then
device.platform = "mac"
elseif target == cc.PLATFORM_OS_ANDROID then
device.platform = "android"
elseif target == cc.PLATFORM_OS_IPHONE or target == cc.PLATFORM_OS_IPAD then
device.platform = "ios"
if target == cc.PLATFORM_OS_IPHONE then
device.model = "iphone"
else
device.model = "ipad"
end
end
local language_ = sharedApplication:getCurrentLanguage()
if language_ == cc.LANGUAGE_CHINESE then
language_ = "cn"
elseif language_ == cc.LANGUAGE_FRENCH then
language_ = "fr"
elseif language_ == cc.LANGUAGE_ITALIAN then
language_ = "it"
elseif language_ == cc.LANGUAGE_GERMAN then
language_ = "gr"
elseif language_ == cc.LANGUAGE_SPANISH then
language_ = "sp"
elseif language_ == cc.LANGUAGE_RUSSIAN then
language_ = "ru"
elseif language_ == cc.LANGUAGE_KOREAN then
language_ = "kr"
elseif language_ == cc.LANGUAGE_JAPANESE then
language_ = "jp"
elseif language_ == cc.LANGUAGE_HUNGARIAN then
language_ = "hu"
elseif language_ == cc.LANGUAGE_PORTUGUESE then
language_ = "pt"
elseif language_ == cc.LANGUAGE_ARABIC then
language_ = "ar"
else
language_ = "en"
end
device.language = language_
device.writablePath = cc.FileUtils:getInstance():getWritablePath()
-- device.cachePath = cc.FileUtils:getInstance():getCachePath()
device.directorySeparator = "/"
device.pathSeparator = ":"
if device.platform == "windows" then
device.directorySeparator = "\\"
device.pathSeparator = ";"
end
printInfo("# device.platform = " .. device.platform)
printInfo("# device.model = " .. device.model)
printInfo("# device.language = " .. device.language)
printInfo("# device.writablePath = " .. device.writablePath)
-- printInfo("# device.cachePath = " .. device.cachePath)
printInfo("# device.directorySeparator = " .. device.directorySeparator)
printInfo("# device.pathSeparator = " .. device.pathSeparator)
printInfo("#")
-- start --
--------------------------------
-- 显示活动指示器
-- @function [parent=#device] showActivityIndicator
--[[--
显示活动指示器
在 iOS 和 Android 设备上显示系统的活动指示器,可以用于阻塞操作时通知用户需要等待。
]]
-- end --
function device.showActivityIndicator()
if DEBUG > 1 then
printInfo("device.showActivityIndicator()")
end
cc.Native:showActivityIndicator()
end
-- start --
--------------------------------
-- 隐藏正在显示的活动指示器
-- @function [parent=#device] hideActivityIndicator
-- end --
function device.hideActivityIndicator()
if DEBUG > 1 then
printInfo("device.hideActivityIndicator()")
end
cc.Native:hideActivityIndicator()
end
-- start --
--------------------------------
-- 显示一个包含按钮的弹出对话框
-- @function [parent=#device] showAlert
-- @param string title 对话框标题
-- @param string message 内容
-- @param table buttonLabels 包含多个按钮标题的表格对象
-- @param function listener 回调函数
--[[--
显示一个包含按钮的弹出对话框
~~~ lua
local function onButtonClicked(event)
if event.buttonIndex == 1 then
.... 玩家选择了 YES 按钮
else
.... 玩家选择了 NO 按钮
end
end
device.showAlert("Confirm Exit", "Are you sure exit game ?", {"YES", "NO"}, onButtonClicked)
~~~
当没有指定按钮标题时对话框会默认显示一个“OK”按钮。
回调函数获得的表格中buttonIndex 指示玩家选择了哪一个按钮,其值是按钮的显示顺序。
]]
-- end --
function device.showAlert(title, message, buttonLabels, listener)
if type(buttonLabels) ~= "table" then
buttonLabels = {tostring(buttonLabels)}
else
table.map(buttonLabels, function(v) return tostring(v) end)
end
if DEBUG > 1 then
printInfo("device.showAlert() - title: %s", title)
printInfo(" message: %s", message)
printInfo(" buttonLabels: %s", table.concat(buttonLabels, ", "))
end
if device.platform == "android" then
local tempListner = function(event)
if type(event) == "string" then
event = require("framework.json").decode(event)
event.buttonIndex = tonumber(event.buttonIndex)
end
if listener then listener(event) end
end
luaj.callStaticMethod("org/cocos2dx/utils/PSNative", "createAlert", {title, message, buttonLabels, tempListner}, "(Ljava/lang/String;Ljava/lang/String;Ljava/util/Vector;I)V");
else
local defaultLabel = ""
if #buttonLabels > 0 then
defaultLabel = buttonLabels[1]
table.remove(buttonLabels, 1)
end
cc.Native:createAlert(title, message, defaultLabel)
for i, label in ipairs(buttonLabels) do
cc.Native:addAlertButton(label)
end
if type(listener) ~= "function" then
listener = function() end
end
cc.Native:showAlert(listener)
end
end
-- start --
--------------------------------
-- 取消正在显示的对话框。
-- @function [parent=#device] cancelAlert
-- end --
function device.cancelAlert()
if DEBUG > 1 then
printInfo("device.cancelAlert()")
end
cc.Native:cancelAlert()
end
-- start --
--------------------------------
-- 返回设备的 OpenUDID 值
-- @function [parent=#device] getOpenUDID
-- @return string#string ret (return value: string) 设备的 OpenUDID 值
--[[--
返回设备的 OpenUDID 值
OpenUDID 是为设备仿造的 UDID唯一设备识别码可以用来识别用户的设备。
但 OpenUDID 存在下列问题:
- 如果删除了应用再重新安装,获得的 OpenUDID 会发生变化
- iOS 7 不支持 OpenUDID
]]
-- end --
function device.getOpenUDID()
local ret = cc.Native:getOpenUDID()
if DEBUG > 1 then
printInfo("device.getOpenUDID() - Open UDID: %s", tostring(ret))
end
return ret
end
-- start --
--------------------------------
-- 用浏览器打开指定的网址
-- @function [parent=#device] openURL
-- @mycompany
-- @mycompany
-- @param string 网址,邮件,拨号等的字符串
--[[--
用浏览器打开指定的网址
~~~ lua
-- 打开网页
device.openURL("http://dualface.github.com/quick-cocos2d-x/")
-- 打开设备上的邮件程序,并创建新邮件,填入收件人地址
device.openURL("mailto:nobody@mycompany.com")
-- 增加主题和内容
local subject = string.urlencode("Hello")
local body = string.urlencode("How are you ?")
device.openURL(string.format("mailto:nobody@mycompany.com?subject=%s&body=%s", subject, body))
-- 打开设备上的拨号程序
device.openURL("tel:123-456-7890")
~~~
]]
-- end --
function device.openURL(url)
if DEBUG > 1 then
printInfo("device.openURL() - url: %s", tostring(url))
end
cc.Native:openURL(url)
end
-- start --
--------------------------------
-- 显示一个输入框,并返回用户输入的内容。
-- @function [parent=#device] showInputBox
-- @param string title 对话框标题
-- @param string message 提示信息
-- @param string defaultValue 输入框默认值
-- @return string#string ret (return value: string) 用户输入的字符串
-- end --
function device.showInputBox(title, message, defaultValue)
title = tostring(title or "INPUT TEXT")
message = tostring(message or "INPUT TEXT, CLICK OK BUTTON")
defaultValue = tostring(defaultValue or "")
if DEBUG > 1 then
printInfo("device.showInputBox() - title: %s", tostring(title))
printInfo(" message: %s", tostring(message))
printInfo(" defaultValue: %s", tostring(defaultValue))
end
return cc.Native:getInputText(title, message, defaultValue)
end
return device

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,82 @@
print("===========================================================")
print(" LOAD Cocos2d-Lua-Community FRAMEWORK")
print("===========================================================")
if type(DEBUG) ~= "number" then DEBUG = 0 end
if type(DEBUG_FPS) ~= "boolean" then DEBUG_FPS = false end
if type(DEBUG_MEM) ~= "boolean" then DEBUG_MEM = false end
local CURRENT_MODULE_NAME = ...
cc = cc or {}
cc.PACKAGE_NAME = string.sub(CURRENT_MODULE_NAME, 1, -6)
require(cc.PACKAGE_NAME .. ".debug")
require(cc.PACKAGE_NAME .. ".functions")
printInfo("")
printInfo("# DEBUG = "..DEBUG)
printInfo("#")
device = require(cc.PACKAGE_NAME .. ".device")
display = require(cc.PACKAGE_NAME .. ".display")
audio = require(cc.PACKAGE_NAME .. ".audio")
network = require(cc.PACKAGE_NAME .. ".network")
crypto = require(cc.PACKAGE_NAME .. ".crypto")
json = require(cc.PACKAGE_NAME .. ".json")
require(cc.PACKAGE_NAME .. ".shortcodes")
require(cc.PACKAGE_NAME .. ".NodeEx")
require(cc.PACKAGE_NAME .. ".WidgetEx")
if device.platform == "android" then
require(cc.PACKAGE_NAME .. ".platform.android")
elseif device.platform == "ios" then
require(cc.PACKAGE_NAME .. ".platform.ios")
elseif device.platform == "mac" then
require(cc.PACKAGE_NAME .. ".platform.mac")
end
local sharedTextureCache = cc.Director:getInstance():getTextureCache()
local sharedDirector = cc.Director:getInstance()
if DEBUG_FPS then
sharedDirector:setDisplayStats(true)
else
sharedDirector:setDisplayStats(false)
end
if DEBUG_MEM then
local sharedTextureCache = cc.Director:getInstance():getTextureCache()
--[[--
@ignore
]]
local function showMemoryUsage()
printInfo(string.format("LUA VM MEMORY USED: %0.2f KB", collectgarbage("count")))
printInfo(sharedTextureCache:getCachedTextureInfo())
printInfo("---------------------------------------------------")
end
sharedDirector:getScheduler():scheduleScriptFunc(showMemoryUsage, DEBUG_MEM_INTERVAL or 10.0, false)
end
-- export global variable
local __g = _G
cc.exports = {}
setmetatable(cc.exports, {
__newindex = function(_, name, value)
rawset(__g, name, value)
end,
__index = function(_, name)
return rawget(__g, name)
end
})
-- disable create unexpected global variable
function cc.disable_global()
setmetatable(__g, {
__newindex = function(_, name, value)
error(string.format("USE \" cc.exports.%s = value \" INSTEAD OF SET GLOBAL VARIABLE", name), 0)
end
})
end

View File

@@ -0,0 +1,157 @@
--[[
Copyright (c) 2011-2014 chukong-inc.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
--------------------------------
-- @module json
--[[--
JSON 编码与解码
]]
local json = {}
local cjson
local function safeLoad()
cjson = require("cjson")
end
if not pcall(safeLoad) then
cjson = nil
end
-- start --
--------------------------------
-- 将表格数据编码为 JSON 字符串
-- @function [parent=#json] encode
-- @param table 表格对象
-- @return string#string ret (return value: string) json字符串
--[[--
将表格数据编码为 JSON 字符串
~~~ lua
local str = json.encode({a=1,b="ss",c={c1=1,c2=2},d={10,11},100})
echo(str) -- {"a":1,"b":"ss","c":{"c1":1,"c2":2},"d":[10,11],"1":100}
local str = json.encode({1,2,"3",{10,11}})
echo(str) -- [ 1,2,"3",[10,11] ]
~~~
注意: table作为字典使用时整型键值将被转换为字符串键值
~~~ lua
local str = json.encode({a=1,[5]=3})
echo(str) -- {"a":1,"5":3}
~~~
注意: table所有键值为整型时会当作数组看待空位将转化为null
~~~ lua
local str = json.encode({[3]=2,[5]=3})
echo(str) -- [null,null,2,null,3]
~~~
]]
-- end --
function json.encode(var)
local status, result = pcall(cjson.encode, var)
if status then return result end
if DEBUG > 1 then
printError("json.encode() - encoding failed: %s", tostring(result))
end
end
-- start --
--------------------------------
-- 将 JSON 字符串解码为表格对象
-- @function [parent=#json] decode
-- @param string json字符串
-- @return table#table ret (return value: table) 表格对象
--[[--
将 JSON 字符串解码为表格对象
~~~ lua
local json = require("framework.json")
local tb = json.decode('{"a":1,"b":"ss","c":{"c1":1,"c2":2},"d":[10,11],"1":100}')
dump(tb) --[ [
- "<var>" = {
- "1" = 100
- "a" = 1
- "b" = "ss"
- "c" = {
- "c1" = 1
- "c2" = 2
- }
- "d" = {
- 1 = 10
- 2 = 11
- }
- }
] ]
local tb = json.decode('[1,2,"3",[10,11] ]')
dump(tb) --[ [
- "<var>" = {
- 1 = 1
- 2 = 2
- 3 = "3"
- 4 = {
- 1 = 10
- 2 = 11
- }
- }
] ]
~~~
]]
-- end --
function json.decode(text)
local status, result = pcall(cjson.decode, text)
if status then return result end
if DEBUG > 1 then
printError("json.decode() - decoding failed: %s", tostring(result))
end
end
if cjson then
json.null = cjson.null
else
json = nil
end
return json

View File

@@ -0,0 +1,343 @@
--[[
Copyright (c) 2011-2014 chukong-inc.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
--------------------------------
-- @module network
--[[--
网络服务
]]
local network = {}
-- start --
--------------------------------
-- 检查地 WIFI 网络是否可用
-- @function [parent=#network] isLocalWiFiAvailable
-- @return boolean#boolean ret (return value: bool) 网络是否可用
--[[--
检查地 WIFI 网络是否可用
提示: WIFI 网络可用不代表可以访问互联网。
]]
-- end --
function network.isLocalWiFiAvailable()
return cc.Network:isLocalWiFiAvailable()
end
-- start --
--------------------------------
-- 检查互联网连接是否可用
-- @function [parent=#network] isInternetConnectionAvailable
-- @return boolean#boolean ret (return value: bool) 网络是否可用
--[[--
检查互联网连接是否可用
通常,这里接口返回 3G 网络的状态,具体情况与设备和操作系统有关。
]]
-- end --
function network.isInternetConnectionAvailable()
return cc.Network:isInternetConnectionAvailable()
end
-- start --
--------------------------------
-- 检查是否可以解析指定的主机名
-- @function [parent=#network] isHostNameReachable
-- @param string hostname 主机名
-- @return boolean#boolean ret (return value: bool) 主机名是否可以解析
--[[--
检查是否可以解析指定的主机名
~~~ lua
if network.isHostNameReachable("www.google.com") then
-- 域名可以解析
end
~~~
注意: 该接口会阻塞程序,因此在调用该接口时应该提醒用户应用程序在一段时间内会失去响应。
]]
-- end --
function network.isHostNameReachable(hostname)
if type(hostname) ~= "string" then
printError("network.isHostNameReachable() - invalid hostname %s", tostring(hostname))
return false
end
return cc.Network:isHostNameReachable(hostname)
end
-- start --
--------------------------------
-- 返回互联网连接状态值
-- @function [parent=#network] getInternetConnectionStatus
-- @return string#string ret (return value: string) 互联网连接状态值
--[[--
返回互联网连接状态值
状态值有三种:
- kCCNetworkStatusNotReachable: 无法访问互联网
- kCCNetworkStatusReachableViaWiFi: 通过 WIFI
- kCCNetworkStatusReachableViaWWAN: 通过 3G 网络
]]
-- end --
function network.getInternetConnectionStatus()
return cc.Network:getInternetConnectionStatus()
end
-- start --
--------------------------------
-- 创建异步 HTTP 请求,并返回 cc.HTTPRequest 对象。
-- @function [parent=#network] createHTTPRequest
-- @param function callbock 回调函数
-- @url string http路径
-- method string method 请求方式
-- @return HTTPRequest#HTTPRequest ret (return value: cc.HTTPRequest)
--[[--
创建异步 HTTP 请求,并返回 cc.HTTPRequest 对象。
~~~ lua
function onRequestFinished(event)
local ok = (event.name == "completed")
local request = event.request
if not ok then
-- 请求失败,显示错误代码和错误消息
print(request:getErrorCode(), request:getErrorMessage())
return
end
local code = request:getResponseStatusCode()
if code ~= 200 then
-- 请求结束,但没有返回 200 响应代码
print(code)
return
end
-- 请求成功,显示服务端返回的内容
local response = request:getResponseString()
print(response)
end
-- 创建一个请求,并以 POST 方式发送数据到服务端
local url = "http://www.mycompany.com/request.php"
local request = network.createHTTPRequest(onRequestFinished, url, "POST")
request:addPOSTValue("KEY", "VALUE")
-- 开始请求。当请求完成时会调用 callback() 函数
request:start()
~~~
]]
-- end --
function network.createHTTPRequest(callback, url, method)
if not method then method = "GET" end
if string.upper(tostring(method)) == "GET" then
method = cc.kCCHTTPRequestMethodGET
elseif string.upper(tostring(method)) == "PUT" then
method = cc.kCCHTTPRequestMethodPUT
elseif string.upper(tostring(method)) == "DELETE" then
method = cc.kCCHTTPRequestMethodDELETE
else
method = cc.kCCHTTPRequestMethodPOST
end
return cc.HTTPRequest:createWithUrl(callback, url, method)
end
-- start --
--------------------------------
-- 通过HTTPRequest上传一个文件
-- @function [parent=#network] uploadFile
-- @param function callback 回调函数
-- @param string url 上传路径
-- @param tabel datas 上传参数
-- @return HTTPRequest#HTTPRequest 结果
--[[--
--- Upload a file through a HTTPRequest instance.
-- @author zrong(zengrong.net)
-- Creation: 2014-04-14
-- @param callback As same as the first parameter of network.createHTTPRequest.
-- @param url As same as the second parameter of network.createHTTPRequest.
-- @param datas Includes following values:
-- fileFiledName(The input label name that type is file);
-- filePath(A absolute path for a file)
-- contentType(Optional, the file's contentType, default is application/octet-stream)
-- extra(Optional, the key-value table that transmit to form)
-- for example:
~~~ lua
network.uploadFile(function(evt)
if evt.name == "completed" then
local request = evt.request
printf("REQUEST getResponseStatusCode() = %d", request:getResponseStatusCode())
printf("REQUEST getResponseHeadersString() =\n%s", request:getResponseHeadersString())
printf("REQUEST getResponseDataLength() = %d", request:getResponseDataLength())
printf("REQUEST getResponseString() =\n%s", request:getResponseString())
end
end,
"http://127.0.0.1/upload.php",
{
fileFieldName="filepath",
filePath=device.writablePath.."screen.jpg",
contentType="Image/jpeg",
extra={
{"act", "upload"},
{"submit", "upload"},
}
}
)
~~~
]]
-- end --
function network.uploadFile(callback, url, datas)
assert(datas or datas.fileFieldName or datas.filePath, "Need file datas!")
local request = network.createHTTPRequest(callback, url, "POST")
local fileFieldName = datas.fileFieldName
local filePath = datas.filePath
local contentType = datas.contentType
if contentType then
request:addFormFile(fileFieldName, filePath, contentType)
else
request:addFormFile(fileFieldName, filePath)
end
if datas.extra then
for i in ipairs(datas.extra) do
local data = datas.extra[i]
request:addFormContents(data[1], data[2])
end
end
request:start()
return request
end
local function parseTrueFalse(t)
t = string.lower(tostring(t))
if t == "yes" or t == "true" then return true end
return false
end
-- start --
--------------------------------
-- 转换cookie为一个字串
-- @function [parent=#network] makeCookieString
-- @param tabel cookie
-- @return string#string 结果
-- end --
function network.makeCookieString(cookie)
local arr = {}
for name, value in pairs(cookie) do
if type(value) == "table" then
value = tostring(value.value)
else
value = tostring(value)
end
arr[#arr + 1] = tostring(name) .. "=" .. string.urlencode(value)
end
return table.concat(arr, "; ")
end
-- start --
--------------------------------
-- 转换字串为一个cookie表
-- @function [parent=#network] parseCookie
-- @param string cookieString
-- @return table#table 结果
-- end --
function network.parseCookie(cookieString)
local cookie = {}
local arr = string.split(cookieString, "\n")
for _, item in ipairs(arr) do
item = string.trim(item)
if item ~= "" then
local parts = string.split(item, "\t")
-- ".amazon.com" represents the domain name of the Web server that created the cookie and will be able to read the cookie in the future
-- TRUE indicates that all machines within the given domain can access the cookie
-- "/" denotes the path within the domain for which the variable is valid
-- "FALSE" indicates that the connection is not secure
-- "2082787601" represents the expiration date in UNIX time (number of seconds since January 1, 1970 00:00:00 GMT)
-- "ubid-main" is the name of the cookie
-- "002-2904428-3375661" is the value of the cookie
local c = {
domain = parts[1],
access = parseTrueFalse(parts[2]),
path = parts[3],
secure = parseTrueFalse(parts[4]),
expire = checkint(parts[5]),
name = parts[6],
value = string.urldecode(parts[7]),
}
cookie[c.name] = c
end
end
return cookie
end
return network

View File

@@ -0,0 +1,4 @@
luaj = require(cc.PACKAGE_NAME .. ".platform.luaj")
function device.showAlertAndroid(title, message, buttonLabels, listener)
end

View File

@@ -0,0 +1,4 @@
luaoc = require(cc.PACKAGE_NAME .. ".platform.luaoc")
function device.showAlertIOS(title, message, buttonLabels, listener)
end

View File

@@ -0,0 +1,83 @@
--[[
Copyright (c) 2011-2014 chukong-inc.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
--------------------------------
-- @module luaj
--[[--
Lua 与 Java 的交互接口
]]
local luaj = {}
local callJavaStaticMethod = LuaJavaBridge.callStaticMethod
--[[--
私有方法
]]
local function checkArguments(args, sig)
if type(args) ~= "table" then args = {} end
if sig then return args, sig end
sig = {"("}
for i, v in ipairs(args) do
local t = type(v)
if t == "number" then
sig[#sig + 1] = "F"
elseif t == "boolean" then
sig[#sig + 1] = "Z"
elseif t == "function" then
sig[#sig + 1] = "I"
else
sig[#sig + 1] = "Ljava/lang/String;"
end
end
sig[#sig + 1] = ")V"
return args, table.concat(sig)
end
-- start --
--------------------------------
-- 调用java类的接口。
-- @function [parent=#luaj] callStaticMethod
-- @param string className java类名
-- @param string methodName java类静态方法名
-- @param table args java类静态方法所需要的各种参数 数组
-- @param string sig java类方法的签名
-- @return boolean#boolean ret (return value: bool) ok, mixed ret ok为是否调用成功, ok为true时,ret为java方法的返回值,ok为false时,ret为出错原因
-- end --
function luaj.callStaticMethod(className, methodName, args, sig)
local args, sig = checkArguments(args, sig)
printInfo("luaj.callStaticMethod(\"%s\",\n\t\"%s\",\n\targs,\n\t\"%s\"", className, methodName, sig)
return callJavaStaticMethod(className, methodName, args, sig)
end
return luaj

View File

@@ -0,0 +1,71 @@
--[[
Copyright (c) 2011-2014 chukong-inc.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
--------------------------------
-- @module luaoc
--[[--
Lua 与 Objective-C 的交互接口
]]
local luaoc = {}
local callStaticMethod = LuaObjcBridge.callStaticMethod
-- start --
--------------------------------
-- 调用Objective-C类的接口。
-- @function [parent=#luaoc] callStaticMethod
-- @param string className Objective-C类名
-- @param string methodName Objective-C类方法名
-- @param table args Objective-C类方法所需要的各种参数字典,key值为方法的参数名
-- @return boolean#boolean ret (return value: bool) ok, mixed ret ok为是否调用成功, ok为true时,ret为Objective-C方法的返回值,ok为false时,ret为出错原因
-- end --
function luaoc.callStaticMethod(className, methodName, args)
local ok, ret = callStaticMethod(className, methodName, args)
if not ok then
local msg = string.format("luaoc.callStaticMethod(\"%s\", \"%s\", \"%s\") - error: [%s] ",
className, methodName, tostring(args), tostring(ret))
if ret == -1 then
printError(msg .. "INVALID PARAMETERS")
elseif ret == -2 then
printError(msg .. "CLASS NOT FOUND")
elseif ret == -3 then
printError(msg .. "METHOD NOT FOUND")
elseif ret == -4 then
printError(msg .. "EXCEPTION OCCURRED")
elseif ret == -5 then
printError(msg .. "INVALID METHOD SIGNATURE")
else
printError(msg .. "UNKNOWN")
end
end
return ok, ret
end
return luaoc

View File

@@ -0,0 +1 @@
luaoc = require(cc.PACKAGE_NAME .. ".platform.luaoc")

View File

@@ -0,0 +1,146 @@
--[[
Copyright (c) 2011-2014 chukong-inc.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
--------------------------------
-- @module scheduler
--[[--
全局计时器、计划任务
«该模块在框架初始化时不会自动载入»
加载方式: local scheduler = require(cc.PACKAGE_NAME .. ".scheduler")
]]
local scheduler = {}
local sharedScheduler = cc.Director:getInstance():getScheduler()
-- start --
--------------------------------
-- 计划一个全局帧事件回调,并返回该计划的句柄。
-- @function [parent=#scheduler] scheduleUpdateGlobal
-- @param function 回调函数
-- @return mixed#mixed ret (return value: mixed) schedule句柄
--[[--
计划一个全局帧事件回调,并返回该计划的句柄。
全局帧事件在任何场景中都会执行,因此可以在整个应用程序范围内实现较为精确的全局计时器。
该函数返回的句柄用作 scheduler.unscheduleGlobal() 的参数,可以取消指定的计划。
]]
-- end --
function scheduler.scheduleUpdateGlobal(listener)
return sharedScheduler:scheduleScriptFunc(listener, 0, false)
end
-- start --
--------------------------------
-- 计划一个以指定时间间隔执行的全局事件回调,并返回该计划的句柄。
-- @function [parent=#scheduler] scheduleGlobal
-- @param function listener 回调函数
-- @param number interval 间隔时间
-- @return mixed#mixed ret (return value: mixed) schedule句柄
--[[--
计划一个以指定时间间隔执行的全局事件回调,并返回该计划的句柄。
~~~ lua
local function onInterval(dt)
end
-- 每 0.5 秒执行一次 onInterval()
local handle = scheduler.scheduleGlobal(onInterval, 0.5)
~~~
]]
-- end --
function scheduler.scheduleGlobal(listener, interval)
return sharedScheduler:scheduleScriptFunc(listener, interval, false)
end
-- start --
--------------------------------
-- 取消一个全局计划
-- @function [parent=#scheduler] unscheduleGlobal
-- @param mixed schedule句柄
--[[--
取消一个全局计划
scheduler.unscheduleGlobal() 的参数就是 scheduler.scheduleUpdateGlobal() 和 scheduler.scheduleGlobal() 的返回值。
]]
-- end --
function scheduler.unscheduleGlobal(handle)
sharedScheduler:unscheduleScriptEntry(handle)
end
-- start --
--------------------------------
-- 计划一个全局延时回调,并返回该计划的句柄。
-- @function [parent=#scheduler] performWithDelayGlobal
-- @param function listener 回调函数
-- @param number time 延迟时间
-- @return mixed#mixed ret (return value: mixed) schedule句柄
--[[--
计划一个全局延时回调,并返回该计划的句柄。
scheduler.performWithDelayGlobal() 会在等待指定时间后执行一次回调函数,然后自动取消该计划。
]]
-- end --
function scheduler.performWithDelayGlobal(listener, time)
local handle
handle = sharedScheduler:scheduleScriptFunc(function()
scheduler.unscheduleGlobal(handle)
listener()
end, time, false)
return handle
end
return scheduler

View File

@@ -0,0 +1,489 @@
--[[
Copyright (c) 2011-2014 chukong-inc.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
--------------------------------
-- @module shortcodes
--[[--
shortcode
]]
local c = cc
local Node = c.Node
--------------------------------
-- @module Node
-- start --
--------------------------------
-- 在当前结点中加入一个子结点
-- @function [parent=#Node] add
-- @param node child 要加入的结点
-- @param number zorder 要加入结点的Z值
-- @param number tag 要加入结点的tag
-- @return Node#Node 当前结点
-- end --
function Node:add(child, zorder, tag)
self:addChild(child, zorder or child:getLocalZOrder(), tag or child:getTag())
return self
end
-- start --
--------------------------------
-- 把当前结点作为一个子结点加到target中
-- @function [parent=#Node] addTo
-- @param node target 想作为其子结点的结点
-- @param number zorder 当前结点的Z值
-- @param number tag 当前结点的tag
-- @return Node#Node 当前结点
-- end --
function Node:addTo(target, zorder, tag)
target:addChild(self, zorder or self:getLocalZOrder(), tag or self:getTag())
return self
end
-- start --
--------------------------------
-- 显示当前结点,让当前结点可显示
-- @function [parent=#Node] show
-- @return Node#Node 当前结点
-- end --
function Node:show()
self:setVisible(true)
return self
end
-- start --
--------------------------------
-- 隐藏当前结点,让当前结点不可显示
-- @function [parent=#Node] hide
-- @return Node#Node 当前结点
-- end --
function Node:hide()
self:setVisible(false)
return self
end
-- start --
--------------------------------
-- 设置当前结点的位置
-- @function [parent=#Node] pos
-- @param number x X值
-- @param number y Y值
-- @return Node#Node 当前结点
-- end --
function Node:pos(x, y)
self:setPosition(x, y)
return self
end
-- start --
--------------------------------
-- 设置当前结点在屏幕的中心
-- @function [parent=#Node] center
-- @return Node#Node 当前结点
-- end --
function Node:center()
self:setPosition(display.cx, display.cy)
return self
end
-- start --
--------------------------------
-- 设置当前结点的缩放值
-- @function [parent=#Node] scale
-- @param number scale 要缩放的值
-- @return Node#Node 当前结点
-- end --
function Node:scale(scale)
self:setScale(scale)
return self
end
-- start --
--------------------------------
-- 设置当前结点的旋转角度值
-- @function [parent=#Node] rotation
-- @param number r 旋转角度
-- @return Node#Node 当前结点
-- end --
function Node:rotation(r)
self:setRotation(r)
return self
end
-- start --
--------------------------------
-- 设置当前结点的大小
-- @function [parent=#Node] size
-- @param mixed width 宽度或cc.size表
-- @param number height 高度
-- @return Node#Node 当前结点
-- end --
function Node:size(width, height)
if type(width) == "table" then
self:setContentSize(width)
else
self:setContentSize(cc.size(width, height))
end
return self
end
-- start --
--------------------------------
-- 设置当前结点的透明度, 0到255,0为完全透明
-- @function [parent=#Node] opacity
-- @param number opacity 透明度
-- @return Node#Node 当前结点
-- end --
function Node:opacity(opacity)
self:setOpacity(opacity)
return self
end
-- start --
--------------------------------
-- 设置当前结点z值
-- @function [parent=#Node] zorder
-- @param number z z值
-- @return Node#Node 当前结点
-- end --
function Node:zorder(z)
self:setLocalZOrder(z)
return self
end
-- start --
--------------------------------
-- 停止结点的所有动作
-- @function [parent=#Node] stop
-- @return Node#Node 当前结点
-- end --
function Node:stop()
self:stopAllActions()
return self
end
-- start --
--------------------------------
-- 渐显动画
-- @function [parent=#Node] fadeIn
-- @param number time 渐显时间
-- @return Node#Node 当前结点
-- end --
function Node:fadeIn(time)
self:runAction(cc.FadeIn:create(time))
return self
end
-- start --
--------------------------------
-- 渐隐动画
-- @function [parent=#Node] fadeOut
-- @param number time 渐隐时间
-- @return Node#Node 当前结点
-- end --
function Node:fadeOut(time)
self:runAction(cc.FadeOut:create(time))
return self
end
-- start --
--------------------------------
-- 渐变到一个固定透明度
-- @function [parent=#Node] fadeTo
-- @param number time 渐变时间
-- @param number opacity 最终的透明度
-- @return Node#Node 当前结点
-- end --
function Node:fadeTo(time, opacity)
self:runAction(cc.FadeTo:create(time, opacity))
return self
end
-- start --
--------------------------------
-- 在一段时间内移动结点到特定位置
-- @function [parent=#Node] moveTo
-- @param number time 移动时间
-- @param number x 要移动到的X点
-- @param number y 要移动到的Y点
-- @return Node#Node 当前结点
-- end --
function Node:moveTo(time, x, y)
self:runAction(cc.MoveTo:create(time, cc.p(x or self:getPositionX(), y or self:getPositionY())))
return self
end
-- start --
--------------------------------
-- 在一段时间内移动相对位置
-- @function [parent=#Node] moveBy
-- @param number time 移动时间
-- @param number x 要移动的相对X值
-- @param number y 要移动的相对Y值
-- @return Node#Node 当前结点
-- end --
function Node:moveBy(time, x, y)
self:runAction(cc.MoveBy:create(time, cc.p(x or 0, y or 0)))
return self
end
-- start --
--------------------------------
-- 在一段时间内旋转的角度
-- @function [parent=#Node] rotateTo
-- @param number time 移动时间
-- @param number rotation 旋转的角度
-- @return Node#Node 当前结点
-- end --
function Node:rotateTo(time, rotation)
self:runAction(cc.RotateTo:create(time, rotation))
return self
end
-- start --
--------------------------------
-- 在一段时间内旋转的相对角度
-- @function [parent=#Node] rotateBy
-- @param number time 移动时间
-- @param number rotation 旋转的相对角度
-- @return Node#Node 当前结点
-- end --
function Node:rotateBy(time, rotation)
self:runAction(cc.RotateBy:create(time, rotation))
return self
end
-- start --
--------------------------------
-- 在一段时间内缩放
-- @function [parent=#Node] scaleTo
-- @param number time 移动时间
-- @param number scale 缩放的值
-- @return Node#Node 当前结点
-- end --
function Node:scaleTo(time, scale)
self:runAction(cc.ScaleTo:create(time, scale))
return self
end
-- start --
--------------------------------
-- 在一段时间内的相对缩放
-- @function [parent=#Node] scaleBy
-- @param number time 移动时间
-- @param number scale 相对缩放的值
-- @return Node#Node 当前结点
-- end --
function Node:scaleBy(time, scale)
self:runAction(cc.ScaleBy:create(time, scale))
return self
end
-- start --
--------------------------------
-- 在一段时间内倾斜的大小
-- @function [parent=#Node] skewTo
-- @param number time 移动时间
-- @param number sx 倾斜的X值
-- @param number sy 倾斜的Y值
-- @return Node#Node 当前结点
-- end --
function Node:skewTo(time, sx, sy)
self:runAction(cc.SkewTo:create(time, sx or self:getSkewX(), sy or self:getSkewY()))
return self
end
-- start --
--------------------------------
-- 在一段时间内倾斜的相对大小
-- @function [parent=#Node] skewBy
-- @param number time 移动时间
-- @param number sx 倾斜的相对X值
-- @param number sy 倾斜的相对Y值
-- @return Node#Node 当前结点
-- end --
function Node:skewBy(time, sx, sy)
self:runAction(cc.SkewBy:create(time, sx or 0, sy or 0))
return self
end
-- start --
--------------------------------
-- 在一段时间内染色
-- @function [parent=#Node] tintTo
-- @param number time 移动时间
-- @param number r 染色的R值
-- @param number g 染色的G值
-- @param number b 染色的B值
-- @return Node#Node 当前结点
-- end --
function Node:tintTo(time, r, g, b)
self:runAction(cc.TintTo:create(time, r or 0, g or 0, b or 0))
return self
end
-- start --
--------------------------------
-- 在一段时间内相对染色
-- @function [parent=#Node] tintBy
-- @param number time 移动时间
-- @param number r 染色的相对R值
-- @param number g 染色的相对G值
-- @param number b 染色的相对B值
-- @return Node#Node 当前结点
-- end --
function Node:tintBy(time, r, g, b)
self:runAction(cc.TintBy:create(time, r or 0, g or 0, b or 0))
return self
end
--------------------------------
-- @module Sprite
local Sprite = c.Sprite
-- start --
--------------------------------
-- 设置当前精灵的显示帧
-- @function [parent=#Sprite] displayFrame
-- @param mixed frame 要显示的图片名或图片帧的frame
-- @return Sprite#Sprite 当前精灵
-- end --
function Sprite:displayFrame(frame)
self:setSpriteFrame(frame)
return self
end
-- start --
--------------------------------
-- 在X方向上翻转当前精灵
-- @function [parent=#Sprite] flipX
-- @param boolean b 是否翻转
-- @return Sprite#Sprite 当前精灵
-- end --
function Sprite:flipX(b)
self:setFlippedX(b)
return self
end
-- start --
--------------------------------
-- 在Y方向上翻转当前精灵
-- @function [parent=#Sprite] flipY
-- @param boolean b 是否翻转
-- @return Sprite#Sprite 当前精灵
-- end --
function Sprite:flipY(b)
self:setFlippedY(b)
return self
end

View File

@@ -0,0 +1,87 @@
function tolua.cloneTable(src)
if type(src)~="table" then
return nil
end
local dest = {}
for k, v in pairs(src) do
dest[k] = v
end
local mt = getmetatable(src)
if mt then
setmetatable(dest, mt)
end
return dest
end
if CCPoint then
tolua.default_gc_classes__ = {
-- "CCAtlasNode",
-- "ccBezierConfig",
-- "ccBlendFunc",
-- "CCBool",
-- "CCCamera",
"ccColor3B",
"ccColor4B",
"ccColor4F",
-- "CCDouble",
-- "CCFloat",
-- "ccFontDefinition",
-- "CCImage",
-- "CCInteger",
-- "CCLabelBMFont",
-- "CCLabelTTF",
-- "CCParticleSystemQuad",
"CCPoint",
"CCRect",
-- "CCScrollView",
"CCSize",
-- "CCTableView",
-- "ccTexParams",
-- "CCTileMapAtlas",
-- "CCTMXLayer",
-- "CCTMXLayerInfo",
-- "CCTMXMapInfo",
-- "CCTMXTilesetInfo",
-- "cc_timeval",
-- "HSV",
-- "RGBA",
}
else
tolua.default_gc_classes__ = {
}
end
function tolua.fullgc(classes)
collectgarbage("collect")
if classes == nil then
classes = tolua.default_gc_classes__
elseif type(classes) == "string" then
classes = {classes}
elseif type(classes) ~= "table" then
classes = tolua.default_gc_classes__
end
local o = tolua.getregval("tolua_gc")
local t = tolua.cloneTable(o)
if t then
tolua.setregval("tolua_gc", t)
end
for i,v in ipairs(classes) do
o = tolua.getubox(v)
t = tolua.cloneTable(o)
if o then
tolua.setubox(v, t)
end
end
o = nil
t = nil
collectgarbage("collect")
end

View File

@@ -1,12 +1,10 @@
require "config"
require "cocos.init"
local function main()
require("app.MyApp"):create():run()
function __G__TRACKBACK__(errorMessage)
print("----------------------------------------")
print("LUA ERROR: " .. tostring(errorMessage) .. "\n")
print(debug.traceback("", 2))
print("----------------------------------------")
end
local status, msg = xpcall(main, __G__TRACKBACK__)
if not status then
print(msg)
end
package.path = package.path .. ";src/?.lua;src/framework/protobuf/?.lua"
require("app.MyApp").new():run()

View File

@@ -1,67 +0,0 @@
local AppBase = class("AppBase")
function AppBase:ctor(configs)
self.configs_ = {
viewsRoot = "app.views",
modelsRoot = "app.models",
defaultSceneName = "MainScene",
}
for k, v in pairs(configs or {}) do
self.configs_[k] = v
end
if type(self.configs_.viewsRoot) ~= "table" then
self.configs_.viewsRoot = {self.configs_.viewsRoot}
end
if type(self.configs_.modelsRoot) ~= "table" then
self.configs_.modelsRoot = {self.configs_.modelsRoot}
end
if DEBUG > 1 then
dump(self.configs_, "AppBase configs")
end
if CC_SHOW_FPS then
cc.Director:getInstance():setDisplayStats(true)
end
-- event
self:onCreate()
end
function AppBase:run(initSceneName)
initSceneName = initSceneName or self.configs_.defaultSceneName
self:enterScene(initSceneName)
end
function AppBase:enterScene(sceneName, transition, time, more)
local view = self:createView(sceneName)
view:showWithScene(transition, time, more)
return view
end
function AppBase:createView(name)
for _, root in ipairs(self.configs_.viewsRoot) do
local packageName = string.format("%s.%s", root, name)
local status, view = xpcall(function()
return require(packageName)
end, function(msg)
if not string.find(msg, string.format("'%s' not found:", packageName)) then
print("load view error: ", msg)
end
end)
local t = type(view)
if status and (t == "table" or t == "userdata") then
return view:create(self, name)
end
end
error(string.format("AppBase:createView() - not found view \"%s\" in search paths \"%s\"",
name, table.concat(self.configs_.viewsRoot, ",")), 0)
end
function AppBase:onCreate()
end
return AppBase

View File

@@ -1,68 +0,0 @@
local ViewBase = class("ViewBase", cc.Node)
function ViewBase:ctor(app, name)
self:enableNodeEvents()
self.app_ = app
self.name_ = name
-- check CSB resource file
local res = rawget(self.class, "RESOURCE_FILENAME")
if res then
self:createResourceNode(res)
end
local binding = rawget(self.class, "RESOURCE_BINDING")
if res and binding then
self:createResourceBinding(binding)
end
if self.onCreate then self:onCreate() end
end
function ViewBase:getApp()
return self.app_
end
function ViewBase:getName()
return self.name_
end
function ViewBase:getResourceNode()
return self.resourceNode_
end
function ViewBase:createResourceNode(resourceFilename)
if self.resourceNode_ then
self.resourceNode_:removeSelf()
self.resourceNode_ = nil
end
self.resourceNode_ = cc.CSLoader:createNode(resourceFilename)
assert(self.resourceNode_, string.format("ViewBase:createResourceNode() - load resouce node from file \"%s\" failed", resourceFilename))
self:addChild(self.resourceNode_)
end
function ViewBase:createResourceBinding(binding)
assert(self.resourceNode_, "ViewBase:createResourceBinding() - not load resource node")
for nodeName, nodeBinding in pairs(binding) do
local node = self.resourceNode_:getChildByName(nodeName)
if nodeBinding.varname then
self[nodeBinding.varname] = node
end
for _, event in ipairs(nodeBinding.events or {}) do
if event.event == "touch" then
node:onTouch(handler(self, self[event.method]))
end
end
end
end
function ViewBase:showWithScene(transition, time, more)
self:setVisible(true)
local scene = display.newScene(self.name_)
scene:addChild(self)
display.runScene(scene, transition, time, more)
return self
end
return ViewBase

View File

@@ -1,7 +0,0 @@
local _M = {}
_M.AppBase = import(".AppBase")
_M.ViewBase = import(".ViewBase")
return _M

0
templates/src/sproto.lua Executable file → Normal file
View File

0
templates/src/sprotoparser.lua Executable file → Normal file
View File

View File

@@ -132,18 +132,13 @@ def createProject(packageName, outputDir, isLandscape, needCopyCocos2d):
print("====> Copying template.")
createRootPath(outputDir)
copyDir(templateRoot, outputDir)
print("====> Copying cocos.")
shutil.copytree(joinDir(engineRoot, "cocos", "scripting", "lua-bindings", "script"), joinDir(outputDir, "src", "cocos"))
if needCopyCocos2d:
print("====> Copying cocos sources.")
os.mkdir(joinDir(outputDir, "frameworks", "cocos2d-x"))
for dirName in ["cmake", "cocos", "extensions", "external"]:
shutil.copytree(joinDir(engineRoot, dirName), joinDir(outputDir, "frameworks", "cocos2d-x", dirName))
# for fileName in ["CHANGELOG", "VERSION", "README.md"]:
# copyFile(joinDir(engineRoot, fileName), joinDir(outputDir, "frameworks", "cocos2d-x", fileName))
copyFile(joinDir(engineRoot, "cocos", "scripting", "lua-bindings", "manual", "lua_module_register.h"), joinDir(outputDir, "frameworks", "runtime-src", "Classes", "lua_module_register.h"))
shutil.rmtree(joinDir(outputDir, "frameworks", "cocos2d-x", "cocos", "scripting", "lua-bindings", "script")) # remove double files
print("====> Done.")
if __name__ == "__main__":