-- tolua: variable class -- Written by Waldemar Celes -- TeCGraf/PUC-Rio -- Jul 1998 -- $Id: $ -- 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. -- Variable class -- Represents a extern variable or a public member of a class. -- Stores all fields present in a declaration. classVariable = { _get = {}, -- mapped get functions _set = {}, -- mapped set functions } classVariable.__index = classVariable setmetatable(classVariable,classDeclaration) -- Print method function classVariable:print (ident,close) print(ident.."Variable{") print(ident.." mod = '"..self.mod.."',") print(ident.." type = '"..self.type.."',") print(ident.." ptr = '"..self.ptr.."',") print(ident.." name = '"..self.name.."',") if self.dim then print(ident.." dim = '"..self.dim.."',") end print(ident.." def = '"..self.def.."',") print(ident.." ret = '"..self.ret.."',") print(ident.."}"..close) end -- Generates C function name function classVariable:cfuncname (prefix) local parent = "" local unsigned = "" local ptr = "" local p = self:inmodule() or self:innamespace() or self:inclass() if p then if self.parent.classtype == 'class' then parent = "_" .. self.parent.type else parent = "_" .. p end end if strfind(self.mod,"(unsigned)") then unsigned = "_unsigned" end if self.ptr == "*" then ptr = "_ptr" elseif self.ptr == "&" then ptr = "_ref" end local name = prefix .. parent .. unsigned .. "_" .. gsub(self.lname or self.name,".*::","") .. ptr name = clean_template(name) return name end -- check if it is a variable function classVariable:isvariable () return true end -- get variable value function classVariable:getvalue (class,static, prop_get) local name if prop_get then name = prop_get.."()" else name = self.name end if class and static then return self.parent.type..'::'..name elseif class then return 'self->'..name else return name end end -- get variable pointer value function classVariable:getpointervalue (class,static) if class and static then return class..'::p' elseif class then return 'self->p' else return 'p' end end -- Write binding functions function classVariable:supcode () local class = self:inclass() local prop_get,prop_set if string.find(self.mod, 'tolua_property') then _,_,type = string.find(self.mod, "tolua_property__([^%s]*)") type = type or "default" prop_get,prop_set = get_property_methods(type, self.name) self.mod = string.gsub(self.mod, "tolua_property[^%s]*", "") end -- get function ------------------------------------------------ if class then output("/* get function:",self.name," of class ",class," */") else output("/* get function:",self.name," */") end self.cgetname = self:cfuncname("tolua_get") output("#ifndef TOLUA_DISABLE_"..self.cgetname) output("\nstatic int",self.cgetname,"(lua_State* tolua_S)") output("{") -- declare self, if the case local _,_,static = strfind(self.mod,'^%s*(static)') if class and static==nil then output(' ',self.parent.type,'*','self = ') output('(',self.parent.type,'*) ') output('tolua_tousertype(tolua_S,1,0);') elseif static then _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)') end -- check self value if class and static==nil then output('#ifndef TOLUA_RELEASE\n') output(' if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);'); output('#endif\n') end -- return value if string.find(self.mod, 'tolua_inherits') then output('#ifdef __cplusplus\n') output(' tolua_pushusertype(tolua_S,(void*)static_cast<'..self.type..'*>(self), "',self.type,'");') output('#else\n') output(' tolua_pushusertype(tolua_S,(void*)(('..self.type..'*)self), "',self.type,'");') output('#endif\n') else local t,ct = isbasic(self.type) if t then output(' tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static,prop_get)..');') else t = self.type if self.ptr == '&' or self.ptr == '' then output(' tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static,prop_get)..',"',t,'");') else output(' tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static,prop_get)..',"',t,'");') end end end output(' return 1;') output('}') output('#endif //#ifndef TOLUA_DISABLE\n') output('\n') -- set function ------------------------------------------------ if not (strfind(self.type,'const%s+') or string.find(self.mod, 'tolua_readonly') or string.find(self.mod, 'tolua_inherits')) then if class then output("/* set function:",self.name," of class ",class," */") else output("/* set function:",self.name," */") end self.csetname = self:cfuncname("tolua_set") output("#ifndef TOLUA_DISABLE_"..self.csetname) output("\nstatic int",self.csetname,"(lua_State* tolua_S)") output("{") -- declare self, if the case if class and static==nil then output(' ',self.parent.type,'*','self = ') output('(',self.parent.type,'*) ') output('tolua_tousertype(tolua_S,1,0);') -- check self value end -- check types output('#ifndef TOLUA_RELEASE\n') output(' tolua_Error tolua_err;') if class and static==nil then output(' if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);'); elseif static then _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)') end -- check variable type output(' if (!'..self:outchecktype(2)..')') output(' tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);') output('#endif\n') -- assign value local def = 0 if self.def ~= '' then def = self.def end if self.type == 'char*' and self.dim ~= '' then -- is string output(' strncpy(') if class and static then output(self.parent.type..'::'..self.name) elseif class then output('self->'..self.name) else output(self.name) end output(',tolua_tostring(tolua_S,2,',def,'),',self.dim,'-1);') else local ptr = '' if self.ptr~='' then ptr = '*' end output(' ') local name = prop_set or self.name if class and static then output(self.parent.type..'::'..name) elseif class then output('self->'..name) else output(name) end local t = isbasic(self.type) if prop_set then output('(') else output(' = ') end if not t and ptr=='' then output('*') end output('((',self.mod,self.type) if not t then output('*') end output(') ') if t then if isenum(self.type) then output('(int) ') end output('tolua_to'..t,'(tolua_S,2,',def,'))') else output('tolua_tousertype(tolua_S,2,',def,'))') end if prop_set then output(")") end output(";") end output(' return 0;') output('}') output('#endif //#ifndef TOLUA_DISABLE\n') output('\n') end end function classVariable:register (pre) if not self:check_public_access() then return end pre = pre or '' local parent = self:inmodule() or self:innamespace() or self:inclass() if not parent then if classVariable._warning==nil then warning("Mapping variable to global may degrade performance") classVariable._warning = 1 end end if self.csetname then output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');') else output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);') end end -- Internal constructor function _Variable (t) setmetatable(t,classVariable) append(t) return t end -- Constructor -- Expects a string representing the variable declaration. function Variable (s) return _Variable (Declaration(s,'var')) end