Files
mir_server/Gateway/srvlib/3rd/tolua++/lua/class.lua
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

221 lines
5.5 KiB
Lua

-- tolua: class class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: class.lua 1004 2006-02-27 13:03:20Z lindquist $
-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications.
-- Class class
-- Represents a class definition.
-- Stores the following fields:
-- name = class name
-- base = class base, if any (only single inheritance is supported)
-- {i} = list of members
classClass = {
classtype = 'class',
name = '',
base = '',
type = '',
btype = '',
ctype = '',
}
classClass.__index = classClass
setmetatable(classClass,classContainer)
-- register class
function classClass:register (pre)
if not self:check_public_access() then
return
end
pre = pre or ''
push(self)
if _collect[self.type] then
output(pre,'#ifdef __cplusplus\n')
output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",'.._collect[self.type]..');')
output(pre,'#else\n')
output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",NULL);')
output(pre,'#endif\n')
else
output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",NULL);')
end
if self.extra_bases then
for k,base in ipairs(self.extra_bases) do
-- not now
--output(pre..' tolua_addbase(tolua_S, "'..self.type..'", "'..base..'");')
end
end
output(pre..'tolua_beginmodule(tolua_S,(char*)"'..self.lname..'");')
local i=1
while self[i] do
self[i]:register(pre..' ')
i = i+1
end
output(pre..'tolua_endmodule(tolua_S);')
pop()
end
-- return collection requirement
function classClass:requirecollection (t)
if self.flags.protected_destructor then
return false
end
push(self)
local r = false
local i=1
while self[i] do
r = self[i]:requirecollection(t) or r
i = i+1
end
pop()
-- only class that exports destructor can be appropriately collected
-- classes that export constructors need to have a collector (overrided by -D flag on command line)
if self._delete or ((not flags['D']) and self._new) then
--t[self.type] = "tolua_collect_" .. gsub(self.type,"::","_")
t[self.type] = "tolua_collect_" .. clean_template(self.type)
r = true
end
return r
end
-- output tags
function classClass:decltype ()
push(self)
self.type = regtype(self.original_name or self.name)
self.btype = typevar(self.base)
self.ctype = 'const '..self.type
if self.extra_bases then
for i=1,table.getn(self.extra_bases) do
self.extra_bases[i] = typevar(self.extra_bases[i])
end
end
local i=1
while self[i] do
self[i]:decltype()
i = i+1
end
pop()
end
-- Print method
function classClass:print (ident,close)
print(ident.."Class{")
print(ident.." name = '"..self.name.."',")
print(ident.." base = '"..self.base.."';")
print(ident.." lname = '"..self.lname.."',")
print(ident.." type = '"..self.type.."',")
print(ident.." btype = '"..self.btype.."',")
print(ident.." ctype = '"..self.ctype.."',")
local i=1
while self[i] do
self[i]:print(ident.." ",",")
i = i+1
end
print(ident.."}"..close)
end
function classClass:set_protected_destructor(p)
self.flags.protected_destructor = self.flags.protected_destructor or p
end
-- Internal constructor
function _Class (t)
setmetatable(t,classClass)
t:buildnames()
append(t)
return t
end
-- Constructor
-- Expects the name, the base (array) and the body of the class.
function Class (n,p,b)
if table.getn(p) > 1 then
b = string.sub(b, 1, -2)
for i=2,table.getn(p),1 do
b = b.."\n tolua_inherits "..p[i].." __"..p[i].."__;\n"
end
b = b.."\n}"
end
-- check for template
b = string.gsub(b, "^{%s*TEMPLATE_BIND", "{\nTOLUA_TEMPLATE_BIND")
local t,_,T,I = string.find(b, "^{%s*TOLUA_TEMPLATE_BIND%s*%(+%s*\"?([^\",]*)\"?%s*,%s*([^%)]*)%s*%)+")
if t then
-- remove quotes
I = string.gsub(I, "\"", "")
T = string.gsub(T, "\"", "")
-- get type list
local types = split_c_tokens(I, ",")
-- remove TEMPLATE_BIND line
local bs = string.gsub(b, "^{%s*TOLUA_TEMPLATE_BIND[^\n]*\n", "{\n")
-- replace
for i =1 , types.n do
local Tl = split(T, " ")
local Il = split_c_tokens(types[i], " ")
local bI = bs
local pI = {}
for j = 1,Tl.n do
Tl[j] = findtype(Tl[j]) or Tl[j]
bI = string.gsub(bI, "([^_%w])"..Tl[j].."([^_%w])", "%1"..Il[j].."%2")
if p then
for i=1,table.getn(p) do
pI[i] = string.gsub(p[i], "([^_%w]?)"..Tl[j].."([^_%w]?)", "%1"..Il[j].."%2")
end
end
end
--local append = "<"..string.gsub(types[i], "%s+", ",")..">"
local append = "<"..concat(Il, 1, table.getn(Il), ",")..">"
append = string.gsub(append, "%s*,%s*", ",")
append = string.gsub(append, ">>", "> >")
for i=1,table.getn(pI) do
--pI[i] = string.gsub(pI[i], ">>", "> >")
pI[i] = resolve_template_types(pI[i])
end
bI = string.gsub(bI, ">>", "> >")
Class(n..append, pI, bI)
end
return
end
local mbase
if p then
mbase = table.remove(p, 1)
if not p[1] then p = nil end
end
mbase = mbase and resolve_template_types(mbase)
local c
local oname = string.gsub(n, "@.*$", "")
oname = getnamespace(classContainer.curr)..oname
if _global_classes[oname] then
c = _global_classes[oname]
if mbase and ((not c.base) or c.base == "") then
c.base = mbase
end
else
c = _Class(_Container{name=n, base=mbase, extra_bases=p})
local ft = getnamespace(c.parent)..c.original_name
append_global_type(ft, c)
end
push(c)
c:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces
pop()
end