summaryrefslogtreecommitdiffstats
path: root/source/virtual_method_hooks.lua
diff options
context:
space:
mode:
authorAlexander Harkness <bearbin@gmail.com>2013-07-29 13:13:03 +0200
committerAlexander Harkness <bearbin@gmail.com>2013-07-29 13:13:03 +0200
commit53e22b11857fed62e2313d6d84d90f88ed412ffb (patch)
treec61e56725da7dff0154d566722651e2c39c9d6c6 /source/virtual_method_hooks.lua
parentWebAdmin: Removed the duplicate memory usage querying (diff)
downloadcuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.tar
cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.tar.gz
cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.tar.bz2
cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.tar.lz
cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.tar.xz
cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.tar.zst
cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.zip
Diffstat (limited to 'source/virtual_method_hooks.lua')
-rw-r--r--source/virtual_method_hooks.lua1012
1 files changed, 506 insertions, 506 deletions
diff --git a/source/virtual_method_hooks.lua b/source/virtual_method_hooks.lua
index 407b61627..b6cbe8268 100644
--- a/source/virtual_method_hooks.lua
+++ b/source/virtual_method_hooks.lua
@@ -1,506 +1,506 @@
--- flags
-local disable_virtual_hooks = false
-local enable_pure_virtual = true
-local default_private_access = false
-
-local access = {public = 0, protected = 1, private = 2}
-
-function preparse_hook(p)
-
- if default_private_access then
- -- we need to make all structs 'public' by default
- p.code = string.gsub(p.code, "(struct[^;]*{)", "%1\npublic:\n")
- end
-end
-
-
-function parser_hook(s)
-
- local container = classContainer.curr -- get the current container
-
- if default_private_access then
- if not container.curr_member_access and container.classtype == 'class' then
- -- default access for classes is private
- container.curr_member_access = access.private
- end
- end
-
- -- try labels (public, private, etc)
- do
- local b,e,label = string.find(s, "^%s*(%w*)%s*:[^:]") -- we need to check for [^:], otherwise it would match 'namespace::type'
- if b then
-
- -- found a label, get the new access value from the global 'access' table
- if access[label] then
- container.curr_member_access = access[label]
- end -- else ?
-
- return strsub(s, e) -- normally we would use 'e+1', but we need to preserve the [^:]
- end
- end
-
-
- local ret = nil
-
- if disable_virtual_hooks then
-
- return ret
- end
-
- local b,e,decl,arg = string.find(s, "^%s*virtual%s+([^%({~]+)(%b())")
- local const
- if b then
- local ret = string.sub(s, e+1)
- if string.find(ret, "^%s*const") then
- const = "const"
- ret = string.gsub(ret, "^%s*const", "")
- end
- local purev = false
- if string.find(ret, "^%s*=%s*0") then
- purev = true
- ret = string.gsub(ret, "^%s*=%s*0", "")
- end
- ret = string.gsub(ret, "^%s*%b{}", "")
-
- local func = Function(decl, arg, const)
- func.pure_virtual = purev
- --func.access = access
- func.original_sig = decl
-
- local curflags = classContainer.curr.flags
- if not curflags.virtual_class then
-
- curflags.virtual_class = VirtualClass()
- end
- curflags.virtual_class:add(func)
- curflags.pure_virtual = curflags.pure_virtual or purev
-
- return ret
- end
-
- return ret
-end
-
-
--- class VirtualClass
-classVirtualClass = {
- classtype = 'class',
- name = '',
- base = '',
- type = '',
- btype = '',
- ctype = '',
-}
-classVirtualClass.__index = classVirtualClass
-setmetatable(classVirtualClass,classClass)
-
-function classVirtualClass:add(f)
-
- local parent = classContainer.curr
- pop()
-
- table.insert(self.methods, {f=f})
-
- local name,sig
-
- -- doble negative means positive
- if f.name == 'new' and ((not self.flags.parent_object.flags.pure_virtual) or (enable_pure_virtual)) then
-
- name = self.original_name
- elseif f.name == 'delete' then
- name = '~'..self.original_name
- else
- if f.access ~= 2 and (not f.pure_virtual) and f.name ~= 'new' and f.name ~= 'delete' then
- name = f.mod.." "..f.type..f.ptr.." "..self.flags.parent_object.lname.."__"..f.name
- end
- end
-
- if name then
- sig = name..self:get_arg_list(f, true)..";\n"
- push(self)
- sig = preprocess(sig)
- self:parse(sig)
- pop()
- end
-
- push(parent)
-end
-
-function preprocess(sig)
-
- sig = gsub(sig,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
- sig = gsub(sig,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
- sig = gsub(sig,"([^%w_])char%s*%*","%1_cstring ") -- substitute 'char*'
- sig = gsub(sig,"([^%w_])lua_State%s*%*","%1_lstate ") -- substitute 'lua_State*'
-
- return sig
-end
-
-function classVirtualClass:get_arg_list(f, decl)
-
- local ret = ""
- local sep = ""
- local i=1
- while f.args[i] do
-
- local arg = f.args[i]
- if decl then
- local ptr
- if arg.ret ~= '' then
- ptr = arg.ret
- else
- ptr = arg.ptr
- end
- local def = ""
- if arg.def and arg.def ~= "" then
-
- def = " = "..arg.def
- end
- ret = ret..sep..arg.mod.." "..arg.type..ptr.." "..arg.name..def
- else
- ret = ret..sep..arg.name
- end
-
- sep = ","
- i = i+1
- end
-
- return "("..ret..")"
-end
-
-function classVirtualClass:add_parent_virtual_methods(parent)
-
- parent = parent or _global_classes[self.flags.parent_object.btype]
-
- if not parent then return end
-
- if parent.flags.virtual_class then
-
- local vclass = parent.flags.virtual_class
- for k,v in ipairs(vclass.methods) do
- if v.f.name ~= 'new' and v.f.name ~= 'delete' and (not self:has_method(v.f)) then
- table.insert(self.methods, {f=v.f})
- end
- end
- end
-
- parent = _global_classes[parent.btype]
- if parent then
- self:add_parent_virtual_methods(parent)
- end
-end
-
-function classVirtualClass:has_method(f)
-
- for k,v in pairs(self.methods) do
- -- just match name for now
- if v.f.name == f.name then
- return true
- end
- end
-
- return false
-end
-
-function classVirtualClass:add_constructors()
-
- local i=1
- while self.flags.parent_object[i] do
-
- local v = self.flags.parent_object[i]
- if getmetatable(v) == classFunction and (v.name == 'new' or v.name == 'delete') then
-
- self:add(v)
- end
-
- i = i+1
- end
-
-end
-
---[[
-function classVirtualClass:requirecollection(t)
-
- self:add_constructors()
- local req = classClass.requirecollection(self, t)
- if req then
- output('class ',self.name,";")
- end
- return req
-end
---]]
-
-function classVirtualClass:supcode()
-
- -- pure virtual classes can have no default constructors on gcc 4
-
- if self.flags.parent_object.flags.pure_virtual and not enable_pure_virtual then
- output('#if (__GNUC__ == 4) || (__GNUC__ > 4 ) // I hope this works on Microsoft Visual studio .net server 2003 XP Compiler\n')
- end
-
- local ns
- if self.prox.classtype == 'namespace' then
- output('namespace ',self.prox.name, " {")
- ns = true
- end
-
- output("class "..self.original_name.." : public "..self.btype..", public ToluaBase {")
-
- output("public:\n")
-
- self:add_parent_virtual_methods()
-
- self:output_methods(self.btype)
- self:output_parent_methods()
-
- self:add_constructors()
-
- -- no constructor for pure virtual classes
- if (not self.flags.parent_object.flags.pure_virtual) or enable_pure_virtual then
-
- self:output_constructors()
- end
-
- output("};\n\n")
-
- if ns then
- output("};")
- end
-
- classClass.supcode(self)
-
- if self.flags.parent_object.flags.pure_virtual and not enable_pure_virtual then
- output('#endif // __GNUC__ >= 4\n')
- end
-
- -- output collector for custom class if required
- if self:requirecollection(_collect) and _collect[self.type] then
-
- output('\n')
- output('/* function to release collected object via destructor */')
- output('#ifdef __cplusplus\n')
- --for i,v in pairs(collect) do
- i,v = self.type, _collect[self.type]
- output('\nstatic int '..v..' (lua_State* tolua_S)')
- output('{')
- output(' '..i..'* self = ('..i..'*) tolua_tousertype(tolua_S,1,0);')
- output(' delete self;')
- output(' return 0;')
- output('}')
- --end
- output('#endif\n\n')
- end
-
-end
-
-function classVirtualClass:register(pre)
-
- -- pure virtual classes can have no default constructors on gcc 4
- if self.flags.parent_object.flags.pure_virtual and not enable_pure_virtual then
- output('#if (__GNUC__ == 4) || (__GNUC__ > 4 )\n')
- end
-
- classClass.register(self, pre)
-
- if self.flags.parent_object.flags.pure_virtual and not enable_pure_virtual then
- output('#endif // __GNUC__ >= 4\n')
- end
-end
-
-
---function classVirtualClass:requirecollection(_c)
--- if self.flags.parent_object.flags.pure_virtual then
--- return false
--- end
--- return classClass.requirecollection(self, _c)
---end
-
-function classVirtualClass:output_parent_methods()
-
- for k,v in ipairs(self.methods) do
-
- if v.f.access ~= 2 and (not v.f.pure_virtual) and v.f.name ~= 'new' and v.f.name ~= 'delete' then
-
- local rettype = v.f.mod.." "..v.f.type..v.f.ptr.." "
- local parent_name = rettype..self.btype.."__"..v.f.name
-
- local par_list = self:get_arg_list(v.f, true)
- local var_list = self:get_arg_list(v.f, false)
-
- -- the parent's virtual function
- output("\t"..parent_name..par_list.." {")
-
- output("\t\treturn (",rettype,")"..self.btype.."::"..v.f.name..var_list..";")
- output("\t};")
- end
- end
-end
-
-function classVirtualClass:output_methods(btype)
-
- for k,v in ipairs(self.methods) do
-
- if v.f.name ~= 'new' and v.f.name ~= 'delete' then
-
- self:output_method(v.f, btype)
- end
- end
- output("\n")
-end
-
-function classVirtualClass:output_constructors()
-
- for k,v in ipairs(self.methods) do
-
- if v.f.name == 'new' then
-
- local par_list = self:get_arg_list(v.f, true)
- local var_list = self:get_arg_list(v.f, false)
-
- output("\t",self.original_name,par_list,":",self.btype,var_list,"{};")
- end
- end
-end
-
-function classVirtualClass:output_method(f, btype)
-
- if f.access == 2 then -- private
- return
- end
-
- local ptr
- if f.ret ~= '' then
- ptr = f.ret
- else
- ptr = f.ptr
- end
-
- local rettype = f.mod.." "..f.type..f.ptr.." "
- local par_list = self:get_arg_list(f, true)
- local var_list = self:get_arg_list(f, false)
-
- if string.find(rettype, "%s*LuaQtGenericFlags%s*") then
-
- _,_,rettype = string.find(f.original_sig, "^%s*([^%s]+)%s+")
- end
-
- -- the caller of the lua method
- output("\t"..rettype.." "..f.name..par_list..f.const.." {")
- local fn = f.cname
- if f.access == 1 then
- fn = "NULL"
- end
- output('\t\tif (push_method("',f.lname,'", ',fn,')) {')
-
- --if f.type ~= 'void' then
- -- output("\t\t\tint top = lua_gettop(lua_state)-1;")
- --end
-
- -- push the parameters
- local argn = 0
- for i,arg in ipairs(f.args) do
- if arg.type ~= 'void' then
- local t,ct = isbasic(arg.type)
- if t and t ~= '' then
- if arg.ret == "*" then
- t = 'userdata'
- ct = 'void*'
- end
- output("\t\t\ttolua_push"..t.."(lua_state, ("..ct..")"..arg.name..");");
- else
- local m = arg.ptr
- if m and m~= "" then
- if m == "*" then m = "" end
- output("\t\t\ttolua_pushusertype(lua_state, (void*)"..m..arg.name..", \""..arg.type.."\");")
- else
- output("\t\t\tvoid* tolua_obj" .. argn .." = (void*)new "..arg.type.."("..arg.name..");\n")
- output('\t\t\ttolua_pushusertype_and_takeownership(lua_state, tolua_obj' .. argn .. ', "'..arg.type..'");\n')
- end
- end
- argn = argn+1
- end
- end
-
- -- call the function
- output("\t\t\tToluaBase::dbcall(lua_state, ",argn+1,", ")
-
- -- return value
- if f.type ~= 'void' then
- output("1);")
-
- local t,ct = isbasic(f.type)
- if t and t ~= '' then
- --output("\t\t\treturn ("..rettype..")tolua_to"..t.."(lua_state, top, 0);")
- output("\t\t\t",rettype,"tolua_ret = ("..rettype..")tolua_to"..t.."(lua_state, -1, 0);")
- else
-
- local mod = ""
- if f.ptr ~= "*" then
- mod = "*("..f.type.."*)"
- end
-
- --output("\t\t\treturn ("..rettype..")"..mod.."tolua_tousertype(lua_state, top, 0);")
- output("\t\t\t",rettype,"tolua_ret = ("..rettype..")"..mod.."tolua_tousertype(lua_state, -1, 0);")
- end
- output("\t\t\tlua_pop(lua_state, 1);")
- output("\t\t\treturn tolua_ret;")
- else
- output("0);")
- end
-
- -- handle non-implemeted function
- output("\t\t} else {")
-
- if f.pure_virtual then
-
- output('\t\t\tif (lua_state)')
- --output('\t\t\t\ttolua_error(lua_state, "pure-virtual method '..btype.."::"..f.name..' not implemented.", NULL);')
- output('\t\t\t\tLOG("pure-virtual method '..btype.."::"..f.name..' not implemented.");')
- output('\t\t\telse {')
- output('\t\t\t\tLOG("pure-virtual method '..btype.."::"..f.name..' called with no lua_state. Aborting");')
- output('\t\t\t\t::abort();')
- output('\t\t\t};')
- if( rettype == " std::string " ) then
- output('\t\t\treturn "";')
- else
- output('\t\t\treturn (',rettype,')0;')
- end
- else
-
- output('\t\t\treturn (',rettype,')',btype,'::',f.name,var_list,';')
- end
-
- output("\t\t};")
-
- output("\t};")
-end
-
-function VirtualClass()
-
- local parent = classContainer.curr
- pop()
-
- local name = "Lua__"..parent.original_name
-
- local c = _Class(_Container{name=name, base=parent.name, extra_bases=nil})
- setmetatable(c, classVirtualClass)
-
- local ft = getnamespace(c.parent)..c.original_name
- append_global_type(ft, c)
-
- push(parent)
-
- c.flags.parent_object = parent
- c.methods = {}
-
- push(c)
- c:parse("\nvoid tolua__set_instance(_lstate L, lua_Object lo);\n")
- pop()
-
- return c
-end
-
-
-
-
-
+-- flags
+local disable_virtual_hooks = false
+local enable_pure_virtual = true
+local default_private_access = false
+
+local access = {public = 0, protected = 1, private = 2}
+
+function preparse_hook(p)
+
+ if default_private_access then
+ -- we need to make all structs 'public' by default
+ p.code = string.gsub(p.code, "(struct[^;]*{)", "%1\npublic:\n")
+ end
+end
+
+
+function parser_hook(s)
+
+ local container = classContainer.curr -- get the current container
+
+ if default_private_access then
+ if not container.curr_member_access and container.classtype == 'class' then
+ -- default access for classes is private
+ container.curr_member_access = access.private
+ end
+ end
+
+ -- try labels (public, private, etc)
+ do
+ local b,e,label = string.find(s, "^%s*(%w*)%s*:[^:]") -- we need to check for [^:], otherwise it would match 'namespace::type'
+ if b then
+
+ -- found a label, get the new access value from the global 'access' table
+ if access[label] then
+ container.curr_member_access = access[label]
+ end -- else ?
+
+ return strsub(s, e) -- normally we would use 'e+1', but we need to preserve the [^:]
+ end
+ end
+
+
+ local ret = nil
+
+ if disable_virtual_hooks then
+
+ return ret
+ end
+
+ local b,e,decl,arg = string.find(s, "^%s*virtual%s+([^%({~]+)(%b())")
+ local const
+ if b then
+ local ret = string.sub(s, e+1)
+ if string.find(ret, "^%s*const") then
+ const = "const"
+ ret = string.gsub(ret, "^%s*const", "")
+ end
+ local purev = false
+ if string.find(ret, "^%s*=%s*0") then
+ purev = true
+ ret = string.gsub(ret, "^%s*=%s*0", "")
+ end
+ ret = string.gsub(ret, "^%s*%b{}", "")
+
+ local func = Function(decl, arg, const)
+ func.pure_virtual = purev
+ --func.access = access
+ func.original_sig = decl
+
+ local curflags = classContainer.curr.flags
+ if not curflags.virtual_class then
+
+ curflags.virtual_class = VirtualClass()
+ end
+ curflags.virtual_class:add(func)
+ curflags.pure_virtual = curflags.pure_virtual or purev
+
+ return ret
+ end
+
+ return ret
+end
+
+
+-- class VirtualClass
+classVirtualClass = {
+ classtype = 'class',
+ name = '',
+ base = '',
+ type = '',
+ btype = '',
+ ctype = '',
+}
+classVirtualClass.__index = classVirtualClass
+setmetatable(classVirtualClass,classClass)
+
+function classVirtualClass:add(f)
+
+ local parent = classContainer.curr
+ pop()
+
+ table.insert(self.methods, {f=f})
+
+ local name,sig
+
+ -- doble negative means positive
+ if f.name == 'new' and ((not self.flags.parent_object.flags.pure_virtual) or (enable_pure_virtual)) then
+
+ name = self.original_name
+ elseif f.name == 'delete' then
+ name = '~'..self.original_name
+ else
+ if f.access ~= 2 and (not f.pure_virtual) and f.name ~= 'new' and f.name ~= 'delete' then
+ name = f.mod.." "..f.type..f.ptr.." "..self.flags.parent_object.lname.."__"..f.name
+ end
+ end
+
+ if name then
+ sig = name..self:get_arg_list(f, true)..";\n"
+ push(self)
+ sig = preprocess(sig)
+ self:parse(sig)
+ pop()
+ end
+
+ push(parent)
+end
+
+function preprocess(sig)
+
+ sig = gsub(sig,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
+ sig = gsub(sig,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
+ sig = gsub(sig,"([^%w_])char%s*%*","%1_cstring ") -- substitute 'char*'
+ sig = gsub(sig,"([^%w_])lua_State%s*%*","%1_lstate ") -- substitute 'lua_State*'
+
+ return sig
+end
+
+function classVirtualClass:get_arg_list(f, decl)
+
+ local ret = ""
+ local sep = ""
+ local i=1
+ while f.args[i] do
+
+ local arg = f.args[i]
+ if decl then
+ local ptr
+ if arg.ret ~= '' then
+ ptr = arg.ret
+ else
+ ptr = arg.ptr
+ end
+ local def = ""
+ if arg.def and arg.def ~= "" then
+
+ def = " = "..arg.def
+ end
+ ret = ret..sep..arg.mod.." "..arg.type..ptr.." "..arg.name..def
+ else
+ ret = ret..sep..arg.name
+ end
+
+ sep = ","
+ i = i+1
+ end
+
+ return "("..ret..")"
+end
+
+function classVirtualClass:add_parent_virtual_methods(parent)
+
+ parent = parent or _global_classes[self.flags.parent_object.btype]
+
+ if not parent then return end
+
+ if parent.flags.virtual_class then
+
+ local vclass = parent.flags.virtual_class
+ for k,v in ipairs(vclass.methods) do
+ if v.f.name ~= 'new' and v.f.name ~= 'delete' and (not self:has_method(v.f)) then
+ table.insert(self.methods, {f=v.f})
+ end
+ end
+ end
+
+ parent = _global_classes[parent.btype]
+ if parent then
+ self:add_parent_virtual_methods(parent)
+ end
+end
+
+function classVirtualClass:has_method(f)
+
+ for k,v in pairs(self.methods) do
+ -- just match name for now
+ if v.f.name == f.name then
+ return true
+ end
+ end
+
+ return false
+end
+
+function classVirtualClass:add_constructors()
+
+ local i=1
+ while self.flags.parent_object[i] do
+
+ local v = self.flags.parent_object[i]
+ if getmetatable(v) == classFunction and (v.name == 'new' or v.name == 'delete') then
+
+ self:add(v)
+ end
+
+ i = i+1
+ end
+
+end
+
+--[[
+function classVirtualClass:requirecollection(t)
+
+ self:add_constructors()
+ local req = classClass.requirecollection(self, t)
+ if req then
+ output('class ',self.name,";")
+ end
+ return req
+end
+--]]
+
+function classVirtualClass:supcode()
+
+ -- pure virtual classes can have no default constructors on gcc 4
+
+ if self.flags.parent_object.flags.pure_virtual and not enable_pure_virtual then
+ output('#if (__GNUC__ == 4) || (__GNUC__ > 4 ) // I hope this works on Microsoft Visual studio .net server 2003 XP Compiler\n')
+ end
+
+ local ns
+ if self.prox.classtype == 'namespace' then
+ output('namespace ',self.prox.name, " {")
+ ns = true
+ end
+
+ output("class "..self.original_name.." : public "..self.btype..", public ToluaBase {")
+
+ output("public:\n")
+
+ self:add_parent_virtual_methods()
+
+ self:output_methods(self.btype)
+ self:output_parent_methods()
+
+ self:add_constructors()
+
+ -- no constructor for pure virtual classes
+ if (not self.flags.parent_object.flags.pure_virtual) or enable_pure_virtual then
+
+ self:output_constructors()
+ end
+
+ output("};\n\n")
+
+ if ns then
+ output("};")
+ end
+
+ classClass.supcode(self)
+
+ if self.flags.parent_object.flags.pure_virtual and not enable_pure_virtual then
+ output('#endif // __GNUC__ >= 4\n')
+ end
+
+ -- output collector for custom class if required
+ if self:requirecollection(_collect) and _collect[self.type] then
+
+ output('\n')
+ output('/* function to release collected object via destructor */')
+ output('#ifdef __cplusplus\n')
+ --for i,v in pairs(collect) do
+ i,v = self.type, _collect[self.type]
+ output('\nstatic int '..v..' (lua_State* tolua_S)')
+ output('{')
+ output(' '..i..'* self = ('..i..'*) tolua_tousertype(tolua_S,1,0);')
+ output(' delete self;')
+ output(' return 0;')
+ output('}')
+ --end
+ output('#endif\n\n')
+ end
+
+end
+
+function classVirtualClass:register(pre)
+
+ -- pure virtual classes can have no default constructors on gcc 4
+ if self.flags.parent_object.flags.pure_virtual and not enable_pure_virtual then
+ output('#if (__GNUC__ == 4) || (__GNUC__ > 4 )\n')
+ end
+
+ classClass.register(self, pre)
+
+ if self.flags.parent_object.flags.pure_virtual and not enable_pure_virtual then
+ output('#endif // __GNUC__ >= 4\n')
+ end
+end
+
+
+--function classVirtualClass:requirecollection(_c)
+-- if self.flags.parent_object.flags.pure_virtual then
+-- return false
+-- end
+-- return classClass.requirecollection(self, _c)
+--end
+
+function classVirtualClass:output_parent_methods()
+
+ for k,v in ipairs(self.methods) do
+
+ if v.f.access ~= 2 and (not v.f.pure_virtual) and v.f.name ~= 'new' and v.f.name ~= 'delete' then
+
+ local rettype = v.f.mod.." "..v.f.type..v.f.ptr.." "
+ local parent_name = rettype..self.btype.."__"..v.f.name
+
+ local par_list = self:get_arg_list(v.f, true)
+ local var_list = self:get_arg_list(v.f, false)
+
+ -- the parent's virtual function
+ output("\t"..parent_name..par_list.." {")
+
+ output("\t\treturn (",rettype,")"..self.btype.."::"..v.f.name..var_list..";")
+ output("\t};")
+ end
+ end
+end
+
+function classVirtualClass:output_methods(btype)
+
+ for k,v in ipairs(self.methods) do
+
+ if v.f.name ~= 'new' and v.f.name ~= 'delete' then
+
+ self:output_method(v.f, btype)
+ end
+ end
+ output("\n")
+end
+
+function classVirtualClass:output_constructors()
+
+ for k,v in ipairs(self.methods) do
+
+ if v.f.name == 'new' then
+
+ local par_list = self:get_arg_list(v.f, true)
+ local var_list = self:get_arg_list(v.f, false)
+
+ output("\t",self.original_name,par_list,":",self.btype,var_list,"{};")
+ end
+ end
+end
+
+function classVirtualClass:output_method(f, btype)
+
+ if f.access == 2 then -- private
+ return
+ end
+
+ local ptr
+ if f.ret ~= '' then
+ ptr = f.ret
+ else
+ ptr = f.ptr
+ end
+
+ local rettype = f.mod.." "..f.type..f.ptr.." "
+ local par_list = self:get_arg_list(f, true)
+ local var_list = self:get_arg_list(f, false)
+
+ if string.find(rettype, "%s*LuaQtGenericFlags%s*") then
+
+ _,_,rettype = string.find(f.original_sig, "^%s*([^%s]+)%s+")
+ end
+
+ -- the caller of the lua method
+ output("\t"..rettype.." "..f.name..par_list..f.const.." {")
+ local fn = f.cname
+ if f.access == 1 then
+ fn = "NULL"
+ end
+ output('\t\tif (push_method("',f.lname,'", ',fn,')) {')
+
+ --if f.type ~= 'void' then
+ -- output("\t\t\tint top = lua_gettop(lua_state)-1;")
+ --end
+
+ -- push the parameters
+ local argn = 0
+ for i,arg in ipairs(f.args) do
+ if arg.type ~= 'void' then
+ local t,ct = isbasic(arg.type)
+ if t and t ~= '' then
+ if arg.ret == "*" then
+ t = 'userdata'
+ ct = 'void*'
+ end
+ output("\t\t\ttolua_push"..t.."(lua_state, ("..ct..")"..arg.name..");");
+ else
+ local m = arg.ptr
+ if m and m~= "" then
+ if m == "*" then m = "" end
+ output("\t\t\ttolua_pushusertype(lua_state, (void*)"..m..arg.name..", \""..arg.type.."\");")
+ else
+ output("\t\t\tvoid* tolua_obj" .. argn .." = (void*)new "..arg.type.."("..arg.name..");\n")
+ output('\t\t\ttolua_pushusertype_and_takeownership(lua_state, tolua_obj' .. argn .. ', "'..arg.type..'");\n')
+ end
+ end
+ argn = argn+1
+ end
+ end
+
+ -- call the function
+ output("\t\t\tToluaBase::dbcall(lua_state, ",argn+1,", ")
+
+ -- return value
+ if f.type ~= 'void' then
+ output("1);")
+
+ local t,ct = isbasic(f.type)
+ if t and t ~= '' then
+ --output("\t\t\treturn ("..rettype..")tolua_to"..t.."(lua_state, top, 0);")
+ output("\t\t\t",rettype,"tolua_ret = ("..rettype..")tolua_to"..t.."(lua_state, -1, 0);")
+ else
+
+ local mod = ""
+ if f.ptr ~= "*" then
+ mod = "*("..f.type.."*)"
+ end
+
+ --output("\t\t\treturn ("..rettype..")"..mod.."tolua_tousertype(lua_state, top, 0);")
+ output("\t\t\t",rettype,"tolua_ret = ("..rettype..")"..mod.."tolua_tousertype(lua_state, -1, 0);")
+ end
+ output("\t\t\tlua_pop(lua_state, 1);")
+ output("\t\t\treturn tolua_ret;")
+ else
+ output("0);")
+ end
+
+ -- handle non-implemeted function
+ output("\t\t} else {")
+
+ if f.pure_virtual then
+
+ output('\t\t\tif (lua_state)')
+ --output('\t\t\t\ttolua_error(lua_state, "pure-virtual method '..btype.."::"..f.name..' not implemented.", NULL);')
+ output('\t\t\t\tLOG("pure-virtual method '..btype.."::"..f.name..' not implemented.");')
+ output('\t\t\telse {')
+ output('\t\t\t\tLOG("pure-virtual method '..btype.."::"..f.name..' called with no lua_state. Aborting");')
+ output('\t\t\t\t::abort();')
+ output('\t\t\t};')
+ if( rettype == " std::string " ) then
+ output('\t\t\treturn "";')
+ else
+ output('\t\t\treturn (',rettype,')0;')
+ end
+ else
+
+ output('\t\t\treturn (',rettype,')',btype,'::',f.name,var_list,';')
+ end
+
+ output("\t\t};")
+
+ output("\t};")
+end
+
+function VirtualClass()
+
+ local parent = classContainer.curr
+ pop()
+
+ local name = "Lua__"..parent.original_name
+
+ local c = _Class(_Container{name=name, base=parent.name, extra_bases=nil})
+ setmetatable(c, classVirtualClass)
+
+ local ft = getnamespace(c.parent)..c.original_name
+ append_global_type(ft, c)
+
+ push(parent)
+
+ c.flags.parent_object = parent
+ c.methods = {}
+
+ push(c)
+ c:parse("\nvoid tolua__set_instance(_lstate L, lua_Object lo);\n")
+ pop()
+
+ return c
+end
+
+
+
+
+