Skip to content

Commit fd208c7

Browse files
authored
Merge pull request #157 from gilzoide/feature/method-bind-callable
Convert Variant and LuaScriptInstance method binds to Callable
2 parents bb3b11f + 3808931 commit fd208c7

File tree

15 files changed

+301
-144
lines changed

15 files changed

+301
-144
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@
2727
+ In "Always Evaluate" behavior, Lua code will always be evaluated
2828
+ In "Don't Load" behavior, Lua code will not be loaded nor evaluated at all
2929
+ Note that only evaluated scripts can be attached to Godot Objects.
30+
- Variant and `LuaScriptInstance` methods are now converted to Callable, so they can be more easily passed to Godot APIs such as `Signal.connect`
31+
```lua
32+
-- Before this change, we had to manually instantiate Callable
33+
some_signal:connect(Callable(self, "method_name"))
34+
-- Now we can pass the method directly
35+
some_signal:connect(self.method_name)
36+
```
3037

3138
### Fixed
3239
- Fixed cyclic references from `LuaScriptInstance` <-> `LuaState`, avoiding leaks of `LuaScript`s

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ local LuaBouncingLogo = {
6767
function LuaBouncingLogo:_ready()
6868
self.position = self:get_viewport():get_size() / 2
6969
self.movement = Vector2(self.linear_velocity, 0):rotated(deg_to_rad(self.initial_angle))
70+
71+
-- To connect a signal in Lua, you can use the method name just like in GDScript
72+
self.bounced:connect(self._on_bounced)
7073
end
7174

7275
-- Called every frame. 'delta' is the elapsed time since the previous frame.
@@ -80,6 +83,10 @@ function LuaBouncingLogo:_process(delta)
8083
self.position = self.position + self.movement * delta
8184
end
8285

86+
function LuaBouncingLogo:_on_bounced()
87+
print("Bounced =D")
88+
end
89+
8390
-- Return the metadata table for the script to be usable by Godot objects
8491
return LuaBouncingLogo
8592
```

src/luaopen/variant.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131
#include "../utils/IndexedIterator.hpp"
3232
#include "../utils/ObjectIterator.hpp"
3333
#include "../utils/VariantType.hpp"
34-
#include "../utils/MethodBindByName.hpp"
3534
#include "../utils/convert_godot_lua.hpp"
3635
#include "../utils/convert_godot_std.hpp"
3736
#include "../utils/function_wrapper.hpp"
37+
#include "../utils/method_bind_impl.hpp"
3838
#include "../utils/string_names.hpp"
3939

4040
using namespace godot;
@@ -88,7 +88,7 @@ sol::object variant__index(sol::this_state state, const Variant& variant, const
8888
return to_lua(state, variant.get_named(string_name, is_valid));
8989
}
9090
else if (variant.has_method(string_name)) {
91-
return sol::make_object(state, MethodBindByName(string_name));
91+
return sol::make_object(state, VariantMethodBind(variant, string_name));
9292
}
9393
}
9494

@@ -226,7 +226,7 @@ extern "C" int luaopen_godot_variant(lua_State *L) {
226226
sol::meta_function::to_string, &Variant::stringify
227227
);
228228

229-
MethodBindByName::register_usertype(state);
229+
VariantMethodBind::register_usertype(state);
230230
VariantType::register_usertype(state);
231231

232232
state.set("typeof", &variant_get_type);

src/script-language/LuaScriptInstance.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131
#include "../LuaError.hpp"
3232
#include "../LuaFunction.hpp"
3333
#include "../LuaTable.hpp"
34-
#include "../utils/MethodBindByName.hpp"
3534
#include "../utils/VariantArguments.hpp"
3635
#include "../utils/convert_godot_lua.hpp"
3736
#include "../utils/function_wrapper.hpp"
37+
#include "../utils/method_bind_impl.hpp"
3838
#include "../utils/string_names.hpp"
3939

4040
namespace luagdextension {
@@ -328,7 +328,7 @@ static int lua_index(lua_State *L) {
328328
if (LuaScriptInstance *instance = LuaScriptInstance::find_instance(self)) {
329329
StringName key_name = key.as<StringName>();
330330
if (instance->owner->has_method(key_name)) {
331-
sol::stack::push(L, MethodBindByName(key_name));
331+
sol::stack::push(L, LuaScriptInstanceMethodBind(instance, key_name));
332332
}
333333
else {
334334
Variant value = instance->owner->get(key_name);
@@ -368,14 +368,16 @@ static int lua_to_string(lua_State *L) {
368368
}
369369

370370
void LuaScriptInstance::register_lua(lua_State *L) {
371-
metatable = sol::state_view(L).create_table_with(
371+
sol::state_view state(L);
372+
metatable = state.create_table_with(
372373
"__index", lua_index,
373374
"__newindex", lua_newindex,
374375
"__tostring", lua_to_string,
375376
"__metatable", "LuaScriptInstance"
376377
);
377378
rawget = wrap_function(L, _rawget);
378379
rawset = wrap_function(L, _rawset);
380+
LuaScriptInstanceMethodBind::register_usertype(state);
379381
}
380382

381383
void LuaScriptInstance::unregister_lua(lua_State *L) {

src/utils/Class.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
*/
2222
#include "Class.hpp"
2323

24-
#include "MethodBindByName.hpp"
2524
#include "convert_godot_lua.hpp"
25+
#include "method_bind_impl.hpp"
2626
#include "string_names.hpp"
2727

2828
#include <godot_cpp/classes/class_db_singleton.hpp>
@@ -50,16 +50,6 @@ sol::optional<int64_t> Class::get_constant(const StringName& name) const {
5050
}
5151
}
5252

53-
sol::optional<MethodBindByName> Class::get_method(const StringName& name) const {
54-
ClassDBSingleton *class_db = ClassDBSingleton::get_singleton();
55-
if (class_db->class_has_method(class_name, name)) {
56-
return MethodBindByName(name);
57-
}
58-
else {
59-
return sol::nullopt;
60-
}
61-
}
62-
6353
Variant Class::construct(sol::this_state state, const sol::variadic_args& args) const {
6454
auto class_db = ClassDBSingleton::get_singleton();
6555
if (!class_db->can_instantiate(class_name)) {
@@ -87,8 +77,8 @@ static sol::object __index(sol::this_state state, const Class& cls, sol::stack_o
8777
if (auto constant = cls.get_constant(name)) {
8878
return sol::make_object(state, *constant);
8979
}
90-
else if (auto static_method = cls.get_method(name)) {
91-
return sol::make_object(state, *static_method);
80+
else if (ClassDBSingleton::get_singleton()->class_has_method(cls.get_name(), name)) {
81+
return sol::make_object(state, ClassMethodBind(cls, name));
9282
}
9383
}
9484
return sol::nil;
@@ -100,6 +90,7 @@ void Class::register_usertype(sol::state_view& state) {
10090
sol::meta_function::index, &__index,
10191
sol::meta_function::to_string, &Class::get_name
10292
);
93+
ClassMethodBind::register_usertype(state);
10394
}
10495

10596
}

src/utils/Class.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ using namespace godot;
3030

3131
namespace luagdextension {
3232

33-
class MethodBindByName;
34-
3533
/**
3634
* Object that represents Godot classes in Lua
3735
*/
@@ -44,7 +42,6 @@ class Class {
4442

4543
const StringName& get_name() const;
4644
sol::optional<int64_t> get_constant(const StringName& name) const;
47-
sol::optional<MethodBindByName> get_method(const StringName& name) const;
4845

4946
Variant construct(sol::this_state state, const sol::variadic_args& args) const;
5047

src/utils/MethodBindByName.cpp

Lines changed: 0 additions & 70 deletions
This file was deleted.

src/utils/MethodBindByName.hpp

Lines changed: 0 additions & 50 deletions
This file was deleted.

src/utils/VariantType.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
#include "VariantType.hpp"
2323

2424
#include "Class.hpp"
25-
#include "MethodBindByName.hpp"
2625
#include "VariantArguments.hpp"
2726
#include "convert_godot_lua.hpp"
27+
#include "method_bind_impl.hpp"
2828

2929
#include <godot_cpp/classes/node.hpp>
3030
#include <godot_cpp/classes/resource.hpp>
@@ -173,7 +173,7 @@ sol::object VariantType::__index(sol::this_state L, const VariantType& type, con
173173
StringName method = key.as<StringName>();
174174
Variant empty = type.construct_default();
175175
if (empty.has_method(method)) {
176-
return sol::make_object(L, MethodBindByName(method));
176+
return sol::make_object(L, VariantTypeMethodBind(type, method));
177177
}
178178
}
179179
else if (auto subtype = key.as<sol::optional<VariantType>>()) {
@@ -206,6 +206,7 @@ void VariantType::register_usertype(sol::state_view& state) {
206206
sol::meta_function::call, &VariantType::construct,
207207
sol::meta_function::to_string, &VariantType::to_string
208208
);
209+
VariantTypeMethodBind::register_usertype(state);
209210
}
210211

211212
std::tuple<Variant::Type, StringName, Variant> VariantType::subtype_to_constructor_args(const Variant& subtype) {

src/utils/convert_godot_lua.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "convert_godot_std.hpp"
3535
#include "extra_utility_functions.hpp"
3636
#include "load_fileaccess.hpp"
37+
#include "method_bind_impl.hpp"
3738
#include "stack_top_checker.hpp"
3839

3940
#include <godot_cpp/core/error_macros.hpp>
@@ -79,6 +80,14 @@ Variant to_variant(const sol::basic_object<ref_t>& object) {
7980
Class& cls = object.template as<Class&>();
8081
return cls.get_name();
8182
}
83+
else if (object.template is<VariantMethodBind>()) {
84+
VariantMethodBind& method_bind = object.template as<VariantMethodBind&>();
85+
return method_bind.to_callable();
86+
}
87+
else if (object.template is<LuaScriptInstanceMethodBind>()) {
88+
LuaScriptInstanceMethodBind& method_bind = object.template as<LuaScriptInstanceMethodBind&>();
89+
return method_bind.to_callable();
90+
}
8291
else {
8392
return LuaObject::wrap_object<LuaUserdata>(object);
8493
}

0 commit comments

Comments
 (0)