commit
4c86f17bcb
5 changed files with 335 additions and 9 deletions
|
|
@ -990,7 +990,7 @@ The current list of operators which can be overloaded (and the alternative funct
|
||||||
<li><tt>__sub__</tt> operator-
|
<li><tt>__sub__</tt> operator-
|
||||||
<li><tt>__mul__</tt> operator *
|
<li><tt>__mul__</tt> operator *
|
||||||
<li><tt>__div__</tt> operator/
|
<li><tt>__div__</tt> operator/
|
||||||
<li><tt>__neg__</tt> unary minus
|
<li><tt>__unm__</tt> unary minus
|
||||||
<li><tt>__call__</tt> operator<tt>()</tt> (often used in functor classes)
|
<li><tt>__call__</tt> operator<tt>()</tt> (often used in functor classes)
|
||||||
<li><tt>__pow__</tt> the exponential fn (no C++ equivalent, Lua uses <tt>^</tt>)
|
<li><tt>__pow__</tt> the exponential fn (no C++ equivalent, Lua uses <tt>^</tt>)
|
||||||
<li><tt>__concat__</tt> the concatenation operator (SWIG maps C++'s <tt>~</tt> to Lua's <tt>..</tt>)
|
<li><tt>__concat__</tt> the concatenation operator (SWIG maps C++'s <tt>~</tt> to Lua's <tt>..</tt>)
|
||||||
|
|
@ -1037,7 +1037,29 @@ It is also possible to overload the operator<tt>[]</tt>, but currently this cann
|
||||||
void __setitem__(int i,double d); // i is the index, d is the data
|
void __setitem__(int i,double d); // i is the index, d is the data
|
||||||
};
|
};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
<p>
|
||||||
|
C++ operators are mapped to Lua predefined metafunctions. Class inherits from its bases the following list of metafunctions ( thus inheriting the folloging
|
||||||
|
operators and pseudo-operators):</p>
|
||||||
|
<ul>
|
||||||
|
<li><tt>__add__</tt>
|
||||||
|
<li><tt>__sub__</tt>
|
||||||
|
<li><tt>__mul__</tt>
|
||||||
|
<li><tt>__div__</tt>
|
||||||
|
<li><tt>__unm__</tt>
|
||||||
|
<li><tt>__mod__</tt>
|
||||||
|
<li><tt>__call__</tt>
|
||||||
|
<li><tt>__pow__</tt>
|
||||||
|
<li><tt>__concat__</tt>
|
||||||
|
<li><tt>__eq__</tt>
|
||||||
|
<li><tt>__lt__</tt>
|
||||||
|
<li><tt>__le__</tt>
|
||||||
|
<li><tt>__len__</tt>
|
||||||
|
<li><tt>__getitem__</tt>
|
||||||
|
<li><tt>__setitem__</tt>
|
||||||
|
<li><tt>__tostring</tt> used internaly by Lua for tostring() function. __str__ is mapped to this function
|
||||||
|
</ul>
|
||||||
|
<p>No other lua metafunction is inherited. For example, __gc is not inherited and must be redefined in every class. <tt>__tostring</tt> is subject to a special handling. If absent in class and in class bases, a default one will be provided by SWIG</p>
|
||||||
|
</p>
|
||||||
<H3><a name="Lua_nn19"></a>27.3.12 Class extension with %extend</H3>
|
<H3><a name="Lua_nn19"></a>27.3.12 Class extension with %extend</H3>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,19 @@ class Foo {
|
||||||
}
|
}
|
||||||
|
|
||||||
int (Foo::*func_ptr)(int);
|
int (Foo::*func_ptr)(int);
|
||||||
|
|
||||||
|
const char* __str__() const { return "Foo"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FooSub : public Foo {
|
||||||
|
public:
|
||||||
|
FooSub() :Foo(42) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FooSubSub : public FooSub {
|
||||||
|
public:
|
||||||
|
FooSubSub() : FooSub() {}
|
||||||
|
const char* __str__() const { return "FooSubSub"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
|
||||||
|
|
@ -76,3 +76,13 @@ assert(cb.test_func_ptr(f,2)==-8)
|
||||||
|
|
||||||
-- Test that __tostring metamethod produce no internal asserts
|
-- Test that __tostring metamethod produce no internal asserts
|
||||||
f2_name = tostring(f2)
|
f2_name = tostring(f2)
|
||||||
|
|
||||||
|
f3 = cb.FooSub()
|
||||||
|
f3_name = tostring(f3)
|
||||||
|
|
||||||
|
f4 = cb.FooSubSub()
|
||||||
|
f4_name = tostring(f4)
|
||||||
|
|
||||||
|
assert( f2_name == "Foo" )
|
||||||
|
assert( f3_name == "Foo" )
|
||||||
|
assert( f4_name == "FooSubSub" )
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,38 @@ assert(i(1,2)==6)
|
||||||
assert(tostring(Op(1))=="Op(1)")
|
assert(tostring(Op(1))=="Op(1)")
|
||||||
assert(tostring(Op(-3))=="Op(-3)")
|
assert(tostring(Op(-3))=="Op(-3)")
|
||||||
|
|
||||||
|
|
||||||
|
-- check that operator overloads is correctly propogated accross hierarchy
|
||||||
|
|
||||||
|
a_d=OpDerived()
|
||||||
|
b_d=OpDerived(5)
|
||||||
|
c_d=OpDerived(5)
|
||||||
|
d_d=OpDerived(2)
|
||||||
|
-- test equality
|
||||||
|
assert(a_d~=b_d)
|
||||||
|
assert(b_d==c_d)
|
||||||
|
assert(a_d~=d_d)
|
||||||
|
|
||||||
|
-- test <
|
||||||
|
assert(a_d<b_d)
|
||||||
|
assert(a_d<=b_d)
|
||||||
|
assert(b_d<=c_d)
|
||||||
|
assert(b_d>=c_d)
|
||||||
|
assert(b_d>d_d)
|
||||||
|
assert(b_d>=d_d)
|
||||||
|
--
|
||||||
|
-- test + inheritance
|
||||||
|
f_d=OpDerived(1)
|
||||||
|
g_d=OpDerived(1)
|
||||||
|
assert(f_d+g_d==Op(2))
|
||||||
|
assert(f_d-g_d==Op(0))
|
||||||
|
assert(f_d*g_d==Op(1))
|
||||||
|
assert(f_d/g_d==Op(1))
|
||||||
|
--
|
||||||
|
-- plus add some code to check the __str__ fn inheritance
|
||||||
|
assert(tostring(OpDerived(1))=="Op(1)")
|
||||||
|
assert(tostring(OpDerived(-3))=="Op(-3)")
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
/* Sample test code in C++
|
/* Sample test code in C++
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -332,6 +332,11 @@ typedef struct {
|
||||||
lua_pushcfunction(L, f), \
|
lua_pushcfunction(L, f), \
|
||||||
lua_rawset(L,-3))
|
lua_rawset(L,-3))
|
||||||
|
|
||||||
|
#define SWIG_Lua_add_boolean(L,n,b) \
|
||||||
|
(lua_pushstring(L, n), \
|
||||||
|
lua_pushboolean(L, b), \
|
||||||
|
lua_rawset(L,-3))
|
||||||
|
|
||||||
/* special helper for allowing 'nil' for usertypes */
|
/* special helper for allowing 'nil' for usertypes */
|
||||||
#define SWIG_isptrtype(L,I) (lua_isuserdata(L,I) || lua_isnil(L,I))
|
#define SWIG_isptrtype(L,I) (lua_isuserdata(L,I) || lua_isnil(L,I))
|
||||||
|
|
||||||
|
|
@ -1017,7 +1022,51 @@ SWIGINTERN int SWIG_Lua_class_disown(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gets the swig class registry (or creates it) */
|
/* populate table at the top of the stack with metamethods that ought to be inherited */
|
||||||
|
SWIGINTERN void SWIG_Lua_populate_inheritable_metamethods(lua_State *L)
|
||||||
|
{
|
||||||
|
SWIG_Lua_add_boolean(L, "__add", 1);
|
||||||
|
SWIG_Lua_add_boolean(L, "__sub", 1);
|
||||||
|
SWIG_Lua_add_boolean(L, "__mul", 1);
|
||||||
|
SWIG_Lua_add_boolean(L, "__div", 1);
|
||||||
|
SWIG_Lua_add_boolean(L, "__mod", 1);
|
||||||
|
SWIG_Lua_add_boolean(L, "__pow", 1);
|
||||||
|
SWIG_Lua_add_boolean(L, "__unm", 1);
|
||||||
|
SWIG_Lua_add_boolean(L, "__len", 1 );
|
||||||
|
SWIG_Lua_add_boolean(L, "__concat", 1 );
|
||||||
|
SWIG_Lua_add_boolean(L, "__eq", 1);
|
||||||
|
SWIG_Lua_add_boolean(L, "__lt", 1);
|
||||||
|
SWIG_Lua_add_boolean(L, "__le", 1);
|
||||||
|
SWIG_Lua_add_boolean(L, "__call", 1);
|
||||||
|
SWIG_Lua_add_boolean(L, "__tostring", 1);
|
||||||
|
SWIG_Lua_add_boolean(L, "__gc", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* creates the swig registry */
|
||||||
|
SWIGINTERN void SWIG_Lua_create_class_registry(lua_State *L)
|
||||||
|
{
|
||||||
|
/* create main SWIG registry table */
|
||||||
|
lua_pushstring(L,"SWIG");
|
||||||
|
lua_newtable(L);
|
||||||
|
/* populate it with some predefined data */
|
||||||
|
|
||||||
|
/* .library table. Placeholder */
|
||||||
|
lua_pushstring(L,".library");
|
||||||
|
lua_newtable(L);
|
||||||
|
{
|
||||||
|
/* list of metamethods that class inherits from its bases */
|
||||||
|
lua_pushstring(L,"inheritable_metamethods");
|
||||||
|
lua_newtable(L);
|
||||||
|
/* populate with list of metamethods */
|
||||||
|
SWIG_Lua_populate_inheritable_metamethods(L);
|
||||||
|
lua_rawset(L,-3);
|
||||||
|
}
|
||||||
|
lua_rawset(L,-3);
|
||||||
|
|
||||||
|
lua_rawset(L,LUA_REGISTRYINDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gets the swig registry (or creates it) */
|
||||||
SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L)
|
SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L)
|
||||||
{
|
{
|
||||||
/* add this all into the swig registry: */
|
/* add this all into the swig registry: */
|
||||||
|
|
@ -1026,15 +1075,27 @@ SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L)
|
||||||
if (!lua_istable(L,-1)) /* not there */
|
if (!lua_istable(L,-1)) /* not there */
|
||||||
{ /* must be first time, so add it */
|
{ /* must be first time, so add it */
|
||||||
lua_pop(L,1); /* remove the result */
|
lua_pop(L,1); /* remove the result */
|
||||||
lua_pushstring(L,"SWIG");
|
SWIG_Lua_create_class_registry(L);
|
||||||
lua_newtable(L);
|
|
||||||
lua_rawset(L,LUA_REGISTRYINDEX);
|
|
||||||
/* then get it */
|
/* then get it */
|
||||||
lua_pushstring(L,"SWIG");
|
lua_pushstring(L,"SWIG");
|
||||||
lua_rawget(L,LUA_REGISTRYINDEX);
|
lua_rawget(L,LUA_REGISTRYINDEX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWIGINTERN void SWIG_Lua_get_inheritable_metamethods(lua_State *L)
|
||||||
|
{
|
||||||
|
SWIG_Lua_get_class_registry(L);
|
||||||
|
lua_pushstring(L, ".library");
|
||||||
|
lua_rawget(L,-2);
|
||||||
|
assert( !lua_isnil(L,-1) );
|
||||||
|
lua_pushstring(L, "inheritable_metamethods");
|
||||||
|
lua_rawget(L,-2);
|
||||||
|
|
||||||
|
/* Remove class registry and library table */
|
||||||
|
lua_remove(L,-2);
|
||||||
|
lua_remove(L,-2);
|
||||||
|
}
|
||||||
|
|
||||||
/* Helper function to get the classes metatable from the register */
|
/* Helper function to get the classes metatable from the register */
|
||||||
SWIGINTERN void SWIG_Lua_get_class_metatable(lua_State *L,const char *cname)
|
SWIGINTERN void SWIG_Lua_get_class_metatable(lua_State *L,const char *cname)
|
||||||
{
|
{
|
||||||
|
|
@ -1164,8 +1225,10 @@ SWIGINTERN void SWIG_Lua_add_class_static_details(lua_State *L, swig_lua_class *
|
||||||
SWIG_Lua_add_namespace_details(L, clss->cls_static);
|
SWIG_Lua_add_namespace_details(L, clss->cls_static);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class *clss); /* forward declaration */
|
||||||
|
|
||||||
/* helper to recursively add class details (attributes & operations) */
|
/* helper to recursively add class details (attributes & operations) */
|
||||||
SWIGINTERN void SWIG_Lua_add_class_instance_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;
|
int i;
|
||||||
/* Add bases to .bases table */
|
/* Add bases to .bases table */
|
||||||
|
|
@ -1202,6 +1265,194 @@ SWIGINTERN void SWIG_Lua_add_class_instance_details(lua_State *L,swig_lua_class
|
||||||
SWIG_Lua_add_function(L,clss->metatable[i].name,clss->metatable[i].func);
|
SWIG_Lua_add_function(L,clss->metatable[i].name,clss->metatable[i].func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(SWIG_LUA_SQUASH_BASES)
|
||||||
|
/* Adding metamethods that are defined in base classes. If bases were squashed
|
||||||
|
* then it is obviously unnecessary
|
||||||
|
*/
|
||||||
|
SWIG_Lua_add_class_user_metamethods(L, clss);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* helpers to add user defined class metamedhods - __add, __sub etc. Necessity for those helpers
|
||||||
|
arise from the following issue: Lua runtime checks for metamethod existence with rawget function
|
||||||
|
ignoring our SWIG-provided __index and __newindex functions. Thus our inheritance-aware method
|
||||||
|
search algorithm doesn't work in such case. (Not to say that Lua runtime queries metamethod directly
|
||||||
|
in metatable and not in object).
|
||||||
|
Current solution is this: if somewhere in hierarchy metamethod __x is defined, then all descendants
|
||||||
|
are automatically given a special proxy __x that calls the real __x method.
|
||||||
|
Obvious idea - to copy __x instead of creating __x-proxy is wrong because if someone changes __x in runtime,
|
||||||
|
those changes must be reflected in all descendants.
|
||||||
|
*/
|
||||||
|
|
||||||
|
SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L); /*forward declaration*/
|
||||||
|
|
||||||
|
/* The real function that resolveds metamethod.
|
||||||
|
* Function searches given class and all it's bases(recursively) for first instance of something that is
|
||||||
|
* not equal to SWIG_Lua_resolve_metatmethod. (Almost always this 'something' is actuall metamethod implementation
|
||||||
|
* and it is a SWIG-generated C function.). It returns value on the top of the L and there is no garbage below the
|
||||||
|
* answer.
|
||||||
|
* Returns 1 if found, 0 otherwise.
|
||||||
|
* clss is class which metatable we will search for method
|
||||||
|
* metamethod_name_idx is index in L where metamethod name (as string) lies
|
||||||
|
* skip_check allows to skip searching metamethod in givel clss and immideatelly go to searching in bases. skip_check
|
||||||
|
* is not caried to subsequent recursive calls - false is always passed. It is set to true only at first call from
|
||||||
|
* SWIG_Lua_resolve_metamethod
|
||||||
|
* */
|
||||||
|
SWIGINTERN int SWIG_Lua_do_resolve_metamethod(lua_State *L, const swig_lua_class *clss, int metamethod_name_idx,
|
||||||
|
int skip_check)
|
||||||
|
{
|
||||||
|
/* This function is called recursively */
|
||||||
|
if (!skip_check) {
|
||||||
|
SWIG_Lua_get_class_metatable(L, clss->fqname);
|
||||||
|
lua_pushvalue(L, metamethod_name_idx);
|
||||||
|
lua_rawget(L,-2);
|
||||||
|
/* If this is cfunction and it is equal to SWIG_Lua_resolve_metamethod then
|
||||||
|
* this isn't the function we are looking for :)
|
||||||
|
* lua_tocfunction will return NULL if not cfunction
|
||||||
|
*/
|
||||||
|
if (!lua_isnil(L,-1) && lua_tocfunction(L,-1) != SWIG_Lua_resolve_metamethod ) {
|
||||||
|
lua_remove(L,-2); /* removing class metatable */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
lua_pop(L,2); /* remove class metatable and query result */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forwarding calls to bases */
|
||||||
|
int result = 0;
|
||||||
|
int i = 0;
|
||||||
|
for(i=0;clss->bases[i];i++)
|
||||||
|
{
|
||||||
|
result = SWIG_Lua_do_resolve_metamethod(L, clss->bases[i], metamethod_name_idx, 0);
|
||||||
|
if (result)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The proxy function for metamethod. All parameters are passed as cclosure. Searches for actual method
|
||||||
|
* and calls it */
|
||||||
|
SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L)
|
||||||
|
{
|
||||||
|
lua_checkstack(L,5);
|
||||||
|
const int numargs = lua_gettop(L); /* number of arguments to pass to actuall metamethod */
|
||||||
|
|
||||||
|
/* Get upvalues from closure */
|
||||||
|
lua_pushvalue(L, lua_upvalueindex(1)); /*Get function name*/
|
||||||
|
const int metamethod_name_idx = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_pushvalue(L, lua_upvalueindex(2));
|
||||||
|
const swig_lua_class* clss = (const swig_lua_class*)(lua_touserdata(L,-1));
|
||||||
|
lua_pop(L,1); /* remove lightuserdata with clss from stack */
|
||||||
|
|
||||||
|
/* Actuall work */
|
||||||
|
const int result = SWIG_Lua_do_resolve_metamethod(L, clss, metamethod_name_idx, 1);
|
||||||
|
if (!result) {
|
||||||
|
SWIG_Lua_pushferrstring(L,"The metamethod proxy is set, but it failed to find actuall metamethod. Memory corruption is most likely explanation.");
|
||||||
|
lua_error(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_remove(L,-2); /* remove metamethod key */
|
||||||
|
lua_insert(L,1); /* move function to correct position */
|
||||||
|
lua_call(L, numargs, LUA_MULTRET);
|
||||||
|
return lua_gettop(L); /* return all results */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If given metamethod must be present in given class, then creates appropriate proxy
|
||||||
|
* Returns 1 if successfully added, 0 if not added because no base class has it, -1
|
||||||
|
* if method is defined in the class metatable itself
|
||||||
|
*/
|
||||||
|
SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class *clss, const int metatable_index)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* metamethod name - on the top of the stack */
|
||||||
|
assert(lua_isstring(L,-1));
|
||||||
|
|
||||||
|
const int key_index = lua_gettop(L);
|
||||||
|
|
||||||
|
/* Check whether method is already defined in metatable */
|
||||||
|
lua_pushvalue(L,key_index); /* copy of the key */
|
||||||
|
lua_gettable(L,metatable_index);
|
||||||
|
if( !lua_isnil(L,-1) ) {
|
||||||
|
lua_pop(L,1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
lua_pop(L,1);
|
||||||
|
|
||||||
|
|
||||||
|
/* Iterating over immediate bases */
|
||||||
|
int success = 0;
|
||||||
|
int i = 0;
|
||||||
|
for(i=0;clss->bases[i];i++)
|
||||||
|
{
|
||||||
|
const swig_lua_class *base = clss->bases[i];
|
||||||
|
SWIG_Lua_get_class_metatable(L, base->fqname);
|
||||||
|
lua_pushvalue(L, key_index);
|
||||||
|
lua_rawget(L, -2);
|
||||||
|
if( !lua_isnil(L,-1) ) {
|
||||||
|
lua_pushvalue(L, key_index);
|
||||||
|
|
||||||
|
/* Add proxy function */
|
||||||
|
lua_pushvalue(L, key_index); /* first closure value is function name */
|
||||||
|
lua_pushlightuserdata(L, clss); /* second closure value is swig_lua_class structure */
|
||||||
|
lua_pushcclosure(L, SWIG_Lua_resolve_metamethod, 2);
|
||||||
|
|
||||||
|
lua_rawset(L, metatable_index);
|
||||||
|
success = 1;
|
||||||
|
}
|
||||||
|
lua_pop(L,1); /* remove function or nil */
|
||||||
|
lua_pop(L,1); /* remove base class metatable */
|
||||||
|
|
||||||
|
if( success )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class *clss)
|
||||||
|
{
|
||||||
|
SWIG_Lua_get_class_metatable(L, clss->fqname);
|
||||||
|
const int metatable_index = lua_gettop(L);
|
||||||
|
SWIG_Lua_get_inheritable_metamethods(L);
|
||||||
|
assert(lua_istable(L,-1));
|
||||||
|
const int metamethods_info_index = lua_gettop(L);
|
||||||
|
lua_pushnil(L); /* first key */
|
||||||
|
while(lua_next(L, metamethods_info_index) != 0 ) {
|
||||||
|
/* key at index -2, value at index -1 */
|
||||||
|
const int is_inheritable = lua_toboolean(L,-2);
|
||||||
|
lua_pop(L,1); /* remove value - we don't need it anymore */
|
||||||
|
|
||||||
|
if(is_inheritable) { /* if metamethod is inheritable */
|
||||||
|
SWIG_Lua_add_class_user_metamethod(L,clss,metatable_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L,1); /* remove inheritable metatmethods table */
|
||||||
|
|
||||||
|
/* Special handling for __tostring method */
|
||||||
|
lua_pushstring(L, "__tostring");
|
||||||
|
lua_pushvalue(L,-1);
|
||||||
|
lua_rawget(L,metatable_index);
|
||||||
|
const int tostring_undefined = lua_isnil(L,-1);
|
||||||
|
lua_pop(L,1);
|
||||||
|
if( tostring_undefined ) {
|
||||||
|
lua_pushcfunction(L, SWIG_Lua_class_tostring);
|
||||||
|
lua_rawset(L, metatable_index);
|
||||||
|
} else {
|
||||||
|
lua_pop(L,1); /* remove copy of the key */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Warning: __index and __newindex are SWIG-defined. For user-defined operator[]
|
||||||
|
* a __getitem/__setitem method should be defined
|
||||||
|
*/
|
||||||
|
lua_pop(L,1); /* pop class metatable */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register class static methods,attributes etc as well as constructor proxy */
|
/* Register class static methods,attributes etc as well as constructor proxy */
|
||||||
|
|
@ -1303,8 +1554,6 @@ SWIGINTERN void SWIG_Lua_class_register_instance(lua_State *L,swig_lua_class *c
|
||||||
SWIG_Lua_add_function(L,"__index",SWIG_Lua_class_get);
|
SWIG_Lua_add_function(L,"__index",SWIG_Lua_class_get);
|
||||||
SWIG_Lua_add_function(L,"__newindex",SWIG_Lua_class_set);
|
SWIG_Lua_add_function(L,"__newindex",SWIG_Lua_class_set);
|
||||||
SWIG_Lua_add_function(L,"__gc",SWIG_Lua_class_destruct);
|
SWIG_Lua_add_function(L,"__gc",SWIG_Lua_class_destruct);
|
||||||
/* add tostring method for better output */
|
|
||||||
SWIG_Lua_add_function(L,"__tostring",SWIG_Lua_class_tostring);
|
|
||||||
/* add it */
|
/* add it */
|
||||||
lua_rawset(L,-3); /* metatable into registry */
|
lua_rawset(L,-3); /* metatable into registry */
|
||||||
lua_pop(L,1); /* tidy stack (remove registry) */
|
lua_pop(L,1); /* tidy stack (remove registry) */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue