nspace.i example is working
This commit is contained in:
parent
1c5a0f8b9c
commit
295788c8a0
3 changed files with 468 additions and 156 deletions
|
|
@ -157,7 +157,8 @@ struct swig_lua_namespace {
|
|||
};
|
||||
|
||||
struct swig_lua_class {
|
||||
const char *name;
|
||||
const char *name; // Name that this class has in Lua
|
||||
const char *fqname; // Fully qualified name - Scope + class name
|
||||
swig_type_info **type;
|
||||
lua_CFunction constructor;
|
||||
void (*destructor)(void *);
|
||||
|
|
@ -511,7 +512,7 @@ SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss);
|
|||
SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State* L, swig_lua_namespace* ns)
|
||||
{
|
||||
int i = 0;
|
||||
/* There must be table at the top of the stack */
|
||||
/* There must be namespace table (not metatable) at the top of the stack */
|
||||
assert(lua_istable(L,-1));
|
||||
SWIG_Lua_InstallConstants(L, ns->ns_constants);
|
||||
|
||||
|
|
@ -539,10 +540,13 @@ SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State* L, swig_lua_namespace*
|
|||
*/
|
||||
SWIGINTERN void SWIG_Lua_add_namespace_classes(lua_State* L, swig_lua_namespace* ns)
|
||||
{
|
||||
// There must be module/namespace table at the top of the stack
|
||||
assert(lua_istable(L,-1));
|
||||
|
||||
swig_lua_class** classes = ns->ns_classes;
|
||||
|
||||
if( classes != 0 ) {
|
||||
while((*classes)->name != 0) {
|
||||
while(*classes != 0) {
|
||||
SWIG_Lua_class_register(L, *classes);
|
||||
classes++;
|
||||
}
|
||||
|
|
@ -556,6 +560,7 @@ SWIGINTERN void SWIG_Lua_add_namespace_classes(lua_State* L, swig_lua_namespace*
|
|||
*/
|
||||
SWIGINTERN int SWIG_Lua_namespace_register(lua_State* L, swig_lua_namespace* ns, bool reg)
|
||||
{
|
||||
int begin = lua_gettop(L);
|
||||
assert(lua_istable(L,-1)); /* just in case. This is supposed to be module table or parent namespace table */
|
||||
lua_checkstack(L,5);
|
||||
lua_newtable(L); /* namespace itself */
|
||||
|
|
@ -582,11 +587,14 @@ SWIGINTERN int SWIG_Lua_namespace_register(lua_State* L, swig_lua_namespace* ns,
|
|||
|
||||
// Register all functions, variables etc
|
||||
SWIG_Lua_add_namespace_details(L,ns);
|
||||
// Register classes
|
||||
SWIG_Lua_add_namespace_classes(L,ns);
|
||||
|
||||
swig_lua_namespace** sub_namespace = ns->ns_namespaces;
|
||||
if( sub_namespace != 0) {
|
||||
while((*sub_namespace)->name != 0) {
|
||||
while(*sub_namespace != 0) {
|
||||
SWIG_Lua_namespace_register(L, *sub_namespace, true);
|
||||
lua_pop(L,1); // removing sub-namespace table
|
||||
sub_namespace++;
|
||||
}
|
||||
}
|
||||
|
|
@ -596,39 +604,45 @@ SWIGINTERN int SWIG_Lua_namespace_register(lua_State* L, swig_lua_namespace* ns,
|
|||
lua_pushvalue(L,-2);
|
||||
lua_rawset(L,-4); /* add namespace to module table */
|
||||
}
|
||||
assert(lua_gettop(L) == begin+1);
|
||||
}
|
||||
/* -----------------------------------------------------------------------------
|
||||
* global variable support code: classes
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* the class.get method, performs the lookup of class attributes */
|
||||
/* the class.get method, performs the lookup of class attributes
|
||||
* Method can be called from Lua directly and recursively from itself. Thats why
|
||||
* we can't use absolute stack positions
|
||||
*/
|
||||
SWIGINTERN int SWIG_Lua_class_get(lua_State* L)
|
||||
{
|
||||
/* there should be 2 params passed in
|
||||
(1) userdata (not the meta table)
|
||||
(2) string name of the attribute
|
||||
*/
|
||||
int base = lua_gettop(L)-2;
|
||||
lua_checkstack(L,5);
|
||||
assert(lua_isuserdata(L,-2)); /* just in case */
|
||||
lua_getmetatable(L,-2); /* get the meta table */
|
||||
assert(lua_istable(L,-1)); /* just in case */
|
||||
SWIG_Lua_get_table(L,".get"); /* find the .get table */
|
||||
assert(lua_istable(L,-1)); /* just in case */
|
||||
/* look for the key in the .get table */
|
||||
lua_pushvalue(L,2); /* key */
|
||||
lua_pushvalue(L,base+2); /* key */
|
||||
lua_rawget(L,-2);
|
||||
lua_remove(L,-2); /* stack tidy, remove .get table */
|
||||
if (lua_iscfunction(L,-1))
|
||||
{ /* found it so call the fn & return its value */
|
||||
lua_pushvalue(L,1); /* the userdata */
|
||||
lua_pushvalue(L,base+1); /* the userdata */
|
||||
lua_call(L,1,1); /* 1 value in (userdata),1 out (result) */
|
||||
lua_remove(L,-2); /* stack tidy, remove metatable */
|
||||
return 1;
|
||||
}
|
||||
lua_pop(L,1); /* remove whatever was there */
|
||||
/* ok, so try the .fn table */
|
||||
SWIG_Lua_get_table(L,".fn"); /* find the .get table */
|
||||
SWIG_Lua_get_table(L,".fn"); /* find the .fn table */
|
||||
assert(lua_istable(L,-1)); /* just in case */
|
||||
lua_pushvalue(L,2); /* key */
|
||||
lua_pushvalue(L,base+2); /* key */
|
||||
lua_rawget(L,-2); /* look for the fn */
|
||||
lua_remove(L,-2); /* stack tidy, remove .fn table */
|
||||
if (lua_isfunction(L,-1)) /* note: if its a C function or lua function */
|
||||
|
|
@ -642,60 +656,197 @@ SWIGINTERN int SWIG_Lua_class_get(lua_State* L)
|
|||
SWIG_Lua_get_table(L,"__getitem"); /* find the __getitem fn */
|
||||
if (lua_iscfunction(L,-1)) /* if its there */
|
||||
{ /* found it so call the fn & return its value */
|
||||
lua_pushvalue(L,1); /* the userdata */
|
||||
lua_pushvalue(L,2); /* the parameter */
|
||||
lua_pushvalue(L,base+1); /* the userdata */
|
||||
lua_pushvalue(L,base+2); /* the parameter */
|
||||
lua_call(L,2,1); /* 2 value in (userdata),1 out (result) */
|
||||
lua_remove(L,-2); /* stack tidy, remove metatable */
|
||||
return 1;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
// Search in base classes
|
||||
// TODO: Different for elua_ltr
|
||||
SWIG_Lua_get_table(L,".bases");
|
||||
assert(lua_istable(L,-1));
|
||||
int bases_count = lua_rawlen(L,-1);
|
||||
if(bases_count>0)
|
||||
{
|
||||
int original_metatable = lua_absindex(L,-2);
|
||||
int i;
|
||||
int ret = 0; // Number of returned values
|
||||
lua_pushvalue(L,base+1); // push userdata
|
||||
lua_pushvalue(L,base+2); // Push key again
|
||||
// Trick: temporaly replacing original metatable
|
||||
// with metatable for base class and call getter
|
||||
for(i=0;i<bases_count;i++) {
|
||||
lua_rawgeti(L,-3,i+1); // get base metatable here
|
||||
assert(lua_istable(L,-1));
|
||||
assert(lua_isuserdata(L,-3));
|
||||
lua_setmetatable(L,-3); // Set new metatable
|
||||
assert(lua_isuserdata(L,-2));
|
||||
ret = SWIG_Lua_class_get(L); // Forward call
|
||||
assert(ret==0||ret==1);
|
||||
if(ret>0)
|
||||
break;
|
||||
}
|
||||
// Return original metatable back
|
||||
lua_pushvalue(L,original_metatable);
|
||||
lua_setmetatable(L,base+1);
|
||||
if(ret>0)
|
||||
{
|
||||
// tidy stack. Stack currently is:
|
||||
// --base--
|
||||
// userdata
|
||||
// key
|
||||
// metatable
|
||||
// .bases table
|
||||
// userdata
|
||||
// key : -2
|
||||
// return value : -1
|
||||
lua_remove(L,-2); // remove key
|
||||
lua_remove(L,-2); // remove userdata
|
||||
lua_remove(L,-2); // remove .bases
|
||||
lua_remove(L,-2); // remove metatable
|
||||
return 1;
|
||||
} else {
|
||||
lua_pop(L,2); // remove key and userdata
|
||||
}
|
||||
}
|
||||
// Tidy stack:
|
||||
// --base--
|
||||
// userdata
|
||||
// key
|
||||
// metatable
|
||||
// .bases table
|
||||
lua_pop(L,2);
|
||||
assert(lua_gettop(L)==base+2);
|
||||
return 0; /* sorry not known */
|
||||
}
|
||||
|
||||
/* the class.set method, performs the lookup of class attributes */
|
||||
SWIGINTERN int SWIG_Lua_class_set(lua_State* L)
|
||||
/* helper for the class.set method, performs the lookup of class attributes
|
||||
* Method can be called from SWIG_Lua_class_set or recursively from itself
|
||||
*/
|
||||
SWIGINTERN int SWIG_Lua_class_do_set(lua_State* L)
|
||||
{
|
||||
/* there should be 3 params passed in
|
||||
(1) table (not the meta table)
|
||||
(2) string name of the attribute
|
||||
(3) any for the new value
|
||||
printf("SWIG_Lua_class_set %p(%s) '%s' %p(%s)\n",
|
||||
lua_topointer(L,1),lua_typename(L,lua_type(L,1)),
|
||||
lua_tostring(L,2),
|
||||
lua_topointer(L,3),lua_typename(L,lua_type(L,3)));*/
|
||||
lua_topointer(L,-3),lua_typename(L,lua_type(L,-3)),
|
||||
lua_tostring(L,-2),
|
||||
lua_topointer(L,-1),lua_typename(L,lua_type(L,-1)));*/
|
||||
|
||||
assert(lua_isuserdata(L,1)); /* just in case */
|
||||
lua_getmetatable(L,1); /* get the meta table */
|
||||
int base = lua_gettop(L) - 3;
|
||||
lua_checkstack(L,5);
|
||||
assert(lua_isuserdata(L,base+1)); /* just in case */
|
||||
lua_getmetatable(L,base+1); /* get the meta table */
|
||||
assert(lua_istable(L,-1)); /* just in case */
|
||||
|
||||
SWIG_Lua_get_table(L,".set"); /* find the .set table */
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
/* look for the key in the .set table */
|
||||
lua_pushvalue(L,2); /* key */
|
||||
lua_pushvalue(L,base+2); /* key */
|
||||
lua_rawget(L,-2);
|
||||
lua_remove(L,-2); /* tidy stack, remove .set table */
|
||||
if (lua_iscfunction(L,-1))
|
||||
{ /* found it so call the fn & return its value */
|
||||
lua_pushvalue(L,1); /* userdata */
|
||||
lua_pushvalue(L,3); /* value */
|
||||
lua_pushvalue(L,base+1); /* userdata */
|
||||
lua_pushvalue(L,base+3); /* value */
|
||||
lua_call(L,2,0);
|
||||
lua_remove(L,base+4); /*remove metatable*/
|
||||
assert(lua_gettop(L) == base+3); // TODO:REMOVE
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1); /* remove the value */
|
||||
} else {
|
||||
lua_pop(L,1); /* remove the answer for .set table request*/
|
||||
}
|
||||
lua_pop(L,1); /* remove the value .set table */
|
||||
assert(lua_gettop(L) == base + 4); // TODO: REMOVE
|
||||
/* NEW: looks for the __setitem() fn
|
||||
this is a user provided set fn */
|
||||
SWIG_Lua_get_table(L,"__setitem"); /* find the fn */
|
||||
if (lua_iscfunction(L,-1)) /* if its there */
|
||||
{ /* found it so call the fn & return its value */
|
||||
lua_pushvalue(L,1); /* the userdata */
|
||||
lua_pushvalue(L,2); /* the parameter */
|
||||
lua_pushvalue(L,3); /* the value */
|
||||
lua_pushvalue(L,base+1); /* the userdata */
|
||||
lua_pushvalue(L,base+2); /* the parameter */
|
||||
lua_pushvalue(L,base+3); /* the value */
|
||||
lua_call(L,3,0); /* 3 values in ,0 out */
|
||||
lua_remove(L,-2); /* stack tidy, remove metatable */
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1); // remove value
|
||||
assert(lua_gettop(L) == base + 4); // TODO: REMOVE
|
||||
|
||||
// Search among bases
|
||||
int original_metatable = base+4;
|
||||
assert(lua_gettop(L) == original_metatable); // Check that stack is correct
|
||||
SWIG_Lua_get_table(L,".bases");
|
||||
assert(lua_istable(L,-1));
|
||||
int bases_count = lua_rawlen(L,-1);
|
||||
if(bases_count>0)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
lua_pushvalue(L,base+1); // push userdata
|
||||
lua_pushvalue(L,base+2); // Push key again
|
||||
lua_pushvalue(L,base+3); // Push value again
|
||||
// Trick: temporaly replacing original metatable
|
||||
// with metatable for base class and call getter
|
||||
for(i=0;i<bases_count;i++) {
|
||||
lua_rawgeti(L,-4,i+1); // get base metatable here
|
||||
assert(lua_istable(L,-1));
|
||||
assert(lua_isuserdata(L,-4));
|
||||
lua_setmetatable(L,-4); // Set new metatable
|
||||
assert(lua_isuserdata(L,-3));
|
||||
ret = SWIG_Lua_class_do_set(L); // Forward call
|
||||
assert(ret==0||ret==-1);
|
||||
if(ret==0)
|
||||
break;
|
||||
}
|
||||
// Return original metatable back
|
||||
lua_pushvalue(L,original_metatable);
|
||||
lua_setmetatable(L,base+1);
|
||||
if(ret==0)
|
||||
{
|
||||
// tidy stack. Stack currently is:
|
||||
// --base--
|
||||
// userdata
|
||||
// key
|
||||
// value
|
||||
// metatable
|
||||
// .bases table
|
||||
// userdata
|
||||
// key : -2
|
||||
// value: -1
|
||||
lua_pop(L,5);
|
||||
return 0;
|
||||
} else {
|
||||
lua_pop(L,3); // remove userdata, key and value
|
||||
}
|
||||
}
|
||||
lua_pop(L,1); // remove .bases_table
|
||||
|
||||
lua_pop(L,1); // remove metatable
|
||||
assert(lua_gettop(L) == base+3);
|
||||
return -1; // Indicator that search failed
|
||||
}
|
||||
|
||||
/* This is actuall method exported to Lua. It calls SWIG_Lua_class_do_set and correctly
|
||||
* handlers return value
|
||||
*/
|
||||
SWIGINTERN int SWIG_Lua_class_set(lua_State* L)
|
||||
{
|
||||
int ret= SWIG_Lua_class_do_set(L);
|
||||
if(ret==0)
|
||||
return 0;
|
||||
else if(ret==-1) {
|
||||
SWIG_Lua_pushferrstring(L,"Assignment not possible. No setter/member with this name. For custom assignments implement __setitem method");
|
||||
lua_error(L);
|
||||
} else {
|
||||
assert(0); // Internal implementation error
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the class.destruct method called by the interpreter */
|
||||
|
|
@ -752,23 +903,6 @@ SWIGINTERN int SWIG_Lua_class_disown(lua_State* L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Constructor proxy. Used when class name entry in module is not class constructor,
|
||||
but special table instead. */
|
||||
SWIGINTERN int SWIG_Lua_constructor_proxy(lua_State* L)
|
||||
{
|
||||
/* unlimited number of parameters
|
||||
First one is our proxy table and we should remove it
|
||||
Other we should pass to real constructor
|
||||
*/
|
||||
assert(lua_istable(L,1));
|
||||
lua_pushstring(L,".constructor");
|
||||
lua_rawget(L,1);
|
||||
assert(!lua_isnil(L,-1));
|
||||
lua_replace(L,1); /* replace our table with real constructor */
|
||||
lua_call(L,lua_gettop(L)-1,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* gets the swig class registry (or creates it) */
|
||||
SWIGINTERN void SWIG_Lua_get_class_registry(lua_State* L)
|
||||
{
|
||||
|
|
@ -829,15 +963,24 @@ SWIGINTERN void SWIG_Lua_add_class_static_details(lua_State* L, swig_lua_class*
|
|||
}
|
||||
|
||||
/* helper to recursively add class details (attributes & operations) */
|
||||
SWIGINTERN void SWIG_Lua_add_class_details(lua_State* L,swig_lua_class* clss)
|
||||
SWIGINTERN void SWIG_Lua_add_class_instance_details(lua_State* L,swig_lua_class* clss)
|
||||
{
|
||||
int i;
|
||||
/* call all the base classes first: we can then override these later: */
|
||||
// Add bases to .bases table
|
||||
SWIG_Lua_get_table(L,".bases");
|
||||
assert(lua_istable(L,-1)); /* just in case */
|
||||
int bases_count = 0;
|
||||
for(i=0;clss->bases[i];i++)
|
||||
{
|
||||
SWIG_Lua_add_class_details(L,clss->bases[i]);
|
||||
SWIG_Lua_get_class_metatable(L,clss->bases[i]->fqname);
|
||||
// Base class must be already registered
|
||||
assert(lua_istable(L,-1));
|
||||
lua_rawseti(L,-2,i+1); // In lua indexing starts from 1
|
||||
bases_count++;
|
||||
}
|
||||
/* add fns */
|
||||
assert(lua_rawlen(L,-1) == bases_count);
|
||||
lua_pop(L,1); // remove .bases table
|
||||
/* add attributes */
|
||||
for(i=0;clss->attributes[i].name;i++){
|
||||
SWIG_Lua_add_variable(L,clss->attributes[i].name,clss->attributes[i].getmethod,clss->attributes[i].setmethod);
|
||||
}
|
||||
|
|
@ -851,7 +994,7 @@ SWIGINTERN void SWIG_Lua_add_class_details(lua_State* L,swig_lua_class* clss)
|
|||
/* add operator overloads
|
||||
these look ANY method which start with "__" and assume they
|
||||
are operator overloads & add them to the metatable
|
||||
(this might mess up is someone defines a method __gc (the destructor)*/
|
||||
(this might mess up if someone defines a method __gc (the destructor)*/
|
||||
for(i=0;clss->methods[i].name;i++){
|
||||
if (clss->methods[i].name[0]=='_' && clss->methods[i].name[1]=='_'){
|
||||
SWIG_Lua_add_function(L,clss->methods[i].name,clss->methods[i].func);
|
||||
|
|
@ -884,13 +1027,13 @@ SWIGINTERN void SWIG_Lua_init_base_class(lua_State* L,swig_lua_class* clss)
|
|||
/* Register class static methods,attributes etc as well as constructor proxy */
|
||||
SWIGINTERN void SWIG_Lua_class_register_static(lua_State* L, swig_lua_class* clss)
|
||||
{
|
||||
int begin = lua_gettop(L);
|
||||
lua_checkstack(L,5); /* just in case */
|
||||
assert(lua_istable(L,-1)); /* just in case */
|
||||
assert(strcmp(clss->name, clss->cls_static.name) == 0); /* in class those 2 must be equal */
|
||||
|
||||
SWIG_Lua_namespace_register(L,&clss->cls_static, false);
|
||||
SWIG_Lua_namespace_register(L,&clss->cls_static, true);
|
||||
|
||||
SWIG_Lua_get_table(L,clss->name); // Get namespace table back
|
||||
assert(lua_istable(L,-1)); /* just in case */
|
||||
|
||||
/* add its constructor to module with the name of the class
|
||||
|
|
@ -899,10 +1042,9 @@ SWIGINTERN void SWIG_Lua_class_register_static(lua_State* L, swig_lua_class* cls
|
|||
(this overcomes the problem of pure virtual classes without constructors)*/
|
||||
if (clss->constructor)
|
||||
{
|
||||
SWIG_Lua_add_function(L,".constructor", clss->constructor);
|
||||
lua_getmetatable(L,-1);
|
||||
assert(lua_istable(L,-1)); /* just in case */
|
||||
SWIG_Lua_add_function(L,"__call", SWIG_Lua_constructor_proxy);
|
||||
SWIG_Lua_add_function(L,"__call", clss->constructor);
|
||||
lua_pop(L,1);
|
||||
}
|
||||
|
||||
|
|
@ -911,19 +1053,42 @@ SWIGINTERN void SWIG_Lua_class_register_static(lua_State* L, swig_lua_class* cls
|
|||
|
||||
/* clear stack */
|
||||
lua_pop(L,1);
|
||||
assert( lua_gettop(L) == begin );
|
||||
}
|
||||
|
||||
/* performs the entire class registration process */
|
||||
SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
|
||||
/* performs the instance(non-static) class registration process. Metatable for class is created
|
||||
* and added to the class registry.
|
||||
*/
|
||||
SWIGINTERN void SWIG_Lua_class_register_instance(lua_State* L,swig_lua_class* clss)
|
||||
{
|
||||
SWIG_Lua_class_register_static(L,clss);
|
||||
|
||||
int begin = lua_gettop(L);
|
||||
// if name already there (class is already registered) then do nothing
|
||||
SWIG_Lua_get_class_registry(L); /* get the registry */
|
||||
lua_pushstring(L,clss->name); /* get the name */
|
||||
lua_pushstring(L,clss->fqname); /* get the name */
|
||||
lua_rawget(L,-2);
|
||||
if(!lua_isnil(L,-1)) {
|
||||
lua_pop(L,2);
|
||||
assert(lua_gettop(L)==begin);
|
||||
return;
|
||||
}
|
||||
lua_pop(L,2); // tidy stack
|
||||
// Recursively initialize all bases
|
||||
int i = 0;
|
||||
for(i=0;clss->bases[i];i++)
|
||||
{
|
||||
SWIG_Lua_class_register_instance(L,clss->bases[i]);
|
||||
}
|
||||
// Again, get registry and push name
|
||||
SWIG_Lua_get_class_registry(L); /* get the registry */
|
||||
lua_pushstring(L,clss->fqname); /* get the name */
|
||||
lua_newtable(L); /* create the metatable */
|
||||
/* add string of class name called ".type" */
|
||||
lua_pushstring(L,".type");
|
||||
lua_pushstring(L,clss->name);
|
||||
lua_pushstring(L,clss->fqname);
|
||||
lua_rawset(L,-3);
|
||||
/* add a table called bases */
|
||||
lua_pushstring(L,".bases");
|
||||
lua_newtable(L);
|
||||
lua_rawset(L,-3);
|
||||
/* add a table called ".get" */
|
||||
lua_pushstring(L,".get");
|
||||
|
|
@ -948,10 +1113,18 @@ SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
|
|||
/* add it */
|
||||
lua_rawset(L,-3); /* metatable into registry */
|
||||
lua_pop(L,1); /* tidy stack (remove registry) */
|
||||
assert(lua_gettop(L)==begin);
|
||||
|
||||
SWIG_Lua_get_class_metatable(L,clss->name);
|
||||
SWIG_Lua_add_class_details(L,clss); /* recursive adding of details (atts & ops) */
|
||||
SWIG_Lua_get_class_metatable(L,clss->fqname);
|
||||
SWIG_Lua_add_class_instance_details(L,clss); /* recursive adding of details (atts & ops) */
|
||||
lua_pop(L,1); /* tidy stack (remove class metatable) */
|
||||
assert( lua_gettop(L) == begin );
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
|
||||
{
|
||||
SWIG_Lua_class_register_instance(L,clss);
|
||||
SWIG_Lua_class_register_static(L,clss);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
@ -963,7 +1136,7 @@ SWIGINTERN void _SWIG_Lua_AddMetatable(lua_State* L,swig_type_info *type)
|
|||
{
|
||||
if (type->clientdata) /* there is clientdata: so add the metatable */
|
||||
{
|
||||
SWIG_Lua_get_class_metatable(L,((swig_lua_class*)(type->clientdata))->name);
|
||||
SWIG_Lua_get_class_metatable(L,((swig_lua_class*)(type->clientdata))->fqname);
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
lua_setmetatable(L,-2);
|
||||
|
|
|
|||
|
|
@ -1490,6 +1490,7 @@ int Language::membervariableHandler(Node *n) {
|
|||
Setattr(n, "type", type);
|
||||
Setattr(n, "name", name);
|
||||
Setattr(n, "sym:name", symname);
|
||||
Delattr(n, "memberset");
|
||||
|
||||
/* Delete all attached typemaps and typemap attributes */
|
||||
Iterator ki;
|
||||
|
|
@ -1507,6 +1508,7 @@ int Language::membervariableHandler(Node *n) {
|
|||
Setattr(n, "sym:name", mrename_get);
|
||||
Setattr(n, "memberget", "1");
|
||||
functionWrapper(n);
|
||||
Delattr(n, "memberget");
|
||||
}
|
||||
Delete(mrename_get);
|
||||
Delete(mrename_set);
|
||||
|
|
@ -2951,11 +2953,14 @@ int Language::constantWrapper(Node *n) {
|
|||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::variableWrapper(Node *n) {
|
||||
Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", NIL);
|
||||
Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", "?varset", "?varget", NIL);
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
SwigType *type = Getattr(n, "type");
|
||||
String *name = Getattr(n, "name");
|
||||
|
||||
Delattr(n,"varset");
|
||||
Delattr(n,"varget");
|
||||
|
||||
/* If no way to set variables. We simply create functions */
|
||||
int assignable = is_assignable(n);
|
||||
int flags = use_naturalvar_mode(n);
|
||||
|
|
@ -2986,12 +2991,14 @@ int Language::variableWrapper(Node *n) {
|
|||
Delete(pname0);
|
||||
}
|
||||
if (make_set_wrapper) {
|
||||
Setattr(n, "varset", "1");
|
||||
functionWrapper(n);
|
||||
}
|
||||
/* Restore parameters */
|
||||
Setattr(n, "sym:name", symname);
|
||||
Setattr(n, "type", type);
|
||||
Setattr(n, "name", name);
|
||||
Delattr(n, "varset");
|
||||
|
||||
/* Delete all attached typemaps and typemap attributes */
|
||||
Iterator ki;
|
||||
|
|
@ -3005,6 +3012,7 @@ int Language::variableWrapper(Node *n) {
|
|||
String *gname = Swig_name_get(NSpace, symname);
|
||||
Setattr(n, "sym:name", gname);
|
||||
Delete(gname);
|
||||
Setattr(n, "varget", "1");
|
||||
functionWrapper(n);
|
||||
Swig_restore(n);
|
||||
return SWIG_OK;
|
||||
|
|
|
|||
|
|
@ -122,13 +122,20 @@ private:
|
|||
//String *s_vars_meta_tab; // metatable for variables
|
||||
Hash* namespaces_hash;
|
||||
|
||||
// Parameters for current class. NIL if not parsing class
|
||||
int have_constructor;
|
||||
int have_destructor;
|
||||
String *destructor_action;
|
||||
String *class_symname;
|
||||
String *class_fq_symname; // Fully qualified symname - NSpace + '.' + class_symname
|
||||
String *class_static_nspace;
|
||||
String *constructor_name;
|
||||
|
||||
enum {
|
||||
// Many wrappers forward calls to each other, for example staticmembervariableHandler
|
||||
// forwards call to variableHandler, which, in turn, makes to call to functionWrapper.
|
||||
// In order to access information about whether it is static member of class or just
|
||||
// plain old variable an array current is kept and used as 'log' of call stack.
|
||||
enum TState {
|
||||
NO_CPP,
|
||||
VARIABLE,
|
||||
MEMBER_FUNC,
|
||||
|
|
@ -137,8 +144,12 @@ private:
|
|||
MEMBER_VAR,
|
||||
CLASS_CONST,
|
||||
STATIC_FUNC,
|
||||
STATIC_VAR
|
||||
}current;
|
||||
STATIC_VAR,
|
||||
STATIC_CONST, // enums and things like static const int x = 5;
|
||||
|
||||
STATES_COUNT
|
||||
};
|
||||
bool current[STATES_COUNT];
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -175,10 +186,14 @@ public:
|
|||
have_destructor(0),
|
||||
destructor_action(0),
|
||||
class_symname(0),
|
||||
constructor_name(0),
|
||||
current(NO_CPP) {
|
||||
class_fq_symname(0),
|
||||
class_static_nspace(0),
|
||||
constructor_name(0) {
|
||||
namespaces_hash = NewHash();
|
||||
for(int i = 0; i < STATES_COUNT; i++ )
|
||||
current[i] = false;
|
||||
}
|
||||
|
||||
~LUA() {
|
||||
if(namespaces_hash)
|
||||
Delete(namespaces_hash);
|
||||
|
|
@ -306,7 +321,9 @@ public:
|
|||
s_luacode = NewString("");
|
||||
Swig_register_filebyname("luacode", s_luacode);
|
||||
|
||||
current=NO_CPP;
|
||||
current[NO_CPP] = true;
|
||||
// Registering names schemes
|
||||
Swig_name_register("member", "%m");
|
||||
|
||||
/* Standard stuff for the SWIG runtime section */
|
||||
Swig_banner(f_begin);
|
||||
|
|
@ -473,6 +490,21 @@ public:
|
|||
* Create a function declaration and register it with the interpreter.
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
// Helper function. Remembers wrap name
|
||||
void rememberWrapName(Node *n, String *wrapname) {
|
||||
Setattr(n, "wrap:name", wrapname);
|
||||
// If it is getter/setter, then write wrapname under
|
||||
// wrap:memberset/wrap:memberget accordingly
|
||||
if( Getattr(n, "memberset") )
|
||||
Setattr(n, "memberset:wrap:name", wrapname);
|
||||
if( Getattr(n, "varset") )
|
||||
Setattr(n, "varset:wrap:name", wrapname);
|
||||
if( Getattr(n, "memberget") )
|
||||
Setattr(n, "memberget:wrap:name", wrapname);
|
||||
if( Getattr(n, "varget") )
|
||||
Setattr(n, "varget:wrap:name", wrapname);
|
||||
}
|
||||
|
||||
virtual int functionWrapper(Node *n) {
|
||||
REPORT("functionWrapper",n);
|
||||
|
||||
|
|
@ -491,7 +523,7 @@ public:
|
|||
if (Getattr(n, "sym:overloaded")) {
|
||||
overname = Getattr(n, "sym:overname");
|
||||
} else {
|
||||
if (!addSymbol(iname, n, getNSpace())) {
|
||||
if (!luaAddSymbol(iname, n)) {
|
||||
Printf(stderr,"addSymbol(%s) failed\n",iname);
|
||||
return SWIG_ERROR;
|
||||
}
|
||||
|
|
@ -505,11 +537,13 @@ public:
|
|||
Wrapper_add_local(f, "SWIG_arg", "int SWIG_arg = 0");
|
||||
|
||||
|
||||
String *wname = Swig_name_wrapper(iname);
|
||||
String* fqname = fully_qualified_name(iname);
|
||||
String *wname = Swig_name_wrapper(fqname);
|
||||
Delete(fqname);
|
||||
if (overname) {
|
||||
Append(wname, overname);
|
||||
}
|
||||
if (current == CONSTRUCTOR) {
|
||||
if (current[CONSTRUCTOR]) {
|
||||
if( constructor_name != 0)
|
||||
Delete(constructor_name);
|
||||
constructor_name = Copy(wname);
|
||||
|
|
@ -552,12 +586,6 @@ public:
|
|||
}
|
||||
|
||||
|
||||
/* Which input argument to start with? */
|
||||
// int start = (current == MEMBER_FUNC || current == MEMBER_VAR || current == DESTRUCTOR) ? 1 : 0;
|
||||
|
||||
/* Offset to skip over the attribute name */
|
||||
// int offset = (current == MEMBER_VAR) ? 1 : 0;
|
||||
|
||||
/* NEW LANGUAGE NOTE:***********************************************
|
||||
from here on in, it gets rather hairy
|
||||
this is the code to convert from the scripting language to C/C++
|
||||
|
|
@ -693,14 +721,7 @@ public:
|
|||
}
|
||||
|
||||
// Remember C name of the wrapping function
|
||||
Setattr(n, "wrap:name", wname);
|
||||
// If it is getter/setter, then write wname under
|
||||
// wrap:memberset/wrap:memberget accordingly
|
||||
if( Getattr(n, "memberset") )
|
||||
Setattr(n, "memberset:wrap:name", wname);
|
||||
if( Getattr(n, "memberget") )
|
||||
Setattr(n, "memberget:wrap:name", wname);
|
||||
|
||||
rememberWrapName(n, wname);
|
||||
|
||||
/* Emit the function call */
|
||||
String *actioncode = emit_action(n);
|
||||
|
|
@ -777,7 +798,7 @@ public:
|
|||
Therefore we go though the whole function,
|
||||
but do not write the code into the wrapper
|
||||
*/
|
||||
if(current!=DESTRUCTOR) {
|
||||
if(!current[DESTRUCTOR]) {
|
||||
Wrapper_print(f, f_wrappers);
|
||||
}
|
||||
|
||||
|
|
@ -789,7 +810,7 @@ public:
|
|||
if (!Getattr(n, "sym:overloaded")) {
|
||||
//REPORT("dispatchFunction", n);
|
||||
// add_method(n, iname, wname, description);
|
||||
if (current==NO_CPP || current==STATIC_FUNC) { // emit normal fns & static fns
|
||||
if (current[NO_CPP] || current[STATIC_FUNC]) { // emit normal fns & static fns
|
||||
Hash* nspaceHash = getNamespaceHash( getNSpace() );
|
||||
String* s_ns_methods_tab = Getattr(nspaceHash, "methods");
|
||||
if(elua_ltr || eluac_ltr)
|
||||
|
|
@ -877,24 +898,19 @@ public:
|
|||
Printv(f->code, "}\n", NIL);
|
||||
Wrapper_print(f, f_wrappers);
|
||||
//add_method(symname,wname,0);
|
||||
if (current==NO_CPP || current==STATIC_FUNC) { // emit normal fns & static fns
|
||||
if (current[NO_CPP] || current[STATIC_FUNC]) { // emit normal fns & static fns
|
||||
Hash* nspaceHash = getNamespaceHash( getNSpace() );
|
||||
String* s_ns_methods_tab = Getattr(nspaceHash, "methods");
|
||||
Printv(s_ns_methods_tab, tab4, "{ \"", symname, "\",", wname, "},\n", NIL);
|
||||
}
|
||||
if (current == CONSTRUCTOR) {
|
||||
if (current[CONSTRUCTOR]) {
|
||||
if( constructor_name != 0 )
|
||||
Delete(constructor_name);
|
||||
constructor_name = Copy(wname);
|
||||
}
|
||||
|
||||
Setattr(n, "wrap:name", wname);
|
||||
// If it is getter/setter, then write wname under
|
||||
// wrap:memberset/wrap:memberget accordingly
|
||||
if( Getattr(n, "memberset") )
|
||||
Setattr(n, "memberset:wrap:name", wname);
|
||||
if( Getattr(n, "memberget") )
|
||||
Setattr(n, "memberget:wrap:name", wname);
|
||||
// Remember C name of the wrapping function
|
||||
rememberWrapName(n, wname);
|
||||
|
||||
DelWrapper(f);
|
||||
Delete(dispatch);
|
||||
|
|
@ -916,13 +932,14 @@ public:
|
|||
NEW LANGUAGE NOTE:END ************************************************/
|
||||
// REPORT("variableWrapper", n);
|
||||
String *iname = Getattr(n, "sym:name");
|
||||
current=VARIABLE;
|
||||
String *unassignable = NewString("SWIG_Lua_set_immutable");
|
||||
current[VARIABLE] = true;
|
||||
// let SWIG generate the wrappers
|
||||
int result = Language::variableWrapper(n);
|
||||
current=NO_CPP;
|
||||
current[VARIABLE] = false;
|
||||
// normally SWIG will generate 2 wrappers, a get and a set
|
||||
// but in certain scenarios (immutable, or if its arrays), it will not
|
||||
String *getName = Swig_name_wrapper(Swig_name_get(getNSpace(), iname));
|
||||
String *getName = Getattr(n,"varget:wrap:name");
|
||||
String *setName = 0;
|
||||
// checking whether it can be set to or not appears to be a very error prone issue
|
||||
// I referred to the Language::variableWrapper() to find this out
|
||||
|
|
@ -934,14 +951,15 @@ public:
|
|||
Delete(tm);
|
||||
|
||||
if (assignable) {
|
||||
setName = Swig_name_wrapper(Swig_name_set(getNSpace(), iname));
|
||||
setName = Getattr(n,"varset:wrap:name");
|
||||
} else {
|
||||
// how about calling a 'this is not settable' error message?
|
||||
setName = NewString("SWIG_Lua_set_immutable"); // error message
|
||||
//setName = NewString("0");
|
||||
setName = unassignable;// error message
|
||||
}
|
||||
|
||||
// register the variable
|
||||
assert(setName != 0);
|
||||
assert(getName != 0);
|
||||
Hash* nspaceHash = getNamespaceHash( getNSpace() );
|
||||
String* s_ns_methods_tab = Getattr(nspaceHash, "methods");
|
||||
String* s_ns_var_tab = Getattr(nspaceHash, "attributes");
|
||||
|
|
@ -956,12 +974,11 @@ public:
|
|||
} else {
|
||||
Printf(s_ns_var_tab, "%s{ \"%s\", %s, %s },\n", tab4, iname, getName, setName);
|
||||
}
|
||||
if (getCurrentClass()) {
|
||||
if (getCurrentClass()) { // TODO: REMOVE
|
||||
Setattr(n, "luaclassobj:wrap:get", getName);
|
||||
Setattr(n, "luaclassobj:wrap:set", setName);
|
||||
} else {
|
||||
Delete(getName);
|
||||
Delete(setName);
|
||||
Delete(unassignable);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -978,8 +995,9 @@ public:
|
|||
String *rawval = Getattr(n, "rawval");
|
||||
String *value = rawval ? rawval : Getattr(n, "value");
|
||||
String *tm;
|
||||
//Printf( stdout, "Add constant %s, ns %s\n", iname, getNSpace() );// TODO: REMOVE
|
||||
|
||||
if (!addSymbol(iname, n, getNSpace()))
|
||||
if (!luaAddSymbol(iname, n))
|
||||
return SWIG_ERROR;
|
||||
|
||||
/* Special hook for member pointer */
|
||||
|
|
@ -1035,7 +1053,7 @@ public:
|
|||
// REPORT("nativeWrapper", n);
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
String *wrapname = Getattr(n, "wrap:name");
|
||||
if (!addSymbol(wrapname, n, getNSpace()))
|
||||
if (!luaAddSymbol(wrapname, n))
|
||||
return SWIG_ERROR;
|
||||
|
||||
Hash *nspaceHash = getNamespaceHash( getNSpace() );
|
||||
|
|
@ -1050,7 +1068,23 @@ public:
|
|||
* ------------------------------------------------------------ */
|
||||
|
||||
virtual int enumDeclaration(Node *n) {
|
||||
return Language::enumDeclaration(n);
|
||||
// enumDeclaration supplied by Language is messing with NSpace.
|
||||
// So this is the exact copy of function from Language with
|
||||
// correct handling of namespaces
|
||||
String *oldNSpace = getNSpace();
|
||||
if( getCurrentClass() == 0 ) {
|
||||
setNSpace(Getattr(n, "sym:nspace"));
|
||||
}
|
||||
|
||||
if (!ImportMode) {
|
||||
current[STATIC_CONST] = true;
|
||||
emit_children(n);
|
||||
current[STATIC_CONST] = false;
|
||||
}
|
||||
|
||||
setNSpace(oldNSpace);
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
|
|
@ -1058,7 +1092,27 @@ public:
|
|||
* ------------------------------------------------------------ */
|
||||
|
||||
virtual int enumvalueDeclaration(Node *n) {
|
||||
return Language::enumvalueDeclaration(n);
|
||||
if (getCurrentClass() && (cplus_mode != PUBLIC))
|
||||
return SWIG_NOWRAP;
|
||||
|
||||
Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
|
||||
String *value = Getattr(n, "value");
|
||||
String *name = Getattr(n, "name");
|
||||
String *tmpValue;
|
||||
|
||||
if (value)
|
||||
tmpValue = NewString(value);
|
||||
else
|
||||
tmpValue = NewString(name);
|
||||
Setattr(n, "value", tmpValue);
|
||||
|
||||
Setattr(n, "name", tmpValue); /* for wrapping of enums in a namespace when emit_action is used */
|
||||
constantWrapper(n);
|
||||
|
||||
Delete(tmpValue);
|
||||
Swig_restore(n);
|
||||
// TODO: Backward compatibility: add ClassName_ConstantName member
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
|
|
@ -1076,8 +1130,7 @@ public:
|
|||
virtual int classHandler(Node *n) {
|
||||
//REPORT("classHandler", n);
|
||||
|
||||
String *mangled_full_class_symname = 0;
|
||||
String *full_class_symname = 0;
|
||||
String *mangled_class_fq_symname = 0;
|
||||
String* nspace = getNSpace();
|
||||
String* destructor_name = 0;
|
||||
|
||||
|
|
@ -1085,19 +1138,27 @@ public:
|
|||
have_constructor = 0;
|
||||
have_destructor = 0;
|
||||
destructor_action = 0;
|
||||
assert(class_static_nspace == 0);
|
||||
assert(class_fq_symname == 0);
|
||||
assert(class_symname == 0);
|
||||
|
||||
current[NO_CPP] = false;
|
||||
|
||||
class_symname = Getattr(n, "sym:name");
|
||||
if (!addSymbol(class_symname, n, nspace))
|
||||
// We have to enforce nspace here, because technically we are already
|
||||
// inside class parsing (getCurrentClass != 0), but we should register
|
||||
// class in the it's parent namespace
|
||||
if (!luaAddSymbol(class_symname, n, nspace))
|
||||
return SWIG_ERROR;
|
||||
|
||||
if (nspace == 0)
|
||||
full_class_symname = NewStringf("%s", class_symname);
|
||||
class_fq_symname = NewStringf("%s", class_symname);
|
||||
else
|
||||
full_class_symname = NewStringf("%s.%s", nspace, class_symname);
|
||||
class_fq_symname = NewStringf("%s.%s", nspace, class_symname);
|
||||
|
||||
assert(full_class_symname != 0);
|
||||
mangled_full_class_symname = Swig_name_mangle(full_class_symname);
|
||||
Printf( stdout, "Mangled class symname %s\n", mangled_full_class_symname );
|
||||
assert(class_fq_symname != 0);
|
||||
mangled_class_fq_symname = Swig_name_mangle(class_fq_symname);
|
||||
Printf( stdout, "Mangled class symname %s\n", mangled_class_fq_symname );
|
||||
|
||||
// not sure exactly how this works,
|
||||
// but tcl has a static hashtable of all classes emitted and then only emits code for them once.
|
||||
|
|
@ -1107,9 +1168,9 @@ public:
|
|||
// * consider effect on template_specialization_defarg
|
||||
|
||||
static Hash *emitted = NewHash();
|
||||
if (Getattr(emitted, mangled_full_class_symname))
|
||||
if (Getattr(emitted, mangled_class_fq_symname))
|
||||
return SWIG_NOWRAP;
|
||||
Setattr(emitted, mangled_full_class_symname, "1");
|
||||
Setattr(emitted, mangled_class_fq_symname, "1");
|
||||
|
||||
// We treat class T as both 'class' and 'namespace'. All static members, attributes
|
||||
// and constants are considered part of namespace T, all members - part of the 'class'
|
||||
|
|
@ -1122,7 +1183,7 @@ public:
|
|||
// And we can guarantee that there will not be any name collision because names starting with 2 underscores
|
||||
// and capital letter are forbiden to use in C++. So, under know circumstances could our class contain
|
||||
// any member or subclass with name "__Static". Thus, never any name clash.
|
||||
Hash* non_static_cls = getNamespaceHash(full_class_symname, false);
|
||||
Hash* non_static_cls = getNamespaceHash(class_fq_symname, false);
|
||||
assert(non_static_cls != 0);
|
||||
s_attr_tab = Getattr(non_static_cls, "attributes");
|
||||
s_methods_tab = Getattr(non_static_cls, "methods");
|
||||
|
|
@ -1135,11 +1196,9 @@ public:
|
|||
* All constants are considered part of static part of class.
|
||||
*/
|
||||
|
||||
String *static_cls_key = NewStringf("%s%s__Static", full_class_symname, NSPACE_SEPARATOR);
|
||||
Hash *static_cls = getNamespaceHash(static_cls_key, false);
|
||||
if (static_cls == 0) {
|
||||
return SWIG_ERROR; // This cant be, so it is internal, implementation error
|
||||
}
|
||||
class_static_nspace = NewStringf("%s%s__Static", class_fq_symname, NSPACE_SEPARATOR);
|
||||
Hash *static_cls = getNamespaceHash(class_static_nspace, false);
|
||||
assert(static_cls != 0);
|
||||
Setattr(static_cls, "lua:no_namespaces", "1");
|
||||
/* TODO: REMOVE
|
||||
s_cls_methods_tab = Getattr(static_cls, "methods");
|
||||
|
|
@ -1160,17 +1219,18 @@ public:
|
|||
|
||||
// Replacing namespace with namespace + class in order to static
|
||||
// member be put inside class static area
|
||||
setNSpace(static_cls_key);
|
||||
setNSpace(class_static_nspace);
|
||||
// Generate normal wrappers
|
||||
Language::classHandler(n);
|
||||
// Restore correct nspace
|
||||
setNSpace(nspace);
|
||||
//Printf( stdout, "Class finished\n" ); TODO:REMOVE
|
||||
|
||||
SwigType *t = Copy(Getattr(n, "name"));
|
||||
SwigType_add_pointer(t);
|
||||
|
||||
// Catch all: eg. a class with only static functions and/or variables will not have 'remembered'
|
||||
String *wrap_class = NewStringf("&_wrap_class_%s", mangled_full_class_symname);
|
||||
String *wrap_class = NewStringf("&_wrap_class_%s", mangled_class_fq_symname);
|
||||
SwigType_remember_clientdata(t, wrap_class);
|
||||
|
||||
String *rt = Copy(getClassType());
|
||||
|
|
@ -1182,12 +1242,12 @@ public:
|
|||
Printv( ns_classes, wrap_class, ",\n", NIL );
|
||||
|
||||
// Register the class structure with the type checker
|
||||
// Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_full_class_symname);
|
||||
// Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_class_fq_symname);
|
||||
|
||||
// emit a function to be called to delete the object
|
||||
// TODO: class_name -> full_class_name || mangled full_class_name
|
||||
if (have_destructor) {
|
||||
destructor_name = NewStringf("swig_delete_%s", mangled_full_class_symname);
|
||||
destructor_name = NewStringf("swig_delete_%s", mangled_class_fq_symname);
|
||||
Printv(f_wrappers, "static void ", destructor_name, "(void *obj) {\n", NIL);
|
||||
if (destructor_action) {
|
||||
Printv(f_wrappers, SwigType_str(rt, "arg1"), " = (", SwigType_str(rt, 0), ") obj;\n", NIL);
|
||||
|
|
@ -1201,9 +1261,26 @@ public:
|
|||
}
|
||||
Printf(f_wrappers, "}\n");
|
||||
}
|
||||
// Wrap constructor wrapper into one more proxy function. It will be used as class namespace __call method, thus
|
||||
// allowing both
|
||||
// Module.ClassName.StaticMethod to access static method/variable/constant
|
||||
// Module.ClassName() to create new object
|
||||
if (have_constructor) {
|
||||
String* constructor_proxy_name = NewStringf("_proxy_%s", constructor_name);
|
||||
Printv(f_wrappers, "static int ", constructor_proxy_name, "(lua_State *L) {\n", NIL);
|
||||
Printv(f_wrappers,
|
||||
tab4, "assert(lua_istable(L,1));\n",
|
||||
tab4, "lua_pushcfunction(L,", constructor_name, ");\n",
|
||||
tab4, "assert(!lua_isnil(L,-1));\n",
|
||||
tab4, "lua_replace(L,1); /* replace our table with real constructor */\n",
|
||||
tab4, "lua_call(L,lua_gettop(L)-1,1);\n",
|
||||
tab4, "return 1;\n}\n", NIL);
|
||||
Delete(constructor_name);
|
||||
constructor_name = constructor_proxy_name;
|
||||
}
|
||||
|
||||
closeNamespaceHash(full_class_symname, f_wrappers);
|
||||
closeNamespaceHash(static_cls_key, f_wrappers);
|
||||
closeNamespaceHash(class_fq_symname, f_wrappers);
|
||||
closeNamespaceHash(class_static_nspace, f_wrappers);
|
||||
|
||||
|
||||
/* TODO: REMOVE
|
||||
|
|
@ -1251,12 +1328,12 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
Printv(f_wrappers, "static swig_lua_class *swig_", mangled_full_class_symname, "_bases[] = {", base_class, "0};\n", NIL);
|
||||
Printv(f_wrappers, "static swig_lua_class *swig_", mangled_class_fq_symname, "_bases[] = {", base_class, "0};\n", NIL);
|
||||
Delete(base_class);
|
||||
Printv(f_wrappers, "static const char *swig_", mangled_full_class_symname, "_base_names[] = {", base_class_names, "0};\n", NIL);
|
||||
Printv(f_wrappers, "static const char *swig_", mangled_class_fq_symname, "_base_names[] = {", base_class_names, "0};\n", NIL);
|
||||
Delete(base_class_names);
|
||||
|
||||
Printv(f_wrappers, "static swig_lua_class _wrap_class_", mangled_full_class_symname, " = { \"", class_symname, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
|
||||
Printv(f_wrappers, "static swig_lua_class _wrap_class_", mangled_class_fq_symname, " = { \"", class_symname, "\", \"", class_fq_symname,"\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
|
||||
|
||||
// TODO: Replace with constructor_name
|
||||
if (have_constructor) {
|
||||
|
|
@ -1285,7 +1362,7 @@ public:
|
|||
if (have_destructor) {
|
||||
if (eluac_ltr) {
|
||||
String* ns_methods_tab = Getattr(nspaceHash, "methods");
|
||||
Printv(ns_methods_tab, tab4, "{LSTRKEY(\"", "free_", mangled_full_class_symname, "\")", ", LFUNCVAL(", destructor_name, ")", "},\n", NIL);
|
||||
Printv(ns_methods_tab, tab4, "{LSTRKEY(\"", "free_", mangled_class_fq_symname, "\")", ", LFUNCVAL(", destructor_name, ")", "},\n", NIL);
|
||||
Printv(f_wrappers, ", ", destructor_name, NIL);
|
||||
} else {
|
||||
Printv(f_wrappers, ", ", destructor_name, NIL);
|
||||
|
|
@ -1295,15 +1372,21 @@ public:
|
|||
}
|
||||
Printf(f_wrappers, ", %s, %s, ", s_methods_tab_name, s_attr_tab_name );
|
||||
// TODO: Replace class_symname with class_name
|
||||
printNamespaceDefinition(static_cls_key, class_symname, f_wrappers);
|
||||
printNamespaceDefinition(class_static_nspace, class_symname, f_wrappers);
|
||||
Printf(f_wrappers, ", swig_%s_bases, swig_%s_base_names };\n\n",
|
||||
mangled_full_class_symname, mangled_full_class_symname);
|
||||
mangled_class_fq_symname, mangled_class_fq_symname);
|
||||
|
||||
// Printv(f_wrappers, ", swig_", mangled_full_class_symname, "_methods, swig_", mangled_full_class_symname, "_attributes, swig_", mangled_full_class_symname, "_bases };\n\n", NIL);
|
||||
// Printv(s_cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_full_class_symname, "},\n", NIL);
|
||||
// Printv(f_wrappers, ", swig_", mangled_class_fq_symname, "_methods, swig_", mangled_class_fq_symname, "_attributes, swig_", mangled_class_fq_symname, "_bases };\n\n", NIL);
|
||||
// Printv(s_cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_class_fq_symname, "},\n", NIL);
|
||||
|
||||
current[NO_CPP] = true;
|
||||
Delete(t);
|
||||
Delete(mangled_full_class_symname);
|
||||
Delete(static_cls_key);
|
||||
Delete(mangled_class_fq_symname);
|
||||
Delete(class_static_nspace);
|
||||
class_static_nspace = 0;
|
||||
Delete(class_fq_symname);
|
||||
class_fq_symname = 0;
|
||||
class_symname = 0;
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1327,9 +1410,9 @@ public:
|
|||
|
||||
String *realname, *rname;
|
||||
|
||||
current = MEMBER_FUNC;
|
||||
current[MEMBER_FUNC] = true;
|
||||
Language::memberfunctionHandler(n);
|
||||
current = NO_CPP;
|
||||
current[MEMBER_FUNC] = false;
|
||||
|
||||
realname = iname ? iname : name;
|
||||
rname = Getattr(n, "wrap:name");
|
||||
|
|
@ -1350,9 +1433,9 @@ public:
|
|||
String *symname = Getattr(n, "sym:name");
|
||||
String *getter_name, *setter_name;
|
||||
|
||||
current = MEMBER_VAR;
|
||||
current[MEMBER_VAR] = true;
|
||||
Language::membervariableHandler(n);
|
||||
current = NO_CPP;
|
||||
current[MEMBER_VAR] = false;
|
||||
getter_name = Getattr(n, "memberget:wrap:name");
|
||||
assert(getter_name != 0);
|
||||
if (!GetFlag(n, "feature:immutable")) {
|
||||
|
|
@ -1382,9 +1465,9 @@ public:
|
|||
|
||||
virtual int constructorHandler(Node *n) {
|
||||
// REPORT("constructorHandler", n);
|
||||
current = CONSTRUCTOR;
|
||||
current[CONSTRUCTOR] = true;
|
||||
Language::constructorHandler(n);
|
||||
current = NO_CPP;
|
||||
current[CONSTRUCTOR] = false;
|
||||
//constructor_name = NewString(Getattr(n, "sym:name"));
|
||||
have_constructor = 1;
|
||||
//Printf( stdout, "Constructor %s\n", constructor_name); TODO: REMOVE
|
||||
|
|
@ -1397,9 +1480,9 @@ public:
|
|||
|
||||
virtual int destructorHandler(Node *n) {
|
||||
REPORT("destructorHandler", n);
|
||||
current = DESTRUCTOR;
|
||||
current[DESTRUCTOR] = true;
|
||||
Language::destructorHandler(n);
|
||||
current = NO_CPP;
|
||||
current[DESTRUCTOR] = false;
|
||||
have_destructor = 1;
|
||||
destructor_action = Getattr(n, "wrap:action");
|
||||
return SWIG_OK;
|
||||
|
|
@ -1413,28 +1496,28 @@ public:
|
|||
|
||||
virtual int staticmemberfunctionHandler(Node *n) {
|
||||
REPORT("staticmemberfunctionHandler", n);
|
||||
current = STATIC_FUNC;
|
||||
current[STATIC_FUNC] = true;
|
||||
//String *symname = Getattr(n, "sym:name");
|
||||
int result = Language::staticmemberfunctionHandler(n);
|
||||
|
||||
if (cparse_cplusplus && getCurrentClass()) {
|
||||
Swig_restore(n);
|
||||
}
|
||||
current = NO_CPP;
|
||||
current[STATIC_FUNC] = false;;
|
||||
if (result != SWIG_OK)
|
||||
return result;
|
||||
|
||||
if (Getattr(n, "sym:nextSibling"))
|
||||
return SWIG_OK;
|
||||
|
||||
Swig_require("luaclassobj_staticmemberfunctionHandler", n, "luaclassobj:wrap:name", NIL);
|
||||
//Swig_require("luaclassobj_staticmemberfunctionHandler", n, "luaclassobj:wrap:name", NIL);
|
||||
//String *name = Getattr(n, "name");
|
||||
//String *rname, *realname;
|
||||
//realname = symname ? symname : name;
|
||||
//rname = Getattr(n, "luaclassobj:wrap:name");
|
||||
// TODO: Add backward compatibility here: add "ClassName_FuncName" to global table
|
||||
//Printv(s_cls_methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL);
|
||||
Swig_restore(n);
|
||||
//Swig_restore(n);
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
|
@ -1454,7 +1537,7 @@ public:
|
|||
}
|
||||
int result = Language::memberconstantHandler(n);
|
||||
if (cparse_cplusplus && getCurrentClass())
|
||||
Swig_restore(n);
|
||||
Swig_restore(n); // TODO: WTF ?
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1465,9 +1548,10 @@ public:
|
|||
|
||||
virtual int staticmembervariableHandler(Node *n) {
|
||||
REPORT("staticmembervariableHandler",n);
|
||||
current = STATIC_VAR;
|
||||
current[STATIC_VAR] = true;
|
||||
//String *symname = Getattr(n, "sym:name");
|
||||
int result = Language::staticmembervariableHandler(n);
|
||||
current[STATIC_VAR] = false;
|
||||
|
||||
if (result != SWIG_OK)
|
||||
return result;
|
||||
|
|
@ -1868,6 +1952,53 @@ public:
|
|||
|
||||
Printf( output, "static swig_lua_namespace %s;\n", Getattr(nspace_hash, "cname") );
|
||||
}
|
||||
|
||||
// Our implementation of addSymbol. Determines scope correctly, then calls Language::addSymbol
|
||||
int luaAddSymbol(const String *s, const Node *n) {
|
||||
String* scope = 0;
|
||||
// If ouside class, than NSpace is used.
|
||||
if( !getCurrentClass())
|
||||
scope = getNSpace();
|
||||
else {
|
||||
// If inside class, then either class static namespace or class fully qualified name is used
|
||||
assert(!current[NO_CPP]);
|
||||
if(current[STATIC_FUNC] || current[STATIC_VAR] || current[STATIC_CONST] ) {
|
||||
scope = class_static_nspace;
|
||||
} else if(current[MEMBER_VAR] || current[CLASS_CONST] || current[CONSTRUCTOR] || current[DESTRUCTOR]
|
||||
|| current[MEMBER_FUNC] ) {
|
||||
scope = class_fq_symname;
|
||||
} else {
|
||||
assert(0); // Can't be. Implementation error
|
||||
}
|
||||
assert(scope != 0);
|
||||
}
|
||||
return Language::addSymbol(s,n,scope);
|
||||
}
|
||||
|
||||
// Overload. Enforces given scope. Actually, it simply forwards call to Language::addSymbol
|
||||
int luaAddSymbol(const String*s, const Node*n, const_String_or_char_ptr scope) {
|
||||
return Language::addSymbol(s,n,scope);
|
||||
}
|
||||
|
||||
// Function creates fully qualified name of given symbol. Current NSpace and current class
|
||||
// are used
|
||||
String* fully_qualified_name(const_String_or_char_ptr name)
|
||||
{
|
||||
assert(name != 0);
|
||||
String* scope= 0;
|
||||
if( getCurrentClass() )
|
||||
scope = class_fq_symname;
|
||||
else
|
||||
scope = getNSpace();
|
||||
|
||||
String *fqname = 0;
|
||||
if( scope )
|
||||
fqname = NewStringf("%s::%s",scope,name);
|
||||
else
|
||||
fqname = Copy(name);
|
||||
|
||||
return fqname;
|
||||
}
|
||||
};
|
||||
|
||||
/* NEW LANGUAGE NOTE:***********************************************
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue