summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/HTTPRequest.xml30
-rw-r--r--modules/gdscript/gdscript.cpp20
-rw-r--r--modules/gdscript/gdscript.h1
-rw-r--r--modules/gdscript/gdscript_compiler.cpp31
4 files changed, 56 insertions, 26 deletions
diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml
index 641d73e333..166923314f 100644
--- a/doc/classes/HTTPRequest.xml
+++ b/doc/classes/HTTPRequest.xml
@@ -15,7 +15,7 @@
# Create an HTTP request node and connect its completion signal.
var http_request = HTTPRequest.new()
add_child(http_request)
- http_request.connect("request_completed", self, "_http_request_completed")
+ http_request.request_completed.connect(self._http_request_completed)
# Perform a GET request. The URL below returns JSON as of writing.
var error = http_request.request("https://httpbin.org/get")
@@ -25,7 +25,7 @@
# Perform a POST request. The URL below returns JSON as of writing.
# Note: Don't make simultaneous requests using a single HTTPRequest node.
# The snippet below is provided for reference only.
- var body = {"name": "Godette"}
+ var body = JSON.new().stringify({"name": "Godette"})
error = http_request.request("https://httpbin.org/post", [], true, HTTPClient.METHOD_POST, body)
if error != OK:
push_error("An error occurred in the HTTP request.")
@@ -33,7 +33,9 @@
# Called when the HTTP request is completed.
func _http_request_completed(result, response_code, headers, body):
- var response = parse_json(body.get_string_from_utf8())
+ var json = JSON.new()
+ json.parse(body.get_string_from_utf8())
+ var response = json.get_data()
# Will print the user agent string used by the HTTPRequest node (as recognized by httpbin.org).
print(response.headers["User-Agent"])
@@ -44,7 +46,7 @@
// Create an HTTP request node and connect its completion signal.
var httpRequest = new HTTPRequest();
AddChild(httpRequest);
- httpRequest.Connect("request_completed", this, nameof(HttpRequestCompleted));
+ httpRequest.RequestCompleted += HttpRequestCompleted;
// Perform a GET request. The URL below returns JSON as of writing.
Error error = httpRequest.Request("https://httpbin.org/get");
@@ -56,21 +58,24 @@
// Perform a POST request. The URL below returns JSON as of writing.
// Note: Don't make simultaneous requests using a single HTTPRequest node.
// The snippet below is provided for reference only.
- string[] body = { "name", "Godette" };
- // GDScript to_json is non existent, so we use JSON.Print() here.
- error = httpRequest.Request("https://httpbin.org/post", null, true, HTTPClient.Method.Post, JSON.Print(body));
+ string body = new JSON().Stringify(new Godot.Collections.Dictionary
+ {
+ { "name", "Godette" }
+ });
+ error = httpRequest.Request("https://httpbin.org/post", null, true, HTTPClient.Method.Post, body);
if (error != Error.Ok)
{
GD.PushError("An error occurred in the HTTP request.");
}
}
-
// Called when the HTTP request is completed.
private void HttpRequestCompleted(int result, int response_code, string[] headers, byte[] body)
{
- // GDScript parse_json is non existent so we have to use JSON.parse, which has a slightly different syntax.
- var response = JSON.Parse(body.GetStringFromUTF8()).Result as Godot.Collections.Dictionary;
+ var json = new JSON();
+ json.Parse(body.GetStringFromUTF8());
+ var response = json.GetData() as Godot.Collections.Dictionary;
+
// Will print the user agent string used by the HTTPRequest node (as recognized by httpbin.org).
GD.Print((response["headers"] as Godot.Collections.Dictionary)["User-Agent"]);
}
@@ -83,7 +88,7 @@
# Create an HTTP request node and connect its completion signal.
var http_request = HTTPRequest.new()
add_child(http_request)
- http_request.connect("request_completed", self, "_http_request_completed")
+ http_request.request_completed.connect(self._http_request_completed)
# Perform the HTTP request. The URL below returns a PNG image as of writing.
var error = http_request.request("https://via.placeholder.com/512")
@@ -115,7 +120,7 @@
// Create an HTTP request node and connect its completion signal.
var httpRequest = new HTTPRequest();
AddChild(httpRequest);
- httpRequest.Connect("request_completed", this, nameof(HttpRequestCompleted));
+ httpRequest.RequestCompleted += HttpRequestCompleted;
// Perform the HTTP request. The URL below returns a PNG image as of writing.
Error error = httpRequest.Request("https://via.placeholder.com/512");
@@ -125,7 +130,6 @@
}
}
-
// Called when the HTTP request is completed.
private void HttpRequestCompleted(int result, int response_code, string[] headers, byte[] body)
{
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 617db883f8..e6aeef2fd1 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -1254,6 +1254,14 @@ GDScript::~GDScript() {
memdelete(E.value);
}
+ if (implicit_initializer) {
+ memdelete(implicit_initializer);
+ }
+
+ if (implicit_ready) {
+ memdelete(implicit_ready);
+ }
+
if (GDScriptCache::singleton) { // Cache may have been already destroyed at engine shutdown.
GDScriptCache::remove_script(get_path());
}
@@ -1541,6 +1549,18 @@ bool GDScriptInstance::has_method(const StringName &p_method) const {
Variant GDScriptInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
GDScript *sptr = script.ptr();
+ if (unlikely(p_method == SNAME("_ready"))) {
+ // Call implicit ready first, including for the super classes.
+ while (sptr) {
+ if (sptr->implicit_ready) {
+ sptr->implicit_ready->call(this, nullptr, 0, r_error);
+ }
+ sptr = sptr->_base;
+ }
+
+ // Reset this back for the regular call.
+ sptr = script.ptr();
+ }
while (sptr) {
HashMap<StringName, GDScriptFunction *>::Iterator E = sptr->member_functions.find(p_method);
if (E) {
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 0057962d5e..feb0a237df 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -120,6 +120,7 @@ class GDScript : public Script {
GDScriptFunction *implicit_initializer = nullptr;
GDScriptFunction *initializer = nullptr; //direct pointer to new , faster to locate
+ GDScriptFunction *implicit_ready = nullptr;
int subclass_count = 0;
RBSet<Object *> instances;
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 25454030b1..16a0b17d61 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -1990,18 +1990,18 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
// Parse initializer if applies.
bool is_implicit_initializer = !p_for_ready && !p_func && !p_for_lambda;
- bool is_initializer = p_func && !p_for_lambda && String(p_func->identifier->name) == GDScriptLanguage::get_singleton()->strings._init;
- bool is_for_ready = p_for_ready || (p_func && !p_for_lambda && String(p_func->identifier->name) == "_ready");
+ bool is_initializer = p_func && !p_for_lambda && p_func->identifier->name == GDScriptLanguage::get_singleton()->strings._init;
+ bool is_implicit_ready = !p_func && p_for_ready;
- if (!p_for_lambda && (is_implicit_initializer || is_for_ready)) {
+ if (!p_for_lambda && (is_implicit_initializer || is_implicit_ready)) {
// Initialize class fields.
for (int i = 0; i < p_class->members.size(); i++) {
if (p_class->members[i].type != GDScriptParser::ClassNode::Member::VARIABLE) {
continue;
}
const GDScriptParser::VariableNode *field = p_class->members[i].variable;
- if (field->onready != is_for_ready) {
- // Only initialize in _ready.
+ if (field->onready != is_implicit_ready) {
+ // Only initialize in @implicit_ready.
continue;
}
@@ -2123,6 +2123,8 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
p_script->initializer = gd_function;
} else if (is_implicit_initializer) {
p_script->implicit_initializer = gd_function;
+ } else if (is_implicit_ready) {
+ p_script->implicit_ready = gd_function;
}
if (p_func) {
@@ -2140,7 +2142,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
#endif
}
- if (!p_for_lambda) {
+ if (!is_implicit_initializer && !is_implicit_ready && !p_for_lambda) {
p_script->member_functions[func_name] = gd_function;
}
@@ -2208,11 +2210,19 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
for (const KeyValue<StringName, GDScriptFunction *> &E : p_script->member_functions) {
memdelete(E.value);
}
+ if (p_script->implicit_initializer) {
+ memdelete(p_script->implicit_initializer);
+ }
+ if (p_script->implicit_ready) {
+ memdelete(p_script->implicit_ready);
+ }
p_script->member_functions.clear();
p_script->member_indices.clear();
p_script->member_info.clear();
p_script->_signals.clear();
p_script->initializer = nullptr;
+ p_script->implicit_initializer = nullptr;
+ p_script->implicit_ready = nullptr;
p_script->tool = parser->is_tool();
p_script->name = p_class->identifier ? p_class->identifier->name : "";
@@ -2456,15 +2466,10 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
//parse methods
- bool has_ready = false;
-
for (int i = 0; i < p_class->members.size(); i++) {
const GDScriptParser::ClassNode::Member &member = p_class->members[i];
if (member.type == member.FUNCTION) {
const GDScriptParser::FunctionNode *function = member.function;
- if (!has_ready && function->identifier->name == "_ready") {
- has_ready = true;
- }
Error err = OK;
_parse_function(err, p_script, p_class, function);
if (err) {
@@ -2498,8 +2503,8 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa
}
}
- if (!has_ready && p_class->onready_used) {
- //create a _ready constructor
+ if (p_class->onready_used) {
+ // Create an implicit_ready constructor.
Error err = OK;
_parse_function(err, p_script, p_class, nullptr, true);
if (err) {