📄 container.lua
字号:
-- tolua: container abstract class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: container.lua 1141 2006-05-18 23:58:45Z 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.
-- table to store namespaced typedefs/enums in global scope
global_typedefs = {}
global_enums = {}
-- Container class
-- Represents a container of features to be bound
-- to lua.
classContainer =
{
curr = nil,
}
classContainer.__index = classContainer
setmetatable(classContainer,classFeature)
-- output tags
function classContainer:decltype ()
push(self)
local i=1
while self[i] do
self[i]:decltype()
i = i+1
end
pop()
end
-- write support code
function classContainer:supcode ()
if not self:check_public_access() then
return
end
push(self)
local i=1
while self[i] do
if self[i]:check_public_access() then
self[i]:supcode()
end
i = i+1
end
pop()
end
function classContainer:hasvar ()
local i=1
while self[i] do
if self[i]:isvariable() then
return 1
end
i = i+1
end
return 0
end
-- Internal container constructor
function _Container (self)
setmetatable(self,classContainer)
self.n = 0
self.typedefs = {tolua_n=0}
self.usertypes = {}
self.enums = {tolua_n=0}
self.lnames = {}
return self
end
-- push container
function push (t)
t.prox = classContainer.curr
classContainer.curr = t
end
-- pop container
function pop ()
--print("name",classContainer.curr.name)
--foreach(classContainer.curr.usertypes,print)
--print("______________")
classContainer.curr = classContainer.curr.prox
end
-- get current namespace
function getcurrnamespace ()
return getnamespace(classContainer.curr)
end
-- append to current container
function append (t)
return classContainer.curr:append(t)
end
-- append typedef to current container
function appendtypedef (t)
return classContainer.curr:appendtypedef(t)
end
-- append usertype to current container
function appendusertype (t)
return classContainer.curr:appendusertype(t)
end
-- append enum to current container
function appendenum (t)
return classContainer.curr:appendenum(t)
end
-- substitute typedef
function applytypedef (mod,type)
return classContainer.curr:applytypedef(mod,type)
end
-- check if is type
function findtype (type)
local t = classContainer.curr:findtype(type)
return t
end
-- check if is typedef
function istypedef (type)
return classContainer.curr:istypedef(type)
end
-- get fulltype (with namespace)
function fulltype (t)
local curr = classContainer.curr
while curr do
if curr then
if curr.typedefs and curr.typedefs[t] then
return curr.typedefs[t]
elseif curr.usertypes and curr.usertypes[t] then
return curr.usertypes[t]
end
end
curr = curr.prox
end
return t
end
-- checks if it requires collection
function classContainer:requirecollection (t)
push(self)
local i=1
local r = false
while self[i] do
r = self[i]:requirecollection(t) or r
i = i+1
end
pop()
return r
end
-- get namesapce
function getnamespace (curr)
local namespace = ''
while curr do
if curr and
( curr.classtype == 'class' or curr.classtype == 'namespace')
then
namespace = (curr.original_name or curr.name) .. '::' .. namespace
--namespace = curr.name .. '::' .. namespace
end
curr = curr.prox
end
return namespace
end
-- get namespace (only namespace)
function getonlynamespace ()
local curr = classContainer.curr
local namespace = ''
while curr do
if curr.classtype == 'class' then
return namespace
elseif curr.classtype == 'namespace' then
namespace = curr.name .. '::' .. namespace
end
curr = curr.prox
end
return namespace
end
-- check if is enum
function isenum (type)
return classContainer.curr:isenum(type)
end
-- append feature to container
function classContainer:append (t)
self.n = self.n + 1
self[self.n] = t
t.parent = self
end
-- append typedef
function classContainer:appendtypedef (t)
local namespace = getnamespace(classContainer.curr)
self.typedefs.tolua_n = self.typedefs.tolua_n + 1
self.typedefs[self.typedefs.tolua_n] = t
self.typedefs[t.utype] = namespace .. t.utype
global_typedefs[namespace..t.utype] = t
t.ftype = findtype(t.type) or t.type
--print("appending typedef "..t.utype.." as "..namespace..t.utype.." with ftype "..t.ftype)
append_global_type(namespace..t.utype)
if t.ftype and isenum(t.ftype) then
global_enums[namespace..t.utype] = true
end
end
-- append usertype: return full type
function classContainer:appendusertype (t)
local container
if t == (self.original_name or self.name) then
container = self.prox
else
container = self
end
local ft = getnamespace(container) .. t
container.usertypes[t] = ft
_usertype[ft] = ft
return ft
end
-- append enum
function classContainer:appendenum (t)
local namespace = getnamespace(classContainer.curr)
self.enums.tolua_n = self.enums.tolua_n + 1
self.enums[self.enums.tolua_n] = t
global_enums[namespace..t.name] = t
end
-- determine lua function name overload
function classContainer:overload (lname)
if not self.lnames[lname] then
self.lnames[lname] = 0
else
self.lnames[lname] = self.lnames[lname] + 1
end
return format("%02d",self.lnames[lname])
end
-- applies typedef: returns the 'the facto' modifier and type
function classContainer:applytypedef (mod,type)
if global_typedefs[type] then
--print("found typedef "..global_typedefs[type].type)
local mod1, type1 = global_typedefs[type].mod, global_typedefs[type].ftype
local mod2, type2 = applytypedef(mod.." "..mod1, type1)
--return mod2 .. ' ' .. mod1, type2
return mod2, type2
end
do return mod,type end
end
-- check if it is a typedef
function classContainer:istypedef (type)
local env = self
while env do
if env.typedefs then
local i=1
while env.typedefs[i] do
if env.typedefs[i].utype == type then
return type
end
i = i+1
end
end
env = env.parent
end
return nil
end
function find_enum_var(var)
if tonumber(var) then return var end
local c = classContainer.curr
while c do
local ns = getnamespace(c)
for k,v in pairs(_global_enums) do
if match_type(var, v, ns) then
return v
end
end
if c.base and c.base ~= '' then
c = _global_classes[c:findtype(c.base)]
else
c = nil
end
end
return var
end
-- check if is a registered type: return full type or nil
function classContainer:findtype (t)
t = string.gsub(t, "=.*", "")
if _basic[t] then
return t
end
local _,_,em = string.find(t, "([&%*])%s*$")
t = string.gsub(t, "%s*([&%*])%s*$", "")
p = self
while p and type(p)=='table' do
local st = getnamespace(p)
for i=_global_types.n,1,-1 do -- in reverse order
if match_type(t, _global_types[i], st) then
return _global_types[i]..(em or "")
end
end
if p.base and p.base ~= '' and p.base ~= t then
--print("type is "..t..", p is "..p.base.." self.type is "..self.type.." self.name is "..self.name)
p = _global_classes[p:findtype(p.base)]
else
p = nil
end
end
return nil
end
function append_global_type(t, class)
_global_types.n = _global_types.n +1
_global_types[_global_types.n] = t
_global_types_hash[t] = 1
if class then append_class_type(t, class) end
end
function append_class_type(t,class)
if _global_classes[t] then
class.flags = _global_classes[t].flags
class.lnames = _global_classes[t].lnames
if _global_classes[t].base and (_global_classes[t].base ~= '') then
class.base = _global_classes[t].base or class.base
end
end
_global_classes[t] = class
class.flags = class.flags or {}
end
function match_type(childtype, regtype, st)
--print("findtype "..childtype..", "..regtype..", "..st)
local b,e = string.find(regtype, childtype, -string.len(childtype), true)
if b then
if e == string.len(regtype) and
(b == 1 or (string.sub(regtype, b-1, b-1) == ':' and
string.sub(regtype, 1, b-1) == string.sub(st, 1, b-1))) then
return true
end
end
return false
end
function findtype_on_childs(self, t)
local tchild
if self.classtype == 'class' or self.classtype == 'namespace' then
for k,v in ipairs(self) do
if v.classtype == 'class' or v.classtype == 'namespace' then
if v.typedefs and v.typedefs[t] then
return v.typedefs[t]
elseif v.usertypes and v.usertypes[t] then
return v.usertypes[t]
end
tchild = findtype_on_childs(v, t)
if tchild then return tchild end
end
end
end
return nil
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -