Fixed issues with C++ classes and hierachies across multiple source files.
Fixed imports test case & added run test. Added Examples/imports. Added typename for raw lua_State* Added documentation on native functions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9748 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
cea5ba04fa
commit
61fdde65cc
19 changed files with 820 additions and 481 deletions
|
|
@ -1,6 +1,13 @@
|
||||||
Version 1.3.32 (in progress)
|
Version 1.3.32 (in progress)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
05/02/2007: mgossage
|
||||||
|
[Lua] Fixed issues with C++ classes and hierachies across multiple
|
||||||
|
source files. Fixed imports test case & added run test.
|
||||||
|
Added Examples/imports.
|
||||||
|
Added typename for raw lua_State*
|
||||||
|
Added documentation on native functions.
|
||||||
|
|
||||||
05/07/2007: gga
|
05/07/2007: gga
|
||||||
[Ruby]
|
[Ruby]
|
||||||
Docstrings are now supported.
|
Docstrings are now supported.
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,13 @@
|
||||||
<li><a href="#Lua_nn19">Class extension with %extend</a>
|
<li><a href="#Lua_nn19">Class extension with %extend</a>
|
||||||
<li><a href="#Lua_nn20">C++ templates</a>
|
<li><a href="#Lua_nn20">C++ templates</a>
|
||||||
<li><a href="#Lua_nn21">C++ Smart Pointers</a>
|
<li><a href="#Lua_nn21">C++ Smart Pointers</a>
|
||||||
|
<li><a href="#Lua_nn22">Writing your own custom wrappers</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="#Lua_nn22">Details on the Lua binding</a>
|
<li><a href="#Lua_nn23">Details on the Lua binding</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#Lua_nn23">Binding global data into the module.</a>
|
<li><a href="#Lua_nn24">Binding global data into the module.</a>
|
||||||
<li><a href="#Lua_nn24">Userdata and Metatables</a>
|
<li><a href="#Lua_nn25">Userdata and Metatables</a>
|
||||||
<li><a href="#Lua_nn25">Memory management</a>
|
<li><a href="#Lua_nn26">Memory management</a>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -952,7 +953,24 @@ If you ever need to access the underlying pointer returned by <tt>operator->(
|
||||||
> f = p:__deref__() -- Returns underlying Foo *
|
> f = p:__deref__() -- Returns underlying Foo *
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
<H2><a name="Lua_nn22"></a>22.4 Details on the Lua binding</H2>
|
<H3><a name="Lua_nn22"></a>22.3.15 Writing your own custom wrappers</H3>
|
||||||
|
<p>
|
||||||
|
Sometimes, it may be neccesary to add your own special functions, which bypass the normal SWIG wrappering method, and just use the native lua-c API calls. These 'native' functions allow direct adding of your own code into the module. This is performed with the <tt>%native</tt> directive as follows:
|
||||||
|
</p>
|
||||||
|
<div class="code"><pre>%native(my_func) int native_function(lua_State*L); // registers it with SWIG
|
||||||
|
...
|
||||||
|
%{
|
||||||
|
int native_function(lua_State*L) // my native code
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
</pre></div>
|
||||||
|
<p>
|
||||||
|
The <tt>%native</tt> directive in the above example, tells SWIG that there is a function <tt>int native_function(lua_State*L);</tt> which is to be added into the module under the name '<tt>my_func</tt>'. SWIG will not add any wrappering for this function, beyond adding it into the function table. How you write your code is entirely up to you.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<H2><a name="Lua_nn23"></a>22.4 Details on the Lua binding</H2>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -963,7 +981,7 @@ If you ever need to access the underlying pointer returned by <tt>operator->(
|
||||||
</i>
|
</i>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H3><a name="Lua_nn23"></a>22.4.1 Binding global data into the module.</H3>
|
<H3><a name="Lua_nn24"></a>22.4.1 Binding global data into the module.</H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1023,7 +1041,7 @@ end
|
||||||
<p>
|
<p>
|
||||||
That way when you call '<tt>a=example.Foo</tt>', the interpreter looks at the table 'example' sees that there is no field 'Foo' and calls __index. This will in turn check in '.get' table and find the existence of 'Foo' and then return the value of the C function call 'Foo_get()'. Similarly for the code '<tt>example.Foo=10</tt>', the interpreter will check the table, then call the __newindex which will then check the '.set' table and call the C function 'Foo_set(10)'.
|
That way when you call '<tt>a=example.Foo</tt>', the interpreter looks at the table 'example' sees that there is no field 'Foo' and calls __index. This will in turn check in '.get' table and find the existence of 'Foo' and then return the value of the C function call 'Foo_get()'. Similarly for the code '<tt>example.Foo=10</tt>', the interpreter will check the table, then call the __newindex which will then check the '.set' table and call the C function 'Foo_set(10)'.
|
||||||
</p>
|
</p>
|
||||||
<H3><a name="Lua_nn24"></a>22.4.2 Userdata and Metatables</H3>
|
<H3><a name="Lua_nn25"></a>22.4.2 Userdata and Metatables</H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1103,7 +1121,7 @@ Note: Both the opaque structures (like the FILE*) and normal wrappered classes/s
|
||||||
<p>
|
<p>
|
||||||
Note: Operator overloads are basically done in the same way, by adding functions such as '__add' & '__call' to the classes metatable. The current implementation is a bit rough as it will add any member function beginning with '__' into the metatable too, assuming its an operator overload.
|
Note: Operator overloads are basically done in the same way, by adding functions such as '__add' & '__call' to the classes metatable. The current implementation is a bit rough as it will add any member function beginning with '__' into the metatable too, assuming its an operator overload.
|
||||||
</p>
|
</p>
|
||||||
<H3><a name="Lua_nn25"></a>22.4.3 Memory management</H3>
|
<H3><a name="Lua_nn26"></a>22.4.3 Memory management</H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ constants
|
||||||
funcptr3
|
funcptr3
|
||||||
functest
|
functest
|
||||||
functor
|
functor
|
||||||
|
import
|
||||||
pointer
|
pointer
|
||||||
simple
|
simple
|
||||||
variables
|
variables
|
||||||
|
|
|
||||||
19
Examples/lua/import/Makefile
Normal file
19
Examples/lua/import/Makefile
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
TOP = ../..
|
||||||
|
SWIG = $(TOP)/../preinst-swig
|
||||||
|
SWIGOPT =
|
||||||
|
LIBS =
|
||||||
|
|
||||||
|
all::
|
||||||
|
$(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \
|
||||||
|
LIBS='$(LIBS)' TARGET='base' INTERFACE='base.i' lua_cpp
|
||||||
|
$(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \
|
||||||
|
LIBS='$(LIBS)' TARGET='foo' INTERFACE='foo.i' lua_cpp
|
||||||
|
$(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \
|
||||||
|
LIBS='$(LIBS)' TARGET='bar' INTERFACE='bar.i' lua_cpp
|
||||||
|
$(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \
|
||||||
|
LIBS='$(LIBS)' TARGET='spam' INTERFACE='spam.i' lua_cpp
|
||||||
|
|
||||||
|
clean::
|
||||||
|
$(MAKE) -f $(TOP)/Makefile lua_clean
|
||||||
|
|
||||||
|
check: all
|
||||||
36
Examples/lua/import/README
Normal file
36
Examples/lua/import/README
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
This example tests the %import directive and working with multiple modules.
|
||||||
|
|
||||||
|
Use 'lua runme.lua' to run a test.
|
||||||
|
|
||||||
|
Overview:
|
||||||
|
---------
|
||||||
|
|
||||||
|
The example defines 4 different extension modules--each wrapping
|
||||||
|
a separate C++ class.
|
||||||
|
|
||||||
|
base.i - Base class
|
||||||
|
foo.i - Foo class derived from Base
|
||||||
|
bar.i - Bar class derived from Base
|
||||||
|
spam.i - Spam class derived from Bar
|
||||||
|
|
||||||
|
Each module uses %import to refer to another module. For
|
||||||
|
example, the 'foo.i' module uses '%import base.i' to get
|
||||||
|
definitions for its base class.
|
||||||
|
|
||||||
|
If everything is okay, all of the modules will load properly and
|
||||||
|
type checking will work correctly. Caveat: Some compilers, for example
|
||||||
|
gcc-3.2.x, generate broken vtables with the inline methods in this test.
|
||||||
|
This is not a SWIG problem and can usually be solved with non-inlined
|
||||||
|
destructors compiled into separate shared objects/DLLs.
|
||||||
|
|
||||||
|
Unix:
|
||||||
|
-----
|
||||||
|
- Run make
|
||||||
|
- Run the test as described above
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
--------
|
||||||
|
Sorry, no files here.
|
||||||
|
If you know how, you could copy the python or ruby example dsw & dsp and try editing that
|
||||||
|
|
||||||
|
|
||||||
21
Examples/lua/import/bar.h
Normal file
21
Examples/lua/import/bar.h
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "base.h"
|
||||||
|
|
||||||
|
class Bar : public Base {
|
||||||
|
public:
|
||||||
|
Bar() { }
|
||||||
|
~Bar() { }
|
||||||
|
virtual const char * A() const {
|
||||||
|
return "Bar::A";
|
||||||
|
}
|
||||||
|
const char * B() const {
|
||||||
|
return "Bar::B";
|
||||||
|
}
|
||||||
|
virtual Base *toBase() {
|
||||||
|
return static_cast<Base *>(this);
|
||||||
|
}
|
||||||
|
static Bar *fromBase(Base *b) {
|
||||||
|
return dynamic_cast<Bar *>(b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
9
Examples/lua/import/bar.i
Normal file
9
Examples/lua/import/bar.i
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
%module bar
|
||||||
|
%{
|
||||||
|
#include "bar.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%import base.i
|
||||||
|
%include "bar.h"
|
||||||
|
|
||||||
|
|
||||||
16
Examples/lua/import/base.h
Normal file
16
Examples/lua/import/base.h
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
class Base {
|
||||||
|
public:
|
||||||
|
Base() { };
|
||||||
|
virtual ~Base() { };
|
||||||
|
virtual const char * A() const {
|
||||||
|
return "Base::A";
|
||||||
|
}
|
||||||
|
const char * B() const {
|
||||||
|
return "Base::B";
|
||||||
|
}
|
||||||
|
virtual Base *toBase() {
|
||||||
|
return static_cast<Base *>(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
6
Examples/lua/import/base.i
Normal file
6
Examples/lua/import/base.i
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
%module base
|
||||||
|
%{
|
||||||
|
#include "base.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%include base.h
|
||||||
21
Examples/lua/import/foo.h
Normal file
21
Examples/lua/import/foo.h
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "base.h"
|
||||||
|
|
||||||
|
class Foo : public Base {
|
||||||
|
public:
|
||||||
|
Foo() { }
|
||||||
|
~Foo() { }
|
||||||
|
virtual const char * A() const {
|
||||||
|
return "Foo::A";
|
||||||
|
}
|
||||||
|
const char * B() const {
|
||||||
|
return "Foo::B";
|
||||||
|
}
|
||||||
|
virtual Base *toBase() {
|
||||||
|
return static_cast<Base *>(this);
|
||||||
|
}
|
||||||
|
static Foo *fromBase(Base *b) {
|
||||||
|
return dynamic_cast<Foo *>(b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
8
Examples/lua/import/foo.i
Normal file
8
Examples/lua/import/foo.i
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
%module foo
|
||||||
|
%{
|
||||||
|
#include "foo.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%import base.i
|
||||||
|
%include "foo.h"
|
||||||
|
|
||||||
103
Examples/lua/import/runme.lua
Normal file
103
Examples/lua/import/runme.lua
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
# Test various properties of classes defined in separate modules
|
||||||
|
|
||||||
|
print("Testing the %import directive")
|
||||||
|
|
||||||
|
if string.sub(_VERSION,1,7)=='Lua 5.0' then
|
||||||
|
-- lua5.0 doesnt have a nice way to do this
|
||||||
|
function loadit(a,b)
|
||||||
|
lib=loadlib(a..':dll',b) or loadlib(a..':so',b)
|
||||||
|
assert(lib)()
|
||||||
|
end
|
||||||
|
loadit('base','Base_Init')
|
||||||
|
loadit('foo','Foo_Init')
|
||||||
|
loadit('bar','Bar_Init')
|
||||||
|
loadit('spam','Spam_Init')
|
||||||
|
else
|
||||||
|
-- lua 5.1 does
|
||||||
|
require 'base'
|
||||||
|
require 'foo'
|
||||||
|
require 'bar'
|
||||||
|
require 'spam'
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create some objects
|
||||||
|
|
||||||
|
print("Creating some objects")
|
||||||
|
|
||||||
|
a = base.Base()
|
||||||
|
b = foo.Foo()
|
||||||
|
c = bar.Bar()
|
||||||
|
d = spam.Spam()
|
||||||
|
|
||||||
|
-- Try calling some methods
|
||||||
|
print("Testing some methods")
|
||||||
|
print("Should see 'Base::A' ---> ",a:A())
|
||||||
|
print("Should see 'Base::B' ---> ",a:B())
|
||||||
|
|
||||||
|
print("Should see 'Foo::A' ---> ",b:A())
|
||||||
|
print("Should see 'Foo::B' ---> ",b:B())
|
||||||
|
|
||||||
|
print("Should see 'Bar::A' ---> ",c:A())
|
||||||
|
print("Should see 'Bar::B' ---> ",c:B())
|
||||||
|
|
||||||
|
print("Should see 'Spam::A' ---> ",d:A())
|
||||||
|
print("Should see 'Spam::B' ---> ",d:B())
|
||||||
|
|
||||||
|
-- Try some casts
|
||||||
|
|
||||||
|
print("\nTesting some casts")
|
||||||
|
|
||||||
|
x = a:toBase()
|
||||||
|
print("Should see 'Base::A' ---> ",x:A())
|
||||||
|
print("Should see 'Base::B' ---> ",x:B())
|
||||||
|
|
||||||
|
x = b:toBase()
|
||||||
|
print("Should see 'Foo::A' ---> ",x:A())
|
||||||
|
print("Should see 'Base::B' ---> ",x:B())
|
||||||
|
|
||||||
|
x = c:toBase()
|
||||||
|
print("Should see 'Bar::A' ---> ",x:A())
|
||||||
|
print("Should see 'Base::B' ---> ",x:B())
|
||||||
|
|
||||||
|
x = d:toBase()
|
||||||
|
print("Should see 'Spam::A' ---> ",x:A())
|
||||||
|
print("Should see 'Base::B' ---> ",x:B())
|
||||||
|
|
||||||
|
x = d:toBar()
|
||||||
|
print("Should see 'Bar::B' ---> ",x:B())
|
||||||
|
|
||||||
|
|
||||||
|
print "\nTesting some dynamic casts\n"
|
||||||
|
x = d:toBase()
|
||||||
|
|
||||||
|
print " Spam -> Base -> Foo : "
|
||||||
|
y = foo.Foo_fromBase(x)
|
||||||
|
if y then
|
||||||
|
print "bad swig"
|
||||||
|
else
|
||||||
|
print "good swig"
|
||||||
|
end
|
||||||
|
|
||||||
|
print " Spam -> Base -> Bar : "
|
||||||
|
y = bar.Bar_fromBase(x)
|
||||||
|
if y then
|
||||||
|
print "good swig"
|
||||||
|
else
|
||||||
|
print "bad swig"
|
||||||
|
end
|
||||||
|
|
||||||
|
print " Spam -> Base -> Spam : "
|
||||||
|
y = spam.Spam_fromBase(x)
|
||||||
|
if y then
|
||||||
|
print "good swig"
|
||||||
|
else
|
||||||
|
print "bad swig"
|
||||||
|
end
|
||||||
|
|
||||||
|
print " Foo -> Spam : "
|
||||||
|
y = spam.Spam_fromBase(b)
|
||||||
|
if y then
|
||||||
|
print "bad swig"
|
||||||
|
else
|
||||||
|
print "good swig"
|
||||||
|
end
|
||||||
24
Examples/lua/import/spam.h
Normal file
24
Examples/lua/import/spam.h
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include "bar.h"
|
||||||
|
|
||||||
|
class Spam : public Bar {
|
||||||
|
public:
|
||||||
|
Spam() { }
|
||||||
|
~Spam() { }
|
||||||
|
virtual const char * A() const {
|
||||||
|
return "Spam::A";
|
||||||
|
}
|
||||||
|
const char * B() const {
|
||||||
|
return "Spam::B";
|
||||||
|
}
|
||||||
|
virtual Base *toBase() {
|
||||||
|
return static_cast<Base *>(this);
|
||||||
|
}
|
||||||
|
virtual Bar *toBar() {
|
||||||
|
return static_cast<Bar *>(this);
|
||||||
|
}
|
||||||
|
static Spam *fromBase(Base *b) {
|
||||||
|
return dynamic_cast<Spam *>(b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
9
Examples/lua/import/spam.i
Normal file
9
Examples/lua/import/spam.i
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
%module spam
|
||||||
|
%{
|
||||||
|
#include "spam.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%import bar.i
|
||||||
|
%include "spam.h"
|
||||||
|
|
||||||
|
|
||||||
28
Examples/test-suite/lua/imports_runme.lua
Normal file
28
Examples/test-suite/lua/imports_runme.lua
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
require("import") -- the import fn
|
||||||
|
-- need to load two modules
|
||||||
|
import("imports_a") -- import code
|
||||||
|
import("imports_b") -- import code
|
||||||
|
|
||||||
|
b=imports_b.B()
|
||||||
|
b:hello() -- call member function in A which is in a different SWIG generated library.
|
||||||
|
b:bye()
|
||||||
|
|
||||||
|
assert (b:member_virtual_test(imports_a.A_memberenum1) == imports_a.A_memberenum2)
|
||||||
|
assert (b:global_virtual_test(imports_a.globalenum1) == imports_a.globalenum2)
|
||||||
|
|
||||||
|
imports_b.global_test(imports_a.A_memberenum1)
|
||||||
|
|
||||||
|
--[[ B b = new B();
|
||||||
|
b.hello(); //call member function in A which is in a different SWIG generated library.
|
||||||
|
|
||||||
|
B b = new B();
|
||||||
|
b.hello(); //call member function in A which is in a different SWIG generated library.
|
||||||
|
b.bye();
|
||||||
|
|
||||||
|
if (b.member_virtual_test(A.MemberEnum.memberenum1) != A.MemberEnum.memberenum2)
|
||||||
|
throw new Exception("Test 1 failed");
|
||||||
|
if (b.global_virtual_test(GlobalEnum.globalenum1) != GlobalEnum.globalenum2)
|
||||||
|
throw new Exception("Test 2 failed");
|
||||||
|
|
||||||
|
imports_b.global_test(A.MemberEnum.memberenum1);
|
||||||
|
]]
|
||||||
|
|
@ -65,6 +65,7 @@ typedef struct swig_lua_class {
|
||||||
swig_lua_method *methods;
|
swig_lua_method *methods;
|
||||||
swig_lua_attribute *attributes;
|
swig_lua_attribute *attributes;
|
||||||
struct swig_lua_class **bases;
|
struct swig_lua_class **bases;
|
||||||
|
char **base_names;
|
||||||
} swig_lua_class;
|
} swig_lua_class;
|
||||||
|
|
||||||
/* this is the struct for wrappering all pointers in SwigLua
|
/* this is the struct for wrappering all pointers in SwigLua
|
||||||
|
|
@ -128,6 +129,26 @@ it gets the address, casts it, then dereferences it */
|
||||||
//#define SWIG_mem_fn_as_voidptr(a) (*((char**)&(a)))
|
//#define SWIG_mem_fn_as_voidptr(a) (*((char**)&(a)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* storing/access of swig_module_info */
|
||||||
|
SWIGRUNTIME swig_module_info *
|
||||||
|
SWIG_Lua_GetModule(lua_State* L) {
|
||||||
|
swig_module_info *ret = 0;
|
||||||
|
lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
|
||||||
|
lua_rawget(L,LUA_REGISTRYINDEX);
|
||||||
|
if (lua_islightuserdata(L,-1))
|
||||||
|
ret=(swig_module_info*)lua_touserdata(L,-1);
|
||||||
|
lua_pop(L,1); /* tidy */
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIGRUNTIME void
|
||||||
|
SWIG_Lua_SetModule(lua_State* L, swig_module_info *module) {
|
||||||
|
/* add this all into the Lua registry: */
|
||||||
|
lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
|
||||||
|
lua_pushlightuserdata(L,(void*)module);
|
||||||
|
lua_rawset(L,LUA_REGISTRYINDEX);
|
||||||
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* global variable support code: modules
|
* global variable support code: modules
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
@ -466,6 +487,7 @@ SWIGINTERN void SWIG_Lua_add_class_details(lua_State* L,swig_lua_class* clss)
|
||||||
/* performs the entire class registration process */
|
/* performs the entire class registration process */
|
||||||
SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
|
SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
/* add its constructor to module with the name of the class
|
/* add its constructor to module with the name of the class
|
||||||
so you can do MyClass(...) as well as new_MyClass(...)
|
so you can do MyClass(...) as well as new_MyClass(...)
|
||||||
BUT only if a constructor is defined
|
BUT only if a constructor is defined
|
||||||
|
|
@ -500,6 +522,20 @@ SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
|
||||||
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) */
|
||||||
|
|
||||||
|
/* set up the class base classes
|
||||||
|
we need to check the names of the classes to see if the base class exists
|
||||||
|
if so, we need to set up the pointer to it */
|
||||||
|
swig_module_info* module=SWIG_GetModule(L);
|
||||||
|
for(i=0;clss->base_names[i];i++)
|
||||||
|
{
|
||||||
|
if (clss->bases[i]==0) /* not found yet */
|
||||||
|
{
|
||||||
|
/* lookup and cache the base class */
|
||||||
|
swig_type_info *info = SWIG_TypeQueryModule(module,module,clss->base_names[i]);
|
||||||
|
if (info) clss->bases[i] = (swig_lua_class *) info->clientdata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SWIG_Lua_get_class_metatable(L,clss->name);
|
SWIG_Lua_get_class_metatable(L,clss->name);
|
||||||
SWIG_Lua_add_class_details(L,clss); /* recursive adding of details (atts & ops) */
|
SWIG_Lua_add_class_details(L,clss); /* recursive adding of details (atts & ops) */
|
||||||
lua_pop(L,1); /* tidy stack (remove class metatable) */
|
lua_pop(L,1); /* tidy stack (remove class metatable) */
|
||||||
|
|
@ -593,7 +629,6 @@ SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State* L,void* ptr,size_t size,swig_t
|
||||||
SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State* L,int index,void* ptr,size_t size,swig_type_info *type)
|
SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State* L,int index,void* ptr,size_t size,swig_type_info *type)
|
||||||
{
|
{
|
||||||
swig_lua_rawdata* raw;
|
swig_lua_rawdata* raw;
|
||||||
swig_cast_info *cast;
|
|
||||||
raw=(swig_lua_rawdata*)lua_touserdata(L,index); /* get data */
|
raw=(swig_lua_rawdata*)lua_touserdata(L,index); /* get data */
|
||||||
if (!raw) return SWIG_ERROR; /* error */
|
if (!raw) return SWIG_ERROR; /* error */
|
||||||
if (type==0 || type==raw->type) /* void* or identical type */
|
if (type==0 || type==raw->type) /* void* or identical type */
|
||||||
|
|
@ -678,26 +713,6 @@ SWIG_Lua_InstallConstants(lua_State* L, swig_lua_const_info constants[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* storing/access of swig_module_info */
|
|
||||||
SWIGRUNTIME swig_module_info *
|
|
||||||
SWIG_Lua_GetModule(lua_State* L) {
|
|
||||||
swig_module_info *ret = 0;
|
|
||||||
lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
|
|
||||||
lua_rawget(L,LUA_REGISTRYINDEX);
|
|
||||||
if (lua_islightuserdata(L,-1))
|
|
||||||
ret=(swig_module_info*)lua_touserdata(L,-1);
|
|
||||||
lua_pop(L,1); /* tidy */
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
SWIGRUNTIME void
|
|
||||||
SWIG_Lua_SetModule(lua_State* L, swig_module_info *module) {
|
|
||||||
/* add this all into the Lua registry: */
|
|
||||||
lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
|
|
||||||
lua_pushlightuserdata(L,(void*)module);
|
|
||||||
lua_rawset(L,LUA_REGISTRYINDEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,13 @@ with the relevant operators.
|
||||||
%typemap(out) long long, unsigned long long, signed long long
|
%typemap(out) long long, unsigned long long, signed long long
|
||||||
%{ lua_pushnumber(L, (lua_Number) $1); SWIG_arg++;%}
|
%{ lua_pushnumber(L, (lua_Number) $1); SWIG_arg++;%}
|
||||||
|
|
||||||
|
/* It is possible to also pass a lua_State* into a function, so
|
||||||
|
void fn(int a, float b, lua_State* s) is wrappable as
|
||||||
|
> fn(1,4.3) -- note: the state is implicitly passed in
|
||||||
|
*/
|
||||||
|
%typemap(in, numinputs=0) lua_State*
|
||||||
|
%{$1 = L;%}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* typecheck rules
|
* typecheck rules
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
|
||||||
|
|
@ -583,6 +583,7 @@ NEW LANGUAGE NOTE:END ************************************************/
|
||||||
/* Close the function */
|
/* Close the function */
|
||||||
Printv(f->code, "return SWIG_arg;\n", NIL);
|
Printv(f->code, "return SWIG_arg;\n", NIL);
|
||||||
// add the failure cleanup code:
|
// add the failure cleanup code:
|
||||||
|
Printv(f->code, "\nif(0) SWIG_fail;\n", NIL);
|
||||||
Printv(f->code, "\nfail:\n", NIL);
|
Printv(f->code, "\nfail:\n", NIL);
|
||||||
Printv(f->code, "$cleanup", "lua_error(L);\n", NIL);
|
Printv(f->code, "$cleanup", "lua_error(L);\n", NIL);
|
||||||
Printv(f->code, "return SWIG_arg;\n", NIL);
|
Printv(f->code, "return SWIG_arg;\n", NIL);
|
||||||
|
|
@ -891,8 +892,16 @@ NEW LANGUAGE NOTE:END ************************************************/
|
||||||
Delete(s_attr_tab);
|
Delete(s_attr_tab);
|
||||||
|
|
||||||
// Handle inheritance
|
// Handle inheritance
|
||||||
|
// note: with the idea of class hireachied spread over mutliple modules
|
||||||
|
// cf test-suite: imports.i
|
||||||
|
// it is not possible to just add the pointers to the base classes to the code
|
||||||
|
// (as sometimes these classes are not present)
|
||||||
|
// therefore we instead hold the name of the base class and a null pointer
|
||||||
|
// at runtime: we can query the swig type manager & see if the class exists
|
||||||
|
// if so, we can get the pointer to the base class & replace the null pointer
|
||||||
|
// if the type does not exist, then we cannot...
|
||||||
String *base_class = NewString("");
|
String *base_class = NewString("");
|
||||||
|
String *base_class_names = NewString("");
|
||||||
|
|
||||||
List *baselist = Getattr(n, "bases");
|
List *baselist = Getattr(n, "bases");
|
||||||
if (baselist && Len(baselist)) {
|
if (baselist && Len(baselist)) {
|
||||||
|
|
@ -905,44 +914,24 @@ NEW LANGUAGE NOTE:END ************************************************/
|
||||||
b = Next(b);
|
b = Next(b);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* if( itcl ) {
|
// old code: (used the pointer to the base class)
|
||||||
have_base_classes = 1;
|
//String *bmangle = Swig_name_mangle(bname);
|
||||||
Printv( base_classes, bname, " ", NIL );
|
//Printf(base_class, "&_wrap_class_%s", bmangle);
|
||||||
Printv( base_class_init , " ", bname, "Ptr::constructor $ptr\n", NIL );
|
//Putc(',', base_class);
|
||||||
}*/
|
//Delete(bmangle);
|
||||||
String *bmangle = Swig_name_mangle(bname);
|
// new code: stores a null pointer & the name
|
||||||
// Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL);
|
Printf(base_class, "0,");
|
||||||
Printf(base_class, "&_wrap_class_%s", bmangle);
|
Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname));
|
||||||
// Put code to register base classes in init function
|
|
||||||
|
|
||||||
// Printf(f_init,"/* Register base : %s */\n", bmangle);
|
|
||||||
// Printf(f_init,"swig_%s_bases[%d] = (swig_class *) SWIG_TypeQuery(\"%s *\")->clientdata;\n", mangled_classname, index, SwigType_namestr(bname));
|
|
||||||
b = Next(b);
|
b = Next(b);
|
||||||
index++;
|
index++;
|
||||||
Putc(',', base_class);
|
|
||||||
Delete(bmangle);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* List *baselist = Getattr(n,"bases");
|
|
||||||
if (baselist && Len(baselist)) {
|
|
||||||
Node *base = First(baselist);
|
|
||||||
while (base) {
|
|
||||||
String *bname = Getattr(base, "name");
|
|
||||||
if ((!bname) || GetFlag(base,"feature:ignore") || (!Getattr(base,"module"))) {
|
|
||||||
base = Next(baselist);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String *bmangle = Swig_name_mangle(bname);
|
|
||||||
Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL);
|
|
||||||
Printf(base_class,"&_wrap_class_%s",bmangle);
|
|
||||||
base = Next(baselist);
|
|
||||||
Putc(',',base_class);
|
|
||||||
Delete(bmangle);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
Printv(f_wrappers, "static swig_lua_class *swig_", mangled_classname, "_bases[] = {", base_class, "0};\n", NIL);
|
Printv(f_wrappers, "static swig_lua_class *swig_", mangled_classname, "_bases[] = {", base_class, "0};\n", NIL);
|
||||||
Delete(base_class);
|
Delete(base_class);
|
||||||
|
Printv(f_wrappers, "static char *swig_", mangled_classname, "_base_names[] = {", base_class_names, "0};\n", NIL);
|
||||||
|
Delete(base_class_names);
|
||||||
|
|
||||||
Printv(f_wrappers, "swig_lua_class _wrap_class_", mangled_classname, " = { \"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
|
Printv(f_wrappers, "swig_lua_class _wrap_class_", mangled_classname, " = { \"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
|
||||||
|
|
||||||
|
|
@ -959,7 +948,9 @@ NEW LANGUAGE NOTE:END ************************************************/
|
||||||
} else {
|
} else {
|
||||||
Printf(f_wrappers, ",0");
|
Printf(f_wrappers, ",0");
|
||||||
}
|
}
|
||||||
Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname, "_bases };\n\n", NIL);
|
Printf(f_wrappers, ", swig_%s_methods, swig_%s_attributes, swig_%s_bases, swig_%s_base_names };\n\n", mangled_classname, mangled_classname, mangled_classname, mangled_classname);
|
||||||
|
|
||||||
|
// Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname, "_bases };\n\n", NIL);
|
||||||
// Printv(s_cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_classname, "},\n", NIL);
|
// Printv(s_cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_classname, "},\n", NIL);
|
||||||
Delete(t);
|
Delete(t);
|
||||||
Delete(mangled_classname);
|
Delete(mangled_classname);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue