541 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
		
		
			
		
	
	
			541 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| 
								 | 
							
								--[[
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								]]
							 | 
						||
| 
								 | 
							
								local function dump_value_(v)
							 | 
						||
| 
								 | 
							
								    if type(v) == "string" then
							 | 
						||
| 
								 | 
							
								        v = "\"" .. v .. "\""
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    return tostring(v)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function dump(value, desciption, 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, desciption, indent, nest, keylen)
							 | 
						||
| 
								 | 
							
								        desciption = desciption or "<var>"
							 | 
						||
| 
								 | 
							
								        local spc = ""
							 | 
						||
| 
								 | 
							
								        if type(keylen) == "number" then
							 | 
						||
| 
								 | 
							
								            spc = string.rep(" ", keylen - string.len(dump_value_(desciption)))
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								        if type(value) ~= "table" then
							 | 
						||
| 
								 | 
							
								            result[#result +1 ] = string.format("%s%s%s = %s", indent, dump_value_(desciption), spc, dump_value_(value))
							 | 
						||
| 
								 | 
							
								        elseif lookupTable[tostring(value)] then
							 | 
						||
| 
								 | 
							
								            result[#result +1 ] = string.format("%s%s%s = *REF*", indent, dump_value_(desciption), spc)
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								            lookupTable[tostring(value)] = true
							 | 
						||
| 
								 | 
							
								            if nest > nesting then
							 | 
						||
| 
								 | 
							
								                result[#result +1 ] = string.format("%s%s = *MAX NESTING*", indent, dump_value_(desciption))
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								                result[#result +1 ] = string.format("%s%s = {", indent, dump_value_(desciption))
							 | 
						||
| 
								 | 
							
								                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, desciption, "- ", 1)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for i, line in ipairs(result) do
							 | 
						||
| 
								 | 
							
								        print(line)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								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
							 | 
						||
| 
								 | 
							
								        --@TODO: no tolua here
							 | 
						||
| 
								 | 
							
								        --[[
							 | 
						||
| 
								 | 
							
								        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,shallow)
							 | 
						||
| 
								 | 
							
								    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 new_table = {}
							 | 
						||
| 
								 | 
							
								        lookup_table[object] = new_table
							 | 
						||
| 
								 | 
							
								        for key, value in pairs(object) do
							 | 
						||
| 
								 | 
							
								            new_table[_copy(key)] = _copy(value)
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								        if shallow then
							 | 
						||
| 
								 | 
							
								            return new_table
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								            return setmetatable(new_table, getmetatable(object))
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    return _copy(object)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local classTb,hotswap = {},true
							 | 
						||
| 
								 | 
							
								local function _unpack(t,i)
							 | 
						||
| 
								 | 
							
								    i = i or 1
							 | 
						||
| 
								 | 
							
								    if i <= #t then
							 | 
						||
| 
								 | 
							
								        return t[i],_unpack(t,i+1)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								local function _pack(...)
							 | 
						||
| 
								 | 
							
								    local n = select('#', ...)
							 | 
						||
| 
								 | 
							
								    local t = {}
							 | 
						||
| 
								 | 
							
								    for i = 1, n do
							 | 
						||
| 
								 | 
							
								        t[i] = select(i, ...)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    return t
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function class(module, classname, super)
							 | 
						||
| 
								 | 
							
								    if classname == nil and super == nil then
							 | 
						||
| 
								 | 
							
								        module , classname = nil , module
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    local superType = type(super)
							 | 
						||
| 
								 | 
							
								    local class
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								    if superType ~= "function" and superType ~= "table" then
							 | 
						||
| 
								 | 
							
								        superType = nil
							 | 
						||
| 
								 | 
							
								        super = nil
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								    if superType == "function" or (super and super.__ctype == 1) then
							 | 
						||
| 
								 | 
							
								        -- inherited from native C++ Object
							 | 
						||
| 
								 | 
							
								        class = {}
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								        if superType == "table" then
							 | 
						||
| 
								 | 
							
								            -- copy fields from super
							 | 
						||
| 
								 | 
							
								            for k,v in pairs(super) do class[k] = v end
							 | 
						||
| 
								 | 
							
								            class.__create = super.__create
							 | 
						||
| 
								 | 
							
								            class.super    = super
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								            class.__create = super
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								        class.ctor    = function() end
							 | 
						||
| 
								 | 
							
								        class.__cname = classname
							 | 
						||
| 
								 | 
							
								        class.__ctype = 1
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								        function class.new(...)
							 | 
						||
| 
								 | 
							
								            local instance = class.__create(...)
							 | 
						||
| 
								 | 
							
								            -- copy fields from class to native object
							 | 
						||
| 
								 | 
							
								            for k,v in pairs(class) do instance[k] = v end
							 | 
						||
| 
								 | 
							
								            instance.class = class
							 | 
						||
| 
								 | 
							
								            instance:ctor(...)
							 | 
						||
| 
								 | 
							
								            return instance
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								        -- inherited from Lua Object
							 | 
						||
| 
								 | 
							
								        if super then
							 | 
						||
| 
								 | 
							
								            -- class = clone(super)
							 | 
						||
| 
								 | 
							
								            class = setmetatable({}, {__index = super})
							 | 
						||
| 
								 | 
							
								            class.super = super
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								            class = {ctor = function() end}
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								        class.__cname = classname
							 | 
						||
| 
								 | 
							
								        class.__ctype = 2 -- lua
							 | 
						||
| 
								 | 
							
								        class.__index = class
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								        function class.new(...)
							 | 
						||
| 
								 | 
							
								            local instance = setmetatable({}, class)
							 | 
						||
| 
								 | 
							
								            -- local instance = clone(class)
							 | 
						||
| 
								 | 
							
								            -- instance = setmetatable(instance, instance.super)
							 | 
						||
| 
								 | 
							
								            instance.class = class
							 | 
						||
| 
								 | 
							
								            instance:ctor(...)
							 | 
						||
| 
								 | 
							
								            return instance
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    if module ~= nil then
							 | 
						||
| 
								 | 
							
								        module[classname] = class
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    return class
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isKindofClass(obj, class)
							 | 
						||
| 
								 | 
							
								    local t = type(obj)
							 | 
						||
| 
								 | 
							
								    if t ~= "table" then return false end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    local mt = obj.class
							 | 
						||
| 
								 | 
							
								    while mt do
							 | 
						||
| 
								 | 
							
								        if mt == class then
							 | 
						||
| 
								 | 
							
								            return true
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								            mt = mt.super
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    return false
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function class_new(classname, ...)
							 | 
						||
| 
								 | 
							
								    local class = {__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(class.__create == nil,
							 | 
						||
| 
								 | 
							
								                string.format("class() - create class \"%s\" with more than one creating function",
							 | 
						||
| 
								 | 
							
								                    classname));
							 | 
						||
| 
								 | 
							
								            -- if super is function, set it to __create
							 | 
						||
| 
								 | 
							
								            class.__create = super
							 | 
						||
| 
								 | 
							
								        elseif superType == "table" then
							 | 
						||
| 
								 | 
							
								            if super[".isclass"] then
							 | 
						||
| 
								 | 
							
								                -- super is native class
							 | 
						||
| 
								 | 
							
								                assert(class.__create == nil,
							 | 
						||
| 
								 | 
							
								                    string.format("class() - create class \"%s\" with more than one creating function or native class",
							 | 
						||
| 
								 | 
							
								                        classname));
							 | 
						||
| 
								 | 
							
								                class.__create = function() return super:create() end
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								                -- super is pure lua class
							 | 
						||
| 
								 | 
							
								                class.__supers = class.__supers or {}
							 | 
						||
| 
								 | 
							
								                class.__supers[#class.__supers + 1] = super
							 | 
						||
| 
								 | 
							
								                if not class.super then
							 | 
						||
| 
								 | 
							
								                    -- set first super pure lua class as class.super
							 | 
						||
| 
								 | 
							
								                    class.super = super
							 | 
						||
| 
								 | 
							
								                end
							 | 
						||
| 
								 | 
							
								            end
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								            error(string.format("class() - create class \"%s\" with invalid super type",
							 | 
						||
| 
								 | 
							
								                        classname), 0)
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    class.__index = class
							 | 
						||
| 
								 | 
							
								    if not class.__supers or #class.__supers == 1 then
							 | 
						||
| 
								 | 
							
								        setmetatable(class, {__index = class.super})
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								        setmetatable(class, {__index = function(_, key)
							 | 
						||
| 
								 | 
							
								            local supers = class.__supers
							 | 
						||
| 
								 | 
							
								            for i = 1, #supers do
							 | 
						||
| 
								 | 
							
								                local super = supers[i]
							 | 
						||
| 
								 | 
							
								                if super[key] then return super[key] end
							 | 
						||
| 
								 | 
							
								            end
							 | 
						||
| 
								 | 
							
								        end})
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if not class.ctor then
							 | 
						||
| 
								 | 
							
								        -- add default constructor
							 | 
						||
| 
								 | 
							
								        class.ctor = function() end
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    class.new = function(...)
							 | 
						||
| 
								 | 
							
								        local instance
							 | 
						||
| 
								 | 
							
								        if class.__create then
							 | 
						||
| 
								 | 
							
								            instance = class.__create(...)
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								            instance = {}
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								        setmetatableindex(instance, class)
							 | 
						||
| 
								 | 
							
								        instance.class = class
							 | 
						||
| 
								 | 
							
								        instance:ctor(...)
							 | 
						||
| 
								 | 
							
								        return instance
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    class.create = function(_, ...)
							 | 
						||
| 
								 | 
							
								        return class.new(...)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return class
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local iskindof_
							 | 
						||
| 
								 | 
							
								iskindof_ = function(class, name)
							 | 
						||
| 
								 | 
							
								    local __index = rawget(class, "__index")
							 | 
						||
| 
								 | 
							
								    if type(__index) == "table" and rawget(__index, "__cname") == name then return true end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if rawget(class, "__cname") == name then return true end
							 | 
						||
| 
								 | 
							
								    local __supers = rawget(class, "__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
							 | 
						||
| 
								 | 
							
								        -- TODO: reg a typeof method from slua
							 | 
						||
| 
								 | 
							
								        --[[
							 | 
						||
| 
								 | 
							
								        if tolua.iskindof(obj, classname) then return true end
							 | 
						||
| 
								 | 
							
								        mt = tolua.getpeer(obj)
							 | 
						||
| 
								 | 
							
								        ]]
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								        mt = getmetatable(obj)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    if mt then
							 | 
						||
| 
								 | 
							
								        return iskindof_(mt, classname)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    return false
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function handler(obj, method)
							 | 
						||
| 
								 | 
							
								    return function(...)
							 | 
						||
| 
								 | 
							
								        return method(obj, ...)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								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
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								-- @Nullptr and null UObject.
							 | 
						||
| 
								 | 
							
								function isValid(_object)
							 | 
						||
| 
								 | 
							
								    if _object then
							 | 
						||
| 
								 | 
							
								        --@strange that this method often causes an exception when using PreviewLine.
							 | 
						||
| 
								 | 
							
								        --local kismet = LoadClass("KismetSystemLibrary")
							 | 
						||
| 
								 | 
							
								        --return kismet:IsValid(_object)
							 | 
						||
| 
								 | 
							
								        return true
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								        return false
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local unpack = table.unpack
							 | 
						||
| 
								 | 
							
								function toDelegate(func, ...)
							 | 
						||
| 
								 | 
							
									local args = {...}
							 | 
						||
| 
								 | 
							
									local function callback(...)
							 | 
						||
| 
								 | 
							
										if select('#', ...) == 0 then
							 | 
						||
| 
								 | 
							
											func(unpack(args))
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											local len = #args
							 | 
						||
| 
								 | 
							
											if len == 0 then
							 | 
						||
| 
								 | 
							
												func(...)
							 | 
						||
| 
								 | 
							
											elseif len == 1 then
							 | 
						||
| 
								 | 
							
												func(args[1], ...)
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
												local new_args = {}
							 | 
						||
| 
								 | 
							
												for i,v in pairs(args) do
							 | 
						||
| 
								 | 
							
													table.insert(new_args,v)
							 | 
						||
| 
								 | 
							
												end
							 | 
						||
| 
								 | 
							
												for i,v in pairs({...}) do
							 | 
						||
| 
								 | 
							
													table.insert(new_args,v)
							 | 
						||
| 
								 | 
							
												end
							 | 
						||
| 
								 | 
							
												func(unpack(new_args))
							 | 
						||
| 
								 | 
							
											end
							 | 
						||
| 
								 | 
							
										end
							 | 
						||
| 
								 | 
							
									end
							 | 
						||
| 
								 | 
							
									return callback
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								--------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								-- 序列化为字符串 ...
							 | 
						||
| 
								 | 
							
								--------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								function serialize(obj)
							 | 
						||
| 
								 | 
							
								    local lua = ""
							 | 
						||
| 
								 | 
							
								    local t = type(obj)
							 | 
						||
| 
								 | 
							
								    if t == "number" then
							 | 
						||
| 
								 | 
							
								        lua = lua .. obj
							 | 
						||
| 
								 | 
							
								    elseif t == "boolean" then
							 | 
						||
| 
								 | 
							
								        lua = lua .. tostring(obj)
							 | 
						||
| 
								 | 
							
								    elseif t == "string" then
							 | 
						||
| 
								 | 
							
								        lua = lua .. string.format("%q", obj)
							 | 
						||
| 
								 | 
							
								    elseif t == "table" then
							 | 
						||
| 
								 | 
							
								        lua = lua .. "{\n"
							 | 
						||
| 
								 | 
							
								    for k, v in pairs(obj) do
							 | 
						||
| 
								 | 
							
								        lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    local metatable = getmetatable(obj)
							 | 
						||
| 
								 | 
							
								        if metatable ~= nil and type(metatable.__index) == "table" then
							 | 
						||
| 
								 | 
							
								        for k, v in pairs(metatable.__index) do
							 | 
						||
| 
								 | 
							
								            lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								        lua = lua .. "}"
							 | 
						||
| 
								 | 
							
								    elseif t == "nil" then
							 | 
						||
| 
								 | 
							
								        return nil
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								        error("can not serialize a " .. t .. " type.")
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    return lua
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								--------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								-- 从字符串反序列化 ...
							 | 
						||
| 
								 | 
							
								--------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								function unserialize(lua)
							 | 
						||
| 
								 | 
							
								    local t = type(lua)
							 | 
						||
| 
								 | 
							
								    if t == "nil" or lua == "" then
							 | 
						||
| 
								 | 
							
								        return nil
							 | 
						||
| 
								 | 
							
								    elseif t == "number" or t == "string" or t == "boolean" then
							 | 
						||
| 
								 | 
							
								        lua = tostring(lua)
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								        error("can not unserialize a " .. t .. " type.")
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    lua = "return " .. lua
							 | 
						||
| 
								 | 
							
								    -- 5.3 replaced loadstring with load
							 | 
						||
| 
								 | 
							
								    local func = load(lua)
							 | 
						||
| 
								 | 
							
								    if func == nil then
							 | 
						||
| 
								 | 
							
								        return nil
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    return func()
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								-- @Note: this is only a simplicity to avoid writing if-else, while
							 | 
						||
| 
								 | 
							
								-- taking no responsibility to call a interrupt and return to parent stack.
							 | 
						||
| 
								 | 
							
								-- The reason lua assert is not recommanded to use is that it has a chance leading
							 | 
						||
| 
								 | 
							
								-- to memory leak in our project.
							 | 
						||
| 
								 | 
							
								function check(condition, msg)
							 | 
						||
| 
								 | 
							
								    if not condition then
							 | 
						||
| 
								 | 
							
								        logE(msg)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								_G.class = class
							 |