diff options
author | Mattes D <github@xoft.cz> | 2015-05-11 16:11:53 +0200 |
---|---|---|
committer | Mattes D <github@xoft.cz> | 2015-05-11 16:11:53 +0200 |
commit | 4083bc70052e8883d38a94dcd9415ed7ed271fde (patch) | |
tree | 76a8a59c3c3f35dd2afdc41da465c1280cac5ede /src/Bindings/virtual_method_hooks.lua | |
parent | Merge pull request #2000 from mc-server/CommandHandling (diff) | |
download | cuberite-4083bc70052e8883d38a94dcd9415ed7ed271fde.tar cuberite-4083bc70052e8883d38a94dcd9415ed7ed271fde.tar.gz cuberite-4083bc70052e8883d38a94dcd9415ed7ed271fde.tar.bz2 cuberite-4083bc70052e8883d38a94dcd9415ed7ed271fde.tar.lz cuberite-4083bc70052e8883d38a94dcd9415ed7ed271fde.tar.xz cuberite-4083bc70052e8883d38a94dcd9415ed7ed271fde.tar.zst cuberite-4083bc70052e8883d38a94dcd9415ed7ed271fde.zip |
Diffstat (limited to 'src/Bindings/virtual_method_hooks.lua')
-rw-r--r-- | src/Bindings/virtual_method_hooks.lua | 488 |
1 files changed, 7 insertions, 481 deletions
diff --git a/src/Bindings/virtual_method_hooks.lua b/src/Bindings/virtual_method_hooks.lua index a52728ff8..14b0bcae5 100644 --- a/src/Bindings/virtual_method_hooks.lua +++ b/src/Bindings/virtual_method_hooks.lua @@ -1,7 +1,7 @@ --- flags -local disable_virtual_hooks = true -local enable_pure_virtual = true -local default_private_access = false + +-- virtual_method_hooks.lua + +-- Implements additional processing that is done while generating the Lua bindings @@ -9,29 +9,16 @@ 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) +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) + -- process access-specifying 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' + 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 @@ -42,469 +29,8 @@ function parser_hook(s) 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 - - |