1
-- tolua: variable class
2
-- Written by Waldemar Celes
5
-- $Id: tlx_variable.lua 14751 2008-06-14 15:24:19Z cazfi $
7
-- This code is free software; you can redistribute it and/or modify it.
8
-- The software provided hereunder is on an "as is" basis, and
9
-- the author has no obligation to provide maintenance, support, updates,
10
-- enhancements, or modifications.
14
-- Represents a extern variable or a public member of a class.
15
-- Stores all fields present in a declaration.
17
_get = {}, -- mapped get functions
18
_set = {}, -- mapped set functions
20
classVariable.__index = classVariable
21
setmetatable(classVariable,classDeclaration)
24
function classVariable:print (ident,close)
25
print(ident.."Variable{")
26
print(ident.." mod = '"..self.mod.."',")
27
print(ident.." type = '"..self.type.."',")
28
print(ident.." ptr = '"..self.ptr.."',")
29
print(ident.." name = '"..self.name.."',")
30
print(ident.." lname = '"..self.lname.."',")
31
if self.dim then print(ident.." dim = '"..self.dim.."',") end
32
print(ident.." def = '"..self.def.."',")
33
print(ident.." ret = '"..self.ret.."',")
34
print(ident.."}"..close)
37
-- Generates C function name
38
function classVariable:cfuncname (prefix)
43
local p = self:inmodule() or self:innamespace() or self:inclass()
46
if self.parent.classtype == 'class' then
47
parent = "_" .. self.parent.type
53
if strfind(self.mod,"(unsigned)") then
54
unsigned = "_unsigned"
57
if self.ptr == "*" then ptr = "_ptr"
58
elseif self.ptr == "&" then ptr = "_ref"
61
local name = prefix .. parent .. unsigned .. "_" .. gsub(self.lname or self.name,".*::","") .. ptr
63
name = clean_template(name)
68
-- check if it is a variable
69
function classVariable:isvariable ()
74
function classVariable:getvalue ()
75
local prop_get = self.prop_get
77
if prop_get then name = prop_get.."()"
78
else name = self.name end
80
local p = self:innamespace()
81
if p and self.parent.classtype ~= 'class' then
82
return p.."::"..gsub(self.lname or self.name,".*::","")
85
if self:inclass() and self:isstatic() then
86
return self.parent.type..'::'..name
87
elseif self:inclass() then
94
function classVariable:setvalue (value)
95
local name,parent="",""
96
if self:innamespace() and not self:inclass() then parent = self:innamespace() end
97
--if self.prop_set then name = self.prop_set.."("..value..");"
98
--name = self.lname.."="..value..";" end
99
if self:inclass() then parent = self.parent.type end
100
if self.prop_set then name = self.prop_set.."("..value..");"
101
else name = self.lname.."="..value..";" end
102
--print("self.name=",self.name,"self.lname=",self.lname)
103
if self:inclass() and self:isstatic() or not self:inclass() and self:innamespace() then
104
return parent..'::'..name
105
elseif self:inclass() and not self:isstatic() then
106
return 'self->'..name
112
-- get variable pointer value
113
function classVariable:getpointervalue ()
114
local class = self:inclass()
115
local static = self.static
116
if class and static then
125
function classVariable:checkproperty()
126
if string.find(self.mod, 'tolua_property') then
127
local _,_,type = string.find(self.mod, "tolua_property__([^%s]*)")
128
type = type or "default"
129
self.prop_get,self.prop_set = get_property_methods(type, self.name)
130
self.mod = string.gsub(self.mod, "tolua_property[^%s]*", "")
134
function classVariable:checkindex()
135
if string.find(self.mod, 'tolua_index') then
136
local _,_,type = string.find(self.mod, "tolua_index__([^%s]*)")
137
type = type or "default"
138
self.prop_get,self.prop_set = get_index_methods(type, self.name)
139
self.mod = string.gsub(self.mod, "tolua_index[^%s]*", "")
143
function classVariable:checkstatic()
144
local _,_,static = strfind(self.mod,'^%s*(static)')
147
_,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
153
function classVariable:isstatic()
157
function classVariable:declself()
158
if self:inclass() and not self:isstatic() then
159
-- declare self, if the case
160
return ' '..self.parent.type..'*self = ('..self.parent.type..'*) tolua_tousertype(tolua_S,1,0);\n'..
161
'#ifndef TOLUA_RELEASE\n'..
162
' if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);\n'..
169
function classVariable:declfunc_begin(name)
171
if self:inclass() then
172
pref=pref.."/* get function:"..self.name.." of class "..self:inclass().." */\n"
174
pref=pref.."/* get function:"..self.name.." */\n"
176
return pref.."#ifndef TOLUA_DISABLE_"..name.."\n"..
177
"static int "..name.." (lua_State* tolua_S) {\n"..
181
function classVariable:declfunc_end(name,retn)
182
return " return "..tostring(retn)..";"..
184
"#endif /* #ifndef TOLUA_DISABLE_"..name.." */\n"..
188
-- Write binding functions
189
function classVariable:supcode ()
190
local class = self:inclass()
196
-- get function ------------------------------------------------
198
self.cgetname = self:cfuncname("tolua_get")
199
output(self:declfunc_begin(self.cgetname))
202
if string.find(self.mod, 'tolua_inherits') then
203
output('#ifdef __cplusplus\n')
204
output(' tolua_pushusertype(tolua_S,(void*)static_cast<'..self.type..'*>(self), "',self.type,'");')
206
output(' tolua_pushusertype(tolua_S,(void*)(('..self.type..'*)self), "',self.type,'");')
209
local t,ct = isbasic(self.type)
211
output(' tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue()..');')
214
if self.ptr == '&' or self.ptr == '' then
215
output(' tolua_pushusertype(tolua_S,(void*)&'..self:getvalue()..',"',t,'");')
217
output(' tolua_pushusertype(tolua_S,(void*)'..self:getvalue()..',"',t,'");')
222
output(self:declfunc_end(self.cgetname,1))
224
-- set function ------------------------------------------------
225
if not (strfind(self.type,'const%s+') or string.find(self.mod, 'tolua_readonly') or string.find(self.mod, 'tolua_inherits')) then
227
self.csetname = self:cfuncname("tolua_set")
228
output(self:declfunc_begin(self.csetname))
230
-- check variable type
231
output('#ifndef TOLUA_RELEASE\n')
232
output(' tolua_Error tolua_err;\n')
233
output(' if (!'..self:outchecktype(2)..') tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);')
238
if self.def ~= '' then def = self.def end
239
if self.type == 'char*' and self.dim ~= '' then -- is string
241
output(self:getvalue())
242
output(',tolua_tostring(tolua_S,2,',def,'),',self.dim,'-1);')
246
if self.ptr~='' then ptr = '*' end
248
local t = isbasic(self.type)
250
if not t and ptr=='' then val=val..'*' end
251
val=val..'(('..self.mod.." "..self.type
257
if isenum(self.type) then
260
val=val..'tolua_to'..t..'(tolua_S,2,'..def..'))'
262
val=val..'tolua_tousertype(tolua_S,2,'..def..'))'
265
output(self:setvalue(val))
268
output(self:declfunc_end(self.csetname,0))
272
function classVariable:register (pre)
273
if not self:check_public_access() then
277
local parent = self:inmodule() or self:innamespace() or self:inclass()
279
if classVariable._warning==nil then
280
warning("Mapping variable to global may degrade performance")
281
classVariable._warning = 1
284
if self.csetname then
285
output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')
287
output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')
291
-- Internal constructor
292
function _Variable (t)
293
setmetatable(t,classVariable)
299
-- Expects a string representing the variable declaration.
300
function Variable (s)
301
return _Variable (Declaration(s,'var'))