Skip to content

Commit e1d5018

Browse files
committed
Add support for Class and fix Typed Arrays in script properties
1 parent b9aa234 commit e1d5018

File tree

5 files changed

+118
-64
lines changed

5 files changed

+118
-64
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
## [Unreleased](https://github.com/gilzoide/lua-gdextension/compare/0.5.0...HEAD)
33
### Added
44
- Support for constructing typed arrays in Lua using the idiom `Array[some_type]()`
5+
- Support for typed arrays and classes in exported properties:
6+
```lua
7+
MyScript.exported_node_array = export(Array[Node])
8+
MyScript.exported_texture_property = export(Texture)
9+
-- or
10+
MyScript.exported_node_array = export({ type = Array[Node] })
11+
MyScript.exported_texture_property = export({ type = Texture })
12+
```
513

614
### Changed
715
- `LuaScriptInstance`'s data table is passed as `self` to methods instead of their owner `Object`
@@ -10,6 +18,10 @@
1018
### Fixed
1119
- Fixed cyclic references from `LuaScriptInstance` <-> `LuaState`, avoiding leaks of `LuaScript`s
1220
- Fixed cyclic references from `LuaScriptProperty` <-> `LuaState`, avoiding memory leaks
21+
- Support for built-in Variant types in exported properties when passed directly to `export`:
22+
```lua
23+
MyScript.exported_dictionary = export(Dictionary)
24+
```
1325

1426

1527
## [0.5.0](https://github.com/gilzoide/lua-gdextension/releases/tag/0.5.0)

src/script-language/LuaScriptProperty.cpp

Lines changed: 86 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -24,88 +24,119 @@
2424
#include "LuaScriptInstance.hpp"
2525

2626
#include "../LuaCoroutine.hpp"
27+
#include "../utils/Class.hpp"
2728
#include "../utils/VariantArguments.hpp"
2829
#include "../utils/VariantType.hpp"
2930
#include "../utils/VariantTypedArray.hpp"
3031
#include "../utils/convert_godot_lua.hpp"
3132

33+
#include <godot_cpp/classes/node.hpp>
34+
#include <godot_cpp/classes/resource.hpp>
35+
3236
namespace luagdextension {
3337

34-
static LuaScriptProperty lua_property(sol::stack_object value) {
38+
static LuaScriptProperty lua_property(sol::this_state L, sol::stack_object value) {
3539
LuaScriptProperty property;
3640
property.usage = PROPERTY_USAGE_STORAGE;
3741

38-
if (auto table = value.as<sol::optional<sol::stack_table>>()) {
39-
// index 1: either a Variant type or the default value
40-
if (auto type = table->get<sol::optional<VariantType>>(1)) {
41-
property.type = type->get_type();
42-
}
43-
else if (auto typed_array = table->get<sol::optional<VariantTypedArray>>(1)) {
44-
property.type = Variant::Type::ARRAY;
45-
property.hint = PROPERTY_HINT_TYPE_STRING;
46-
property.hint_string = typed_array->get_hint_string();
47-
}
48-
else if (auto default_value = table->get<sol::optional<sol::object>>(1)) {
49-
property.default_value = to_variant(*default_value);
50-
}
42+
sol::stack_table table;
43+
if (value.get_type() == sol::type::table) {
44+
table = value;
45+
}
46+
else {
47+
lua_createtable(L, 1, 0);
48+
lua_pushvalue(L, value.stack_index());
49+
lua_rawseti(L, -2, 1);
50+
table = sol::stack_table(L, -1);
51+
}
5152

52-
// PropertyInfo fields
53-
if (auto type = table->get<sol::optional<VariantType>>("type")) {
54-
property.type = type->get_type();
55-
}
56-
else if (auto typed_array = table->get<sol::optional<VariantTypedArray>>("type")) {
57-
property.type = Variant::Type::ARRAY;
58-
property.hint = PROPERTY_HINT_TYPE_STRING;
59-
property.hint_string = typed_array->get_hint_string();
60-
}
61-
if (auto hint = table->get<sol::optional<uint32_t>>("hint")) {
62-
property.hint = *hint;
63-
}
64-
if (auto hint_string = table->get<sol::optional<String>>("hint_string")) {
65-
property.hint_string = *hint_string;
66-
}
67-
if (auto usage = table->get<sol::optional<uint32_t>>("usage")) {
68-
property.usage = *usage;
53+
// index 1: either a Variant type or the default value
54+
if (auto type = table.get<sol::optional<VariantType>>(1)) {
55+
property.type = type->get_type();
56+
property.default_value = type->construct_default();
57+
}
58+
else if (auto typed_array = table.get<sol::optional<VariantTypedArray>>(1)) {
59+
property.type = Variant::Type::ARRAY;
60+
property.hint = PROPERTY_HINT_ARRAY_TYPE;
61+
property.hint_string = typed_array->get_hint_string();
62+
property.default_value = typed_array->construct_default();
63+
}
64+
else if (auto cls = table.get<sol::optional<Class>>(1)) {
65+
property.type = Variant::Type::OBJECT;
66+
property.class_name = cls->get_name();
67+
if (ClassDB::is_parent_class(property.class_name, Node::get_class_static())) {
68+
property.hint = PROPERTY_HINT_NODE_TYPE;
69+
property.hint_string = property.class_name;
6970
}
70-
if (auto class_name = table->get<sol::optional<StringName>>("class_name")) {
71-
property.class_name = *class_name;
71+
else if (ClassDB::is_parent_class(property.class_name, Resource::get_class_static())) {
72+
property.hint = PROPERTY_HINT_RESOURCE_TYPE;
73+
property.hint_string = property.class_name;
7274
}
75+
}
76+
else if (auto default_value = table.get<sol::optional<sol::object>>(1)) {
77+
property.default_value = to_variant(*default_value);
78+
}
7379

74-
// Extra LuaScriptProperty fields
75-
if (auto default_value = table->get<sol::optional<sol::object>>("default")) {
76-
property.default_value = to_variant(*default_value);
77-
}
78-
if (auto getter_name = table->get<sol::optional<StringName>>("get")) {
79-
property.getter_name = *getter_name;
80-
property.usage &= ~PROPERTY_USAGE_STORAGE;
81-
}
82-
else if (auto getter = table->get<sol::optional<sol::protected_function>>("get")) {
83-
property.getter = *getter;
84-
property.usage &= ~PROPERTY_USAGE_STORAGE;
85-
}
86-
if (auto setter_name = table->get<sol::optional<StringName>>("set")) {
87-
property.setter_name = *setter_name;
80+
// PropertyInfo fields
81+
if (auto type = table.get<sol::optional<VariantType>>("type")) {
82+
property.type = type->get_type();
83+
if (property.default_value.get_type() == Variant::Type::NIL) {
84+
property.default_value = type->construct_default();
8885
}
89-
else if (auto setter = table->get<sol::optional<sol::protected_function>>("set")) {
90-
property.setter = *setter;
86+
}
87+
else if (auto typed_array = table.get<sol::optional<VariantTypedArray>>("type")) {
88+
property.type = Variant::Type::ARRAY;
89+
property.hint = PROPERTY_HINT_ARRAY_TYPE;
90+
property.hint_string = typed_array->get_hint_string();
91+
if (property.default_value.get_type() == Variant::Type::NIL) {
92+
property.default_value = typed_array->construct_default();
9193
}
9294
}
93-
else if (auto type = value.as<sol::optional<VariantType>>()) {
94-
property.type = type->get_type();
95+
if (auto hint = table.get<sol::optional<uint32_t>>("hint")) {
96+
property.hint = *hint;
9597
}
96-
else {
97-
property.default_value = to_variant(value);
98+
if (auto hint_string = table.get<sol::optional<String>>("hint_string")) {
99+
property.hint_string = *hint_string;
100+
}
101+
if (auto usage = table.get<sol::optional<uint32_t>>("usage")) {
102+
property.usage = *usage;
103+
}
104+
if (auto class_name = table.get<sol::optional<StringName>>("class_name")) {
105+
property.class_name = *class_name;
106+
}
107+
108+
// Extra LuaScriptProperty fields
109+
if (auto default_value = table.get<sol::optional<sol::object>>("default")) {
110+
property.default_value = to_variant(*default_value);
111+
}
112+
if (auto getter_name = table.get<sol::optional<StringName>>("get")) {
113+
property.getter_name = *getter_name;
114+
property.usage &= ~PROPERTY_USAGE_STORAGE;
115+
}
116+
else if (auto getter = table.get<sol::optional<sol::protected_function>>("get")) {
117+
property.getter = *getter;
118+
property.usage &= ~PROPERTY_USAGE_STORAGE;
119+
}
120+
if (auto setter_name = table.get<sol::optional<StringName>>("set")) {
121+
property.setter_name = *setter_name;
122+
}
123+
else if (auto setter = table.get<sol::optional<sol::protected_function>>("set")) {
124+
property.setter = *setter;
98125
}
99126

100127
if (property.type == 0) {
101128
property.type = property.default_value.get_type();
129+
if (property.default_value.get_type() == Variant::Type::ARRAY && Array(property.default_value).is_typed()) {
130+
property.hint = PROPERTY_HINT_ARRAY_TYPE;
131+
property.hint_string = VariantTypedArray::of(property.default_value).get_hint_string();
132+
}
102133
}
103134
property.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
104135
return property;
105136
}
106137

107-
static LuaScriptProperty lua_export(sol::stack_object value) {
108-
LuaScriptProperty property = lua_property(value);
138+
static LuaScriptProperty lua_export(sol::this_state L, sol::stack_object value) {
139+
LuaScriptProperty property = lua_property(L, value);
109140
property.usage |= PROPERTY_USAGE_EDITOR;
110141
return property;
111142
}

src/utils/VariantType.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ String VariantType::get_type_name() const {
4343
Variant VariantType::construct_default() const {
4444
Variant result;
4545
GDExtensionCallError error;
46-
internal::gdextension_interface_variant_construct((GDExtensionVariantType) type, &result, nullptr, 0, &error);
46+
internal::gdextension_interface_variant_construct((GDExtensionVariantType) type, result._native_ptr(), nullptr, 0, &error);
4747
ERR_FAIL_COND_V_MSG(error.error != GDEXTENSION_CALL_OK, Variant(), "Error constructing " + get_type_name());
4848
return result;
4949
}
@@ -62,7 +62,7 @@ Variant VariantType::construct(const sol::variadic_args& args) const {
6262

6363
Variant result;
6464
GDExtensionCallError error;
65-
internal::gdextension_interface_variant_construct((GDExtensionVariantType) type, &result, (GDExtensionConstVariantPtr *) variant_args.argv(), variant_args.argc(), &error);
65+
internal::gdextension_interface_variant_construct((GDExtensionVariantType) type, result._native_ptr(), (GDExtensionConstVariantPtr *) variant_args.argv(), variant_args.argc(), &error);
6666
if (error.error != GDEXTENSION_CALL_OK) {
6767
String msg = "Error constructing " + get_type_name();
6868
lua_error(args.lua_state(), error, msg);

src/utils/VariantTypedArray.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ VariantTypedArray::VariantTypedArray(Script *script)
5050
{
5151
}
5252

53+
VariantTypedArray VariantTypedArray::of(const Array& array) {
54+
VariantTypedArray ret;
55+
ret.type = (Variant::Type) array.get_typed_builtin();
56+
ret.class_name = array.get_typed_class_name();
57+
ret.script = array.get_typed_script();
58+
return ret;
59+
}
60+
5361
Variant::Type VariantTypedArray::get_type() const {
5462
return type;
5563
}
@@ -119,7 +127,7 @@ bool VariantTypedArray::operator==(const VariantTypedArray& other) const {
119127

120128
void VariantTypedArray::register_usertype(sol::state_view& state) {
121129
state.new_usertype<VariantTypedArray>(
122-
"VariantClass",
130+
"VariantTypedArray",
123131
sol::meta_function::call, &VariantTypedArray::construct,
124132
sol::meta_function::to_string, &VariantTypedArray::to_string
125133
);

src/utils/VariantTypedArray.hpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,14 @@ using namespace godot;
3232
namespace luagdextension {
3333

3434
/**
35-
* Object that represents Godot's builtin classes (a.k.a. Variants) in Lua.
35+
* Object that represents Godot's Typed Array type.
3636
*/
3737
class VariantTypedArray {
38-
protected:
39-
Variant::Type type;
40-
StringName class_name;
41-
Ref<Script> script;
42-
4338
public:
4439
VariantTypedArray(Variant::Type type);
4540
VariantTypedArray(const StringName& class_name);
4641
VariantTypedArray(Script *script);
42+
static VariantTypedArray of(const Array& array);
4743

4844
Variant::Type get_type() const;
4945
StringName get_class_name() const;
@@ -57,6 +53,13 @@ class VariantTypedArray {
5753
bool operator==(const VariantTypedArray& other) const;
5854

5955
static void register_usertype(sol::state_view& state);
56+
57+
protected:
58+
Variant::Type type;
59+
StringName class_name;
60+
Ref<Script> script;
61+
62+
VariantTypedArray() = default;
6063
};
6164

6265
}

0 commit comments

Comments
 (0)