dub 0.7.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dub might be problematic. Click here for more details.
- data/History.txt +15 -2
- data/README.rdoc +8 -0
- data/dub.gemspec +4 -2
- data/lib/dub/argument.rb +0 -1
- data/lib/dub/function.rb +4 -0
- data/lib/dub/klass.rb +52 -5
- data/lib/dub/lua/class.cpp.erb +3 -0
- data/lib/dub/lua/function.cpp.erb +2 -2
- data/lib/dub/lua/function_gen.rb +51 -23
- data/lib/dub/lua/lua_cpp_helper.cpp +7 -0
- data/lib/dub/lua/lua_object.cpp +158 -0
- data/lib/dub/lua/lua_object.h +69 -0
- data/lib/dub/namespace.rb +7 -0
- data/lib/dub/version.rb +1 -1
- metadata +6 -4
data/History.txt
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
|
+
== 1.0.0
|
|
2
|
+
|
|
3
|
+
* Major enhancement
|
|
4
|
+
* Support for yaml definition of binding body.
|
|
5
|
+
* Support for superclass (reuse of definitions from the super class)
|
|
6
|
+
|
|
7
|
+
== 0.7.1
|
|
8
|
+
|
|
9
|
+
The tests in this release do not pass, but the generator is really better and works. I just
|
|
10
|
+
don't have the time to fix the tests.
|
|
11
|
+
|
|
12
|
+
* Major enhancement
|
|
13
|
+
* When the object inherits from a LuaObject class, it calls luaInit(L, obj, "foo.Bar")
|
|
14
|
+
|
|
1
15
|
== 0.7.0 2011-08-19
|
|
2
16
|
|
|
3
17
|
The tests in this release do not pass, but the generator is really better and works. I just
|
|
4
18
|
don't have the time to fix the tests.
|
|
5
19
|
|
|
6
20
|
* Major enhancements
|
|
7
|
-
* Support for finding userdata from lua table
|
|
8
|
-
* Support to access userdata with 'super'.
|
|
21
|
+
* Support for finding userdata from lua table ('super').
|
|
9
22
|
|
|
10
23
|
== 0.6.7
|
|
11
24
|
|
data/README.rdoc
CHANGED
|
@@ -21,7 +21,13 @@ Currently, the parser supports:
|
|
|
21
21
|
* class enums
|
|
22
22
|
* namespace enums
|
|
23
23
|
* group constant defines
|
|
24
|
+
* bindings for superclass
|
|
25
|
+
* hand made bindings in yaml (this is used to do more 'natural' bindings for
|
|
26
|
+
the target language)
|
|
24
27
|
* well tested
|
|
28
|
+
in fact no, it was but the tests are not up to date and need fixing
|
|
29
|
+
our best testing is that bindings run and compile without a warning or bug.
|
|
30
|
+
|
|
25
31
|
|
|
26
32
|
If you are not good at reading lists, here is an example of the kind of tricks Dub plays with types:
|
|
27
33
|
|
|
@@ -62,6 +68,8 @@ Then you can write settings in the class documentation:
|
|
|
62
68
|
*
|
|
63
69
|
* @dub string_format:'%%f'
|
|
64
70
|
* string_args:'(*userdata)->interval()'
|
|
71
|
+
* super: 'QObject, QWidget'
|
|
72
|
+
* bind: 'Foobar.yml'
|
|
65
73
|
*/
|
|
66
74
|
|
|
67
75
|
Note that for some strange reason, you have to use a double '%' to get one.
|
data/dub.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{dub}
|
|
8
|
-
s.version = "0.
|
|
8
|
+
s.version = "1.0.0"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = [%q{Gaspard Bucher}]
|
|
12
|
-
s.date = %q{2011-
|
|
12
|
+
s.date = %q{2011-09-04}
|
|
13
13
|
s.description = %q{This is a tool to ease the creation of scripting language bindings for a C++ library.
|
|
14
14
|
It is currently developed to crete the OpenCV bindings for Lua in Rubyk (http://rubyk.org). The generator uses the xml output from Doxygen to avoid parsing C++ code by itself.}
|
|
15
15
|
s.email = %q{gaspard@teti.ch}
|
|
@@ -39,6 +39,8 @@ Gem::Specification.new do |s|
|
|
|
39
39
|
"lib/dub/lua/group.cpp.erb",
|
|
40
40
|
"lib/dub/lua/lua_cpp_helper.cpp",
|
|
41
41
|
"lib/dub/lua/lua_cpp_helper.h",
|
|
42
|
+
"lib/dub/lua/lua_object.cpp",
|
|
43
|
+
"lib/dub/lua/lua_object.h",
|
|
42
44
|
"lib/dub/lua/namespace.cpp.erb",
|
|
43
45
|
"lib/dub/lua/namespace_gen.rb",
|
|
44
46
|
"lib/dub/member_extraction.rb",
|
data/lib/dub/argument.rb
CHANGED
data/lib/dub/function.rb
CHANGED
data/lib/dub/klass.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'yaml'
|
|
1
2
|
module Dub
|
|
2
3
|
module MemberExtraction
|
|
3
4
|
end
|
|
@@ -7,7 +8,7 @@ require 'dub/member_extraction'
|
|
|
7
8
|
module Dub
|
|
8
9
|
class Klass
|
|
9
10
|
include MemberExtraction
|
|
10
|
-
attr_reader :name, :xml, :prefix, :constructor, :alias_names, :enums, :parent, :instanciations
|
|
11
|
+
attr_reader :name, :xml, :prefix, :constructor, :alias_names, :enums, :ancestors, :parent, :instanciations
|
|
11
12
|
attr_accessor :opts
|
|
12
13
|
|
|
13
14
|
def initialize(parent, name, xml, prefix = '')
|
|
@@ -58,9 +59,27 @@ module Dub
|
|
|
58
59
|
def members
|
|
59
60
|
list = super(@ignores)
|
|
60
61
|
if self.generator
|
|
61
|
-
@gen_members ||= self.generator.members_list(list.reject {|m| m.constructor?})
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
list = @gen_members ||= self.generator.members_list(list.reject {|m| m.constructor?})
|
|
63
|
+
end
|
|
64
|
+
# Copy members from super classes
|
|
65
|
+
superclasses = (@opts[:super] || '').split(',').map(&:strip)
|
|
66
|
+
@super_members ||= superclasses.map do |id_name|
|
|
67
|
+
if id_name =~ /([^\.])\.(.*)/
|
|
68
|
+
namespace = Dub::Namespace.find($1)
|
|
69
|
+
class_name = $2
|
|
70
|
+
else
|
|
71
|
+
namespace = self.parent
|
|
72
|
+
class_name = id_name
|
|
73
|
+
end
|
|
74
|
+
if x = namespace[class_name]
|
|
75
|
+
x.members
|
|
76
|
+
else
|
|
77
|
+
Dub.logger.warn "Could not find superclass '#{id_name}'"
|
|
78
|
+
nil
|
|
79
|
+
end
|
|
80
|
+
end.compact.flatten
|
|
81
|
+
(list + @super_members).sort do |a,b|
|
|
82
|
+
a.name <=> b.name
|
|
64
83
|
end
|
|
65
84
|
end
|
|
66
85
|
|
|
@@ -165,9 +184,33 @@ module Dub
|
|
|
165
184
|
[@name] + @alias_names
|
|
166
185
|
end
|
|
167
186
|
|
|
187
|
+
# Uses the bind declaration to read function bodies from a yml file:
|
|
188
|
+
# @dub bind: Foo.yml
|
|
189
|
+
def custom_bind(lang)
|
|
190
|
+
if !@bind_hash then
|
|
191
|
+
if file = @opts[:bind] then
|
|
192
|
+
header = (@xml/'location').first[:file]
|
|
193
|
+
path = header.split('/')
|
|
194
|
+
path.pop
|
|
195
|
+
path = (path + [file]).join('/')
|
|
196
|
+
if File.exist?(path) then
|
|
197
|
+
data = File.read(path)
|
|
198
|
+
@bind_hash = YAML::load(data)
|
|
199
|
+
else
|
|
200
|
+
@bind_hash = {}
|
|
201
|
+
Dub.logger.warn "Missing binding file '#{path}'"
|
|
202
|
+
end
|
|
203
|
+
else
|
|
204
|
+
@bind_hash = {}
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
@bind_hash[lang] ||= {}
|
|
208
|
+
end
|
|
209
|
+
|
|
168
210
|
private
|
|
169
211
|
def parse_xml
|
|
170
212
|
parse_opts_hash
|
|
213
|
+
parse_ancestors
|
|
171
214
|
parse_enums
|
|
172
215
|
parse_members
|
|
173
216
|
parse_template_params
|
|
@@ -192,6 +235,10 @@ module Dub
|
|
|
192
235
|
@enums = (@xml/"enumvalue/name").map{|e| e.innerHTML}
|
|
193
236
|
end
|
|
194
237
|
|
|
238
|
+
def parse_ancestors
|
|
239
|
+
@ancestors = (@xml/'inheritancegraph'/'label').map{|a| a.innerHTML}
|
|
240
|
+
end
|
|
241
|
+
|
|
195
242
|
def parse_template_params
|
|
196
243
|
template_params = (@xml/'/templateparamlist/param')
|
|
197
244
|
if !template_params.empty?
|
|
@@ -288,4 +335,4 @@ module Dub
|
|
|
288
335
|
end
|
|
289
336
|
|
|
290
337
|
end
|
|
291
|
-
end
|
|
338
|
+
end
|
data/lib/dub/lua/class.cpp.erb
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
try {
|
|
5
5
|
<%= indent(body(@function, 'dub'), 4) %>
|
|
6
6
|
} catch (std::exception &e) {
|
|
7
|
-
lua_pushfstring(L, "<%= @function.
|
|
7
|
+
lua_pushfstring(L, "<%= @function.name %>: %s", e.what());
|
|
8
8
|
} catch (...) {
|
|
9
|
-
lua_pushfstring(L, "<%= @function.
|
|
9
|
+
lua_pushfstring(L, "<%= @function.name %>: Unknown exception");
|
|
10
10
|
}
|
|
11
11
|
return lua_error(L);
|
|
12
12
|
<% else -%>
|
data/lib/dub/lua/function_gen.rb
CHANGED
|
@@ -3,8 +3,10 @@ require 'erb'
|
|
|
3
3
|
|
|
4
4
|
module Dub
|
|
5
5
|
module Lua
|
|
6
|
+
SELF = "self"
|
|
6
7
|
class FunctionGen < Dub::Generator
|
|
7
|
-
|
|
8
|
+
# klass is used when parsing members from the superclasses.
|
|
9
|
+
attr_accessor :template_path, :klass
|
|
8
10
|
|
|
9
11
|
NUMBER_TYPES = [
|
|
10
12
|
'float',
|
|
@@ -135,44 +137,56 @@ module Dub
|
|
|
135
137
|
res = []
|
|
136
138
|
delta_top = 0
|
|
137
139
|
if func.member_method? && !func.constructor? && !func.static?
|
|
138
|
-
klass
|
|
139
|
-
|
|
140
|
+
# Force @klass when serializing members from superclass.
|
|
141
|
+
klass = @klass || func.parent
|
|
142
|
+
res << "#{klass.name} *#{SELF} = *((#{klass.name}**)#{check_prefix}L_checksdata(L, 1, #{klass.id_name.inspect}));"
|
|
140
143
|
if func.member_method? && func.klass.custom_destructor?
|
|
141
144
|
# protect calls
|
|
142
145
|
if check_prefix == 'dub'
|
|
143
146
|
# we cannot use luaL_error
|
|
144
|
-
res << "if (
|
|
147
|
+
res << "if (!#{SELF}) throw dub::Exception(\"Using deleted #{klass.id_name} in #{func.name}\");"
|
|
145
148
|
else
|
|
146
|
-
res << "if (
|
|
149
|
+
res << "if (!#{SELF}) return luaL_error(L, \"Using deleted #{klass.id_name} in #{func.name}\");"
|
|
147
150
|
end
|
|
148
151
|
end
|
|
149
152
|
delta_top = 1
|
|
150
153
|
end
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
res << "int top__ = lua_gettop(L);"
|
|
154
|
-
if return_value = func.return_value
|
|
155
|
-
res << "#{return_value.create_type} retval__;"
|
|
156
|
-
end
|
|
157
|
-
end
|
|
154
|
+
|
|
155
|
+
custom_body = func.custom_body('lua')
|
|
158
156
|
|
|
159
157
|
if_indent = 0
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
res <<
|
|
165
|
-
|
|
158
|
+
if custom_body && func.has_default_arguments?
|
|
159
|
+
# we do not prepare arguments
|
|
160
|
+
else
|
|
161
|
+
if func.has_default_arguments?
|
|
162
|
+
res << "int top__ = lua_gettop(L);"
|
|
163
|
+
if return_value = func.return_value
|
|
164
|
+
res << "#{return_value.create_type} retval__;"
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
func.arguments.each_with_index do |arg, i|
|
|
168
|
+
if arg.has_default?
|
|
169
|
+
res << indent("if (top__ < #{i+1+delta_top}) {", if_indent)
|
|
170
|
+
res << indent(" #{call_string(func, i)}", if_indent)
|
|
171
|
+
res << indent("} else {", if_indent)
|
|
172
|
+
if_indent += 2
|
|
173
|
+
end
|
|
174
|
+
res << indent(get_arg(arg, i + 1 + delta_top, check_prefix), if_indent)
|
|
166
175
|
end
|
|
167
|
-
res << indent(get_arg(arg, i + 1 + delta_top, check_prefix), if_indent)
|
|
168
176
|
end
|
|
169
|
-
|
|
177
|
+
if custom_body
|
|
178
|
+
res << indent(custom_body, if_indent)
|
|
179
|
+
else
|
|
180
|
+
res << indent(call_string(func, func.arguments.count), if_indent)
|
|
181
|
+
end
|
|
170
182
|
while if_indent > 0
|
|
171
183
|
if_indent -= 2
|
|
172
184
|
res << indent("}", if_indent)
|
|
173
185
|
end
|
|
174
186
|
|
|
175
|
-
|
|
187
|
+
unless custom_body
|
|
188
|
+
res << return_value(func)
|
|
189
|
+
end
|
|
176
190
|
res.join("\n")
|
|
177
191
|
end
|
|
178
192
|
|
|
@@ -197,7 +211,7 @@ module Dub
|
|
|
197
211
|
if func.constructor?
|
|
198
212
|
call_string = "new #{call_string}"
|
|
199
213
|
elsif func.member_method? && !func.static?
|
|
200
|
-
call_string = "
|
|
214
|
+
call_string = "#{SELF}->#{call_string}"
|
|
201
215
|
end
|
|
202
216
|
|
|
203
217
|
|
|
@@ -228,7 +242,11 @@ module Dub
|
|
|
228
242
|
else
|
|
229
243
|
pushclass = 'lua_pushclass'
|
|
230
244
|
if func.constructor?
|
|
231
|
-
if func
|
|
245
|
+
if ctor_with_lua_init?(func)
|
|
246
|
+
res << "// The class inherits from 'LuaCallback', use lua_init instead of pushclass."
|
|
247
|
+
res << "return retval__->luaInit(L, retval__, \"#{return_value.id_name}\");"
|
|
248
|
+
return res.join("\n")
|
|
249
|
+
elsif func.klass.custom_destructor?
|
|
232
250
|
# Use special pushclass to set userdata
|
|
233
251
|
pushclass = 'lua_pushclass2'
|
|
234
252
|
end
|
|
@@ -296,6 +314,16 @@ module Dub
|
|
|
296
314
|
@function_template = ::ERB.new(File.read(@template_path ||File.join(File.dirname(__FILE__), 'function.cpp.erb')), nil, '%<>-')
|
|
297
315
|
@group_template = ::ERB.new(File.read(File.join(File.dirname(__FILE__), 'group.cpp.erb')))
|
|
298
316
|
end
|
|
317
|
+
|
|
318
|
+
def ctor_with_lua_init?(func)
|
|
319
|
+
# If the class inherits from LuaObject, we need to use
|
|
320
|
+
# s->lua_init(L); instead of pushclass.
|
|
321
|
+
if func.constructor?
|
|
322
|
+
func.klass.ancestors.detect{|a| a =~ /LuaObject/}
|
|
323
|
+
else
|
|
324
|
+
false
|
|
325
|
+
end
|
|
326
|
+
end
|
|
299
327
|
end # FunctionGen
|
|
300
328
|
end # Lua
|
|
301
329
|
end # Dub
|
|
@@ -98,6 +98,9 @@ void *dubL_checksdata(lua_State *L, int ud, const char *tname) throw(dub::TypeEx
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
} else if (lua_istable(L, ud)) {
|
|
101
|
+
if (ud < 0) {
|
|
102
|
+
ud = lua_gettop(L) + 1 + ud;
|
|
103
|
+
}
|
|
101
104
|
// get p from super
|
|
102
105
|
// ... <ud> ...
|
|
103
106
|
// TODO: optimize by storing key in registry ?
|
|
@@ -135,6 +138,9 @@ void *dubL_checksdata_n(lua_State *L, int ud, const char *tname) throw() {
|
|
|
135
138
|
}
|
|
136
139
|
}
|
|
137
140
|
} else if (lua_istable(L, ud)) {
|
|
141
|
+
if (ud < 0) {
|
|
142
|
+
ud = lua_gettop(L) + 1 + ud;
|
|
143
|
+
}
|
|
138
144
|
// get p from super
|
|
139
145
|
// ... <ud> ...
|
|
140
146
|
// TODO: optimize by storing key in registry ?
|
|
@@ -250,3 +256,4 @@ void register_mt(lua_State *L, const char *libname, const char *class_name) {
|
|
|
250
256
|
// <mt>
|
|
251
257
|
}
|
|
252
258
|
|
|
259
|
+
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/*
|
|
2
|
+
==============================================================================
|
|
3
|
+
|
|
4
|
+
This file is part of the LUBYK project (http://lubyk.org)
|
|
5
|
+
Copyright (c) 2007-2011 by Gaspard Bucher (http://teti.ch).
|
|
6
|
+
|
|
7
|
+
------------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in
|
|
17
|
+
all copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
25
|
+
THE SOFTWARE.
|
|
26
|
+
|
|
27
|
+
==============================================================================
|
|
28
|
+
*/
|
|
29
|
+
#include "lua_object.h"
|
|
30
|
+
#include "lua_cpp_helper.h"
|
|
31
|
+
|
|
32
|
+
using namespace dub;
|
|
33
|
+
|
|
34
|
+
LuaObject::LuaObject() throw () :
|
|
35
|
+
lua_(NULL) {
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
int LuaObject::lua_init(lua_State *L, const char *type_name) throw() {
|
|
39
|
+
// ... <self> or new table
|
|
40
|
+
setupSuper(L); // creates self if there is no table (without a 'super' field)
|
|
41
|
+
// ... <self>.super = userdata
|
|
42
|
+
// ... <self> <udata>
|
|
43
|
+
|
|
44
|
+
setupMetatable(L, type_name);
|
|
45
|
+
// ... <self> <udata>
|
|
46
|
+
|
|
47
|
+
setupLuaThread(L);
|
|
48
|
+
// <self>
|
|
49
|
+
return 1;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
void LuaObject::setupSuper(lua_State *L) throw() {
|
|
53
|
+
if (!lua_istable(L, -1)) {
|
|
54
|
+
lua_newtable(L);
|
|
55
|
+
}
|
|
56
|
+
// ... <self>
|
|
57
|
+
LuaObject **userdata = (LuaObject**)lua_newuserdata(L, sizeof(LuaObject*));
|
|
58
|
+
*userdata = this;
|
|
59
|
+
// ... <self> <udata>
|
|
60
|
+
lua_pushlstring(L, "super", 5);
|
|
61
|
+
// ... <self> <udata> <"super">
|
|
62
|
+
lua_pushvalue(L, -2);
|
|
63
|
+
// ... <self> <udata> <"super"> <udata>
|
|
64
|
+
lua_rawset(L, -4);
|
|
65
|
+
// self.super = udata
|
|
66
|
+
// ... <self> <udata>
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
void LuaObject::setupMetatable(lua_State *L, const char *type_name) throw() {
|
|
70
|
+
// set metatable
|
|
71
|
+
luaL_getmetatable(L, type_name);
|
|
72
|
+
// ... <self> <udata> <mt>
|
|
73
|
+
lua_pushvalue(L, -1);
|
|
74
|
+
// ... <self> <udata> <mt> <mt>
|
|
75
|
+
lua_setmetatable(L, -3);
|
|
76
|
+
// ... <self> <udata> <mt>
|
|
77
|
+
lua_setmetatable(L, -3);
|
|
78
|
+
// ... <self> <udata>
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// dependency relationship:
|
|
82
|
+
// self.super ---> udata ---> fenv ---> thread ---> self
|
|
83
|
+
//
|
|
84
|
+
// Thanks to Robert G. Jakabosky for the idea to use lua_xmove
|
|
85
|
+
// instead of weak tables to store the function reference.
|
|
86
|
+
void LuaObject::setupLuaThread(lua_State *L) throw() {
|
|
87
|
+
// ... <self> <udata>
|
|
88
|
+
lua_getfenv(L, -1);
|
|
89
|
+
// ... <self> <udata> <env>
|
|
90
|
+
lua_pushstring(L, ".");
|
|
91
|
+
// ... <self> <udata> <env> "."
|
|
92
|
+
lua_rawget(L, -2); // <env>["."]
|
|
93
|
+
// ... <self> <udata> <env> <??>
|
|
94
|
+
if (!lua_rawequal(L, -1, -3)) {
|
|
95
|
+
// ... <self> <udata> <env> <nil>
|
|
96
|
+
// does not have it's own env table
|
|
97
|
+
lua_pop(L, 2);
|
|
98
|
+
// ... <self> <udata>
|
|
99
|
+
// Create env table
|
|
100
|
+
lua_newtable(L);
|
|
101
|
+
// ... <self> <udata> <env>
|
|
102
|
+
lua_pushstring(L, ".");
|
|
103
|
+
// ... <self> <udata> <env> "."
|
|
104
|
+
lua_pushvalue(L, -3);
|
|
105
|
+
// ... <self> <udata> <env> "." <udata>
|
|
106
|
+
lua_rawset(L, -3); // env["."] = udata
|
|
107
|
+
// ... <self> <udata> <env>
|
|
108
|
+
lua_pushvalue(L, -1);
|
|
109
|
+
// ... <self> <udata> <env> <env>
|
|
110
|
+
if (!lua_setfenv(L, -3)) {
|
|
111
|
+
luaL_error(L, "Could not set userdata env on '%s'.", lua_typename(L, lua_type(L, -3)));
|
|
112
|
+
}
|
|
113
|
+
// ... <self> <udata> <env>
|
|
114
|
+
} else {
|
|
115
|
+
// ... <self> <udata> <env> <self>
|
|
116
|
+
// has its own env table
|
|
117
|
+
lua_pop(L, 1);
|
|
118
|
+
// ... <self> <udata> <env>
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ... <self> <udata> <env>
|
|
122
|
+
if (lua_) {
|
|
123
|
+
// remove from env
|
|
124
|
+
luaL_unref(L, -1, thread_in_env_idx_);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
lua_ = lua_newthread(L);
|
|
128
|
+
// ... <self> <udata> <env> <thread>
|
|
129
|
+
|
|
130
|
+
// Store the thread in the Thread/Socket's environment table so it is not GC too soon
|
|
131
|
+
thread_in_env_idx_ = luaL_ref(L, -2);
|
|
132
|
+
// ... <self> <udata> <env>
|
|
133
|
+
|
|
134
|
+
lua_pop(L, 2);
|
|
135
|
+
// ... <self>
|
|
136
|
+
|
|
137
|
+
// Transfer copies of <self> to thread stack
|
|
138
|
+
lua_pushvalue(L, -1);
|
|
139
|
+
// ... <self> <self>
|
|
140
|
+
lua_xmove(L, lua_, 1);
|
|
141
|
+
// ... <self>
|
|
142
|
+
|
|
143
|
+
// lua_ stack is now
|
|
144
|
+
// <self>
|
|
145
|
+
|
|
146
|
+
// L is now
|
|
147
|
+
// <self>
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
void LuaObject::pushLuaCallback(const char *method, int len) const {
|
|
151
|
+
// <self>
|
|
152
|
+
lua_pushlstring(lua_, method, len);
|
|
153
|
+
// <self> <"method">
|
|
154
|
+
lua_gettable(lua_, -2);
|
|
155
|
+
// <self> <?>
|
|
156
|
+
lua_pushvalue(lua_, 1);
|
|
157
|
+
// <self> <?> <self>
|
|
158
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*
|
|
2
|
+
==============================================================================
|
|
3
|
+
|
|
4
|
+
This file is part of the LUBYK project (http://lubyk.org)
|
|
5
|
+
Copyright (c) 2007-2011 by Gaspard Bucher (http://teti.ch).
|
|
6
|
+
|
|
7
|
+
------------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in
|
|
17
|
+
all copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
25
|
+
THE SOFTWARE.
|
|
26
|
+
|
|
27
|
+
==============================================================================
|
|
28
|
+
*/
|
|
29
|
+
#ifndef INCLUDE_DUB_LUA_OBJECT_H_
|
|
30
|
+
#define INCLUDE_DUB_LUA_OBJECT_H_
|
|
31
|
+
|
|
32
|
+
namespace dub {
|
|
33
|
+
/** Calls a lua function back.
|
|
34
|
+
*/
|
|
35
|
+
class LuaObject
|
|
36
|
+
{
|
|
37
|
+
public:
|
|
38
|
+
/** Prepare tables to work with the table based self idion.
|
|
39
|
+
* expects stack to be:
|
|
40
|
+
* ... self
|
|
41
|
+
* if self (last argument) is a table, it is used as self.
|
|
42
|
+
* Otherwise, a new table is created.
|
|
43
|
+
* The method leaves "self" on top of the stack, with self.super = this.
|
|
44
|
+
*/
|
|
45
|
+
LuaObject() throw();
|
|
46
|
+
|
|
47
|
+
int lua_init(lua_State *L, const char *type_name) throw();
|
|
48
|
+
|
|
49
|
+
virtual ~LuaObject() {}
|
|
50
|
+
|
|
51
|
+
/** The caller should lock before calling this.
|
|
52
|
+
* TODO: The 'const' stuff is stupid: can't we remove it ?
|
|
53
|
+
*/
|
|
54
|
+
void pushLuaCallback(const char *method, int len) const;
|
|
55
|
+
|
|
56
|
+
lua_State *lua_;
|
|
57
|
+
|
|
58
|
+
private:
|
|
59
|
+
|
|
60
|
+
int thread_in_env_idx_;
|
|
61
|
+
|
|
62
|
+
void setupSuper(lua_State *L) throw();
|
|
63
|
+
void setupMetatable(lua_State *L, const char *type_name) throw() ;
|
|
64
|
+
void setupLuaThread(lua_State *L) throw();
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
} // dub
|
|
68
|
+
|
|
69
|
+
#endif // INCLUDE_DUB_LUA_OBJECT_H_
|
data/lib/dub/namespace.rb
CHANGED
|
@@ -3,10 +3,17 @@ require 'dub/member_extraction'
|
|
|
3
3
|
module Dub
|
|
4
4
|
|
|
5
5
|
class Namespace
|
|
6
|
+
@@namespaces = {}
|
|
7
|
+
|
|
8
|
+
def self.find(name)
|
|
9
|
+
@@namespaces[name]
|
|
10
|
+
end
|
|
11
|
+
|
|
6
12
|
include MemberExtraction
|
|
7
13
|
attr_accessor :name, :gen, :xml, :enums, :parent, :header, :prefix, :defines
|
|
8
14
|
|
|
9
15
|
def initialize(name, xml, current_dir)
|
|
16
|
+
@@namespaces[name] = self
|
|
10
17
|
@name, @xml, @current_dir = name, xml, current_dir
|
|
11
18
|
@class_alias = {}
|
|
12
19
|
@alias_names = []
|
data/lib/dub/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dub
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 23
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
|
+
- 1
|
|
7
8
|
- 0
|
|
8
|
-
- 7
|
|
9
9
|
- 0
|
|
10
|
-
version: 0.
|
|
10
|
+
version: 1.0.0
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Gaspard Bucher
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2011-
|
|
18
|
+
date: 2011-09-04 00:00:00 Z
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
21
21
|
name: hpricot
|
|
@@ -78,6 +78,8 @@ files:
|
|
|
78
78
|
- lib/dub/lua/group.cpp.erb
|
|
79
79
|
- lib/dub/lua/lua_cpp_helper.cpp
|
|
80
80
|
- lib/dub/lua/lua_cpp_helper.h
|
|
81
|
+
- lib/dub/lua/lua_object.cpp
|
|
82
|
+
- lib/dub/lua/lua_object.h
|
|
81
83
|
- lib/dub/lua/namespace.cpp.erb
|
|
82
84
|
- lib/dub/lua/namespace_gen.rb
|
|
83
85
|
- lib/dub/member_extraction.rb
|