Skip to content

Commit d7acc23

Browse files
authored
Merge pull request #185 from godotengine/master
Merge from Godot
2 parents 01acc79 + db66bd3 commit d7acc23

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+733
-366
lines changed

core/config/project_settings.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,6 @@ bool ProjectSettings::_get(const StringName &p_name, Variant &r_ret) const {
348348
_THREAD_SAFE_METHOD_
349349

350350
if (!props.has(p_name)) {
351-
WARN_PRINT("Property not found: " + String(p_name));
352351
return false;
353352
}
354353
r_ret = props[p_name].variant;

core/extension/gdextension_interface.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,14 @@ static GDExtensionBool gdextension_variant_has_key(GDExtensionConstVariantPtr p_
507507
return ret;
508508
}
509509

510+
static GDObjectInstanceID gdextension_variant_get_object_instance_id(GDExtensionConstVariantPtr p_self) {
511+
const Variant *self = (const Variant *)p_self;
512+
if (likely(self->get_type() == Variant::OBJECT)) {
513+
return self->operator ObjectID();
514+
}
515+
return 0;
516+
}
517+
510518
static void gdextension_variant_get_type_name(GDExtensionVariantType p_type, GDExtensionUninitializedVariantPtr r_ret) {
511519
String name = Variant::get_type_name((Variant::Type)p_type);
512520
memnew_placement(r_ret, String(name));
@@ -1610,6 +1618,7 @@ void gdextension_setup_interface() {
16101618
REGISTER_INTERFACE_FUNC(variant_has_method);
16111619
REGISTER_INTERFACE_FUNC(variant_has_member);
16121620
REGISTER_INTERFACE_FUNC(variant_has_key);
1621+
REGISTER_INTERFACE_FUNC(variant_get_object_instance_id);
16131622
REGISTER_INTERFACE_FUNC(variant_get_type_name);
16141623
REGISTER_INTERFACE_FUNC(variant_can_convert);
16151624
REGISTER_INTERFACE_FUNC(variant_can_convert_strict);

core/extension/gdextension_interface.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,21 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantHasMember)(GDExtensionVaria
13071307
*/
13081308
typedef GDExtensionBool (*GDExtensionInterfaceVariantHasKey)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionBool *r_valid);
13091309

1310+
/**
1311+
* @name variant_get_object_instance_id
1312+
* @since 4.4
1313+
*
1314+
* Gets the object instance ID from a variant of type GDEXTENSION_VARIANT_TYPE_OBJECT.
1315+
*
1316+
* If the variant isn't of type GDEXTENSION_VARIANT_TYPE_OBJECT, then zero will be returned.
1317+
* The instance ID will be returned even if the object is no longer valid - use `object_get_instance_by_id()` to check if the object is still valid.
1318+
*
1319+
* @param p_self A pointer to the Variant.
1320+
*
1321+
* @return The instance ID for the contained object.
1322+
*/
1323+
typedef GDObjectInstanceID (*GDExtensionInterfaceVariantGetObjectInstanceId)(GDExtensionConstVariantPtr p_self);
1324+
13101325
/**
13111326
* @name variant_get_type_name
13121327
* @since 4.1

core/io/resource.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,31 +99,42 @@ void Resource::set_path_cache(const String &p_path) {
9999
GDVIRTUAL_CALL(_set_path_cache, p_path);
100100
}
101101

102+
static thread_local RandomPCG unique_id_gen(0, RandomPCG::DEFAULT_INC);
103+
104+
void Resource::seed_scene_unique_id(uint32_t p_seed) {
105+
unique_id_gen.seed(p_seed);
106+
}
107+
102108
String Resource::generate_scene_unique_id() {
103109
// Generate a unique enough hash, but still user-readable.
104110
// If it's not unique it does not matter because the saver will try again.
105-
OS::DateTime dt = OS::get_singleton()->get_datetime();
106-
uint32_t hash = hash_murmur3_one_32(OS::get_singleton()->get_ticks_usec());
107-
hash = hash_murmur3_one_32(dt.year, hash);
108-
hash = hash_murmur3_one_32(dt.month, hash);
109-
hash = hash_murmur3_one_32(dt.day, hash);
110-
hash = hash_murmur3_one_32(dt.hour, hash);
111-
hash = hash_murmur3_one_32(dt.minute, hash);
112-
hash = hash_murmur3_one_32(dt.second, hash);
113-
hash = hash_murmur3_one_32(Math::rand(), hash);
111+
if (unique_id_gen.get_seed() == 0) {
112+
OS::DateTime dt = OS::get_singleton()->get_datetime();
113+
uint32_t hash = hash_murmur3_one_32(OS::get_singleton()->get_ticks_usec());
114+
hash = hash_murmur3_one_32(dt.year, hash);
115+
hash = hash_murmur3_one_32(dt.month, hash);
116+
hash = hash_murmur3_one_32(dt.day, hash);
117+
hash = hash_murmur3_one_32(dt.hour, hash);
118+
hash = hash_murmur3_one_32(dt.minute, hash);
119+
hash = hash_murmur3_one_32(dt.second, hash);
120+
hash = hash_murmur3_one_32(Math::rand(), hash);
121+
unique_id_gen.seed(hash);
122+
}
123+
124+
uint32_t random_num = unique_id_gen.rand();
114125

115126
static constexpr uint32_t characters = 5;
116127
static constexpr uint32_t char_count = ('z' - 'a');
117128
static constexpr uint32_t base = char_count + ('9' - '0');
118129
String id;
119130
for (uint32_t i = 0; i < characters; i++) {
120-
uint32_t c = hash % base;
131+
uint32_t c = random_num % base;
121132
if (c < char_count) {
122133
id += String::chr('a' + c);
123134
} else {
124135
id += String::chr('0' + (c - char_count));
125136
}
126-
hash /= base;
137+
random_num /= base;
127138
}
128139

129140
return id;

core/io/resource.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class Resource : public RefCounted {
114114
virtual void set_path_cache(const String &p_path); // Set raw path without involving resource cache.
115115
_FORCE_INLINE_ bool is_built_in() const { return path_cache.is_empty() || path_cache.contains("::") || path_cache.begins_with("local://"); }
116116

117+
static void seed_scene_unique_id(uint32_t p_seed);
117118
static String generate_scene_unique_id();
118119
void set_scene_unique_id(const String &p_id);
119120
String get_scene_unique_id() const;

core/io/resource_format_binary.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -845,29 +845,27 @@ Error ResourceLoaderBinary::load() {
845845
}
846846
}
847847

848-
if (ClassDB::has_property(res->get_class_name(), name)) {
849-
if (value.get_type() == Variant::ARRAY) {
850-
Array set_array = value;
851-
bool is_get_valid = false;
852-
Variant get_value = res->get(name, &is_get_valid);
853-
if (is_get_valid && get_value.get_type() == Variant::ARRAY) {
854-
Array get_array = get_value;
855-
if (!set_array.is_same_typed(get_array)) {
856-
value = Array(set_array, get_array.get_typed_builtin(), get_array.get_typed_class_name(), get_array.get_typed_script());
857-
}
848+
if (value.get_type() == Variant::ARRAY) {
849+
Array set_array = value;
850+
bool is_get_valid = false;
851+
Variant get_value = res->get(name, &is_get_valid);
852+
if (is_get_valid && get_value.get_type() == Variant::ARRAY) {
853+
Array get_array = get_value;
854+
if (!set_array.is_same_typed(get_array)) {
855+
value = Array(set_array, get_array.get_typed_builtin(), get_array.get_typed_class_name(), get_array.get_typed_script());
858856
}
859857
}
858+
}
860859

861-
if (value.get_type() == Variant::DICTIONARY) {
862-
Dictionary set_dict = value;
863-
bool is_get_valid = false;
864-
Variant get_value = res->get(name, &is_get_valid);
865-
if (is_get_valid && get_value.get_type() == Variant::DICTIONARY) {
866-
Dictionary get_dict = get_value;
867-
if (!set_dict.is_same_typed(get_dict)) {
868-
value = Dictionary(set_dict, get_dict.get_typed_key_builtin(), get_dict.get_typed_key_class_name(), get_dict.get_typed_key_script(),
869-
get_dict.get_typed_value_builtin(), get_dict.get_typed_value_class_name(), get_dict.get_typed_value_script());
870-
}
860+
if (value.get_type() == Variant::DICTIONARY) {
861+
Dictionary set_dict = value;
862+
bool is_get_valid = false;
863+
Variant get_value = res->get(name, &is_get_valid);
864+
if (is_get_valid && get_value.get_type() == Variant::DICTIONARY) {
865+
Dictionary get_dict = get_value;
866+
if (!set_dict.is_same_typed(get_dict)) {
867+
value = Dictionary(set_dict, get_dict.get_typed_key_builtin(), get_dict.get_typed_key_class_name(), get_dict.get_typed_key_script(),
868+
get_dict.get_typed_value_builtin(), get_dict.get_typed_value_class_name(), get_dict.get_typed_value_script());
871869
}
872870
}
873871
}
@@ -2136,6 +2134,8 @@ static String _resource_get_class(Ref<Resource> p_resource) {
21362134
}
21372135

21382136
Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) {
2137+
Resource::seed_scene_unique_id(p_path.hash());
2138+
21392139
Error err;
21402140
Ref<FileAccess> f;
21412141
if (p_flags & ResourceSaver::FLAG_COMPRESS) {

doc/classes/EditorContextMenuPlugin.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,24 @@
4747
[/codeblock]
4848
</description>
4949
</method>
50+
<method name="add_context_submenu_item">
51+
<return type="void" />
52+
<param index="0" name="name" type="String" />
53+
<param index="1" name="menu" type="PopupMenu" />
54+
<param index="2" name="icon" type="Texture2D" default="null" />
55+
<description>
56+
Add a submenu to the context menu of the plugin's specified slot. The submenu is not automatically handled, you need to connect to its signals yourself. Also the submenu is freed on every popup, so provide a new [PopupMenu] every time.
57+
[codeblock]
58+
func _popup_menu(paths):
59+
var popup_menu = PopupMenu.new()
60+
popup_menu.add_item("Blue")
61+
popup_menu.add_item("White")
62+
popup_menu.id_pressed.connect(_on_color_submenu_option)
63+
64+
add_context_menu_item("Set Node Color", popup_menu)
65+
[/codeblock]
66+
</description>
67+
</method>
5068
<method name="add_menu_shortcut">
5169
<return type="void" />
5270
<param index="0" name="shortcut" type="Shortcut" />

doc/classes/EditorInterface.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,14 @@
343343
[/codeblock]
344344
</description>
345345
</method>
346+
<method name="popup_quick_open">
347+
<return type="void" />
348+
<param index="0" name="callback" type="Callable" />
349+
<param index="1" name="base_types" type="StringName[]" default="[]" />
350+
<description>
351+
Pops up an editor dialog for quick selecting a resource file. The [param callback] must take a single argument of type [String] which will contain the path of the selected resource or be empty if the dialog is canceled. If [param base_types] is provided, the dialog will only show resources that match these types. Only types deriving from [Resource] are supported.
352+
</description>
353+
</method>
346354
<method name="reload_scene_from_path">
347355
<return type="void" />
348356
<param index="0" name="scene_filepath" type="String" />

doc/classes/LineEdit.xml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
- When the [LineEdit] control is focused using the keyboard arrow keys, it will only gain focus and not enter edit mode.
99
- To enter edit mode, click on the control with the mouse or press the [code]ui_text_submit[/code] action (by default [kbd]Enter[/kbd] or [kbd]Kp Enter[/kbd]).
1010
- To exit edit mode, press [code]ui_text_submit[/code] or [code]ui_cancel[/code] (by default [kbd]Escape[/kbd]) actions.
11-
- Check [method is_editing] and [signal editing_toggled] for more information.
11+
- Check [method edit], [method unedit], [method is_editing], and [signal editing_toggled] for more information.
1212
[b]Important:[/b]
1313
- Focusing the [LineEdit] with [code]ui_focus_next[/code] (by default [kbd]Tab[/kbd]) or [code]ui_focus_prev[/code] (by default [kbd]Shift + Tab[/kbd]) or [method Control.grab_focus] still enters edit mode (for compatibility).
1414
[LineEdit] features many built-in shortcuts that are always available ([kbd]Ctrl[/kbd] here maps to [kbd]Cmd[/kbd] on macOS):
@@ -75,6 +75,13 @@
7575
Clears the current selection.
7676
</description>
7777
</method>
78+
<method name="edit">
79+
<return type="void" />
80+
<description>
81+
Allows entering edit mode whether the [LineEdit] is focused or not.
82+
Use [method Callable.call_deferred] if you want to enter edit mode on [signal text_submitted].
83+
</description>
84+
</method>
7885
<method name="get_menu" qualifiers="const">
7986
<return type="PopupMenu" />
8087
<description>
@@ -223,6 +230,12 @@
223230
Selects the whole [String].
224231
</description>
225232
</method>
233+
<method name="unedit">
234+
<return type="void" />
235+
<description>
236+
Allows exiting edit mode while preserving focus.
237+
</description>
238+
</method>
226239
</methods>
227240
<members>
228241
<member name="alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0">

drivers/SCsub

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env python
22
from misc.utility.scons_hints import *
33

4+
from methods import print_error
5+
46
Import("env")
57

68
env.drivers_sources = []
@@ -20,7 +22,7 @@ if env["platform"] == "windows":
2022
SConscript("backtrace/SCsub")
2123
if env["xaudio2"]:
2224
if "xaudio2" not in supported:
23-
print("Target platform '{}' does not support the XAudio2 audio driver. Aborting.".format(env["platform"]))
25+
print_error("Target platform '{}' does not support the XAudio2 audio driver".format(env["platform"]))
2426
Exit(255)
2527
SConscript("xaudio2/SCsub")
2628

@@ -34,7 +36,7 @@ if env["vulkan"]:
3436
SConscript("vulkan/SCsub")
3537
if env["d3d12"]:
3638
if "d3d12" not in supported:
37-
print("Target platform '{}' does not support the D3D12 rendering driver. Aborting.".format(env["platform"]))
39+
print_error("Target platform '{}' does not support the D3D12 rendering driver".format(env["platform"]))
3840
Exit(255)
3941
SConscript("d3d12/SCsub")
4042
if env["opengl3"]:
@@ -43,7 +45,7 @@ if env["opengl3"]:
4345
SConscript("egl/SCsub")
4446
if env["metal"]:
4547
if "metal" not in supported:
46-
print("Target platform '{}' does not support the Metal rendering driver. Aborting.".format(env["platform"]))
48+
print_error("Target platform '{}' does not support the Metal rendering driver".format(env["platform"]))
4749
Exit(255)
4850
SConscript("metal/SCsub")
4951

0 commit comments

Comments
 (0)