summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/core_constants.cpp2
-rw-r--r--core/doc_data.cpp18
-rw-r--r--core/error/error_list.cpp98
-rw-r--r--core/error/error_list.h5
-rw-r--r--core/extension/extension_api_dump.cpp23
-rw-r--r--core/input/input.cpp20
-rw-r--r--core/input/input_event.cpp9
-rw-r--r--core/input/input_event.h3
-rw-r--r--core/input/input_map.cpp18
-rw-r--r--core/input/input_map.h3
-rw-r--r--core/input/shortcut.cpp76
-rw-r--r--core/input/shortcut.h54
-rw-r--r--core/io/resource.cpp9
-rw-r--r--core/io/resource_loader.cpp88
-rw-r--r--core/io/resource_loader.h12
-rw-r--r--core/io/resource_saver.cpp35
-rw-r--r--core/io/resource_saver.h6
-rw-r--r--core/math/a_star.cpp28
-rw-r--r--core/math/a_star.h8
-rw-r--r--core/math/camera_matrix.cpp4
-rw-r--r--core/math/convex_hull.h2
-rw-r--r--core/math/dynamic_bvh.h2
-rw-r--r--core/math/transform_3d.h2
-rw-r--r--core/math/triangulate.h2
-rw-r--r--core/object/class_db.cpp15
-rw-r--r--core/object/class_db.h13
-rw-r--r--core/object/make_virtuals.py19
-rw-r--r--core/object/method_bind.h1
-rw-r--r--core/object/object.cpp15
-rw-r--r--core/object/object.h10
-rw-r--r--core/object/ref_counted.h4
-rw-r--r--core/os/main_loop.cpp29
-rw-r--r--core/os/main_loop.h6
-rw-r--r--core/register_core_types.cpp3
-rw-r--r--core/templates/map.h2
-rw-r--r--core/templates/rid_owner.h10
-rw-r--r--core/templates/set.h2
-rw-r--r--core/variant/method_ptrcall.h7
-rw-r--r--core/variant/native_ptr.h130
-rw-r--r--core/variant/typed_array.h10
-rw-r--r--core/variant/variant_call.cpp1
-rw-r--r--core/variant/variant_utility.cpp12
42 files changed, 592 insertions, 224 deletions
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index 5791f79053..4f3f1fd16e 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -558,6 +558,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NODE_PATH_VALID_TYPES);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_SAVE_FILE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INT_IS_OBJECTID);
+ BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INT_IS_POINTER);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ARRAY_TYPE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX);
@@ -605,6 +606,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_VIRTUAL);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_FROM_SCRIPT);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_STATIC);
+ BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_OBJECT_CORE);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAGS_DEFAULT);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL);
diff --git a/core/doc_data.cpp b/core/doc_data.cpp
index 45450bf97a..4b284a30aa 100644
--- a/core/doc_data.cpp
+++ b/core/doc_data.cpp
@@ -31,7 +31,14 @@
#include "doc_data.h"
void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo) {
- if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ if (p_retinfo.type == Variant::INT && p_retinfo.hint == PROPERTY_HINT_INT_IS_POINTER) {
+ p_method.return_type = p_retinfo.hint_string;
+ if (p_method.return_type == "") {
+ p_method.return_type = "void*";
+ } else {
+ p_method.return_type += "*";
+ }
+ } else if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
p_method.return_enum = p_retinfo.class_name;
if (p_method.return_enum.begins_with("_")) { //proxy class
p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length());
@@ -55,7 +62,14 @@ void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const Proper
void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo) {
p_argument.name = p_arginfo.name;
- if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ if (p_arginfo.type == Variant::INT && p_arginfo.hint == PROPERTY_HINT_INT_IS_POINTER) {
+ p_argument.type = p_arginfo.hint_string;
+ if (p_argument.type == "") {
+ p_argument.type = "void*";
+ } else {
+ p_argument.type += "*";
+ }
+ } else if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
p_argument.enumeration = p_arginfo.class_name;
if (p_argument.enumeration.begins_with("_")) { //proxy class
p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length());
diff --git a/core/error/error_list.cpp b/core/error/error_list.cpp
index a8355065fe..e1e94dd65d 100644
--- a/core/error/error_list.cpp
+++ b/core/error/error_list.cpp
@@ -31,55 +31,55 @@
#include "error_list.h"
const char *error_names[] = {
- "No error",
- "Generic error",
- "Requested operation is unsupported/unavailable",
- "The object hasn't been set up properly",
- "Missing credentials for requested resource",
- "Parameter out of range",
- "Out of memory",
- "File not found",
- "Bad drive",
- "Bad path",
- "Permission denied",
- "Already in use",
- "Can't open file",
- "Can't write file",
- "Can't read file",
- "File unrecognized",
- "File corrupt",
- "Missing dependencies for file",
- "Unexpected eof",
- "Can't open resource/socket/file", // File too? What's the difference to ERR_FILE_CANT_OPEN
- "Can't create", // What can't be created,
- "Query failed", // What query,
- "Already in use",
- "Resource is locked",
- "Timeout",
- "Can't connect",
- "Can't resolve hostname", // I guessed it's the hostname here.
- "Connection error",
- "Can't acquire resource",
- "Can't fork",
- "Invalid data",
- "Invalid parameter",
- "Item already exists",
- "Item does not exist",
- "Can't read from database", // Comments say, it's full? Is that correct?
- "Can't write to database", // Is the database always full when this is raised?
- "Compilation failed",
- "Method not found",
- "Link failed",
- "Script failed",
- "Cyclic link detected",
- "Invalid declaration",
- "Duplicate symbol",
- "Parse error",
- "Resource is busy",
- "Skip error", // ???? What's this? String taken from the docs
- "Help error", // More specific?
- "Bug",
- "Printer on fire",
+ "OK", // OK
+ "Failed", // FAILED
+ "Unavailable", // ERR_UNAVAILABLE
+ "Unconfigured", // ERR_UNCONFIGURED
+ "Unauthorized", // ERR_UNAUTHORIZED
+ "Parameter out of range", // ERR_PARAMETER_RANGE_ERROR
+ "Out of memory", // ERR_OUT_OF_MEMORY
+ "File not found", // ERR_FILE_NOT_FOUND
+ "File: Bad drive", // ERR_FILE_BAD_DRIVE
+ "File: Bad path", // ERR_FILE_BAD_PATH
+ "File: Permission denied", // ERR_FILE_NO_PERMISSION
+ "File already in use", // ERR_FILE_ALREADY_IN_USE
+ "Can't open file", // ERR_FILE_CANT_OPEN
+ "Can't write file", // ERR_FILE_CANT_WRITE
+ "Can't read file", // ERR_FILE_CANT_READ
+ "File unrecognized", // ERR_FILE_UNRECOGNIZED
+ "File corrupt", // ERR_FILE_CORRUPT
+ "Missing dependencies for file", // ERR_FILE_MISSING_DEPENDENCIES
+ "End of file", // ERR_FILE_EOF
+ "Can't open", // ERR_CANT_OPEN
+ "Can't create", // ERR_CANT_CREATE
+ "Query failed", // ERR_QUERY_FAILED
+ "Already in use", // ERR_ALREADY_IN_USE
+ "Locked", // ERR_LOCKED
+ "Timeout", // ERR_TIMEOUT
+ "Can't connect", // ERR_CANT_CONNECT
+ "Can't resolve", // ERR_CANT_RESOLVE
+ "Connection error", // ERR_CONNECTION_ERROR
+ "Can't acquire resource", // ERR_CANT_ACQUIRE_RESOURCE
+ "Can't fork", // ERR_CANT_FORK
+ "Invalid data", // ERR_INVALID_DATA
+ "Invalid parameter", // ERR_INVALID_PARAMETER
+ "Already exists", // ERR_ALREADY_EXISTS
+ "Does not exist", // ERR_DOES_NOT_EXIST
+ "Can't read database", // ERR_DATABASE_CANT_READ
+ "Can't write database", // ERR_DATABASE_CANT_WRITE
+ "Compilation failed", // ERR_COMPILATION_FAILED
+ "Method not found", // ERR_METHOD_NOT_FOUND
+ "Link failed", // ERR_LINK_FAILED
+ "Script failed", // ERR_SCRIPT_FAILED
+ "Cyclic link detected", // ERR_CYCLIC_LINK
+ "Invalid declaration", // ERR_INVALID_DECLARATION
+ "Duplicate symbol", // ERR_DUPLICATE_SYMBOL
+ "Parse error", // ERR_PARSE_ERROR
+ "Busy", // ERR_BUSY
+ "Skip", // ERR_SKIP
+ "Help", // ERR_HELP
+ "Bug", // ERR_BUG
+ "Printer on fire", // ERR_PRINTER_ON_FIRE
};
static_assert(sizeof(error_names) / sizeof(*error_names) == ERR_MAX);
diff --git a/core/error/error_list.h b/core/error/error_list.h
index e7c7f10265..852825dda5 100644
--- a/core/error/error_list.h
+++ b/core/error/error_list.h
@@ -36,6 +36,11 @@
* values can be more detailed in the future.
*
* This is a generic error list, mainly for organizing a language of returning errors.
+ *
+ * Errors:
+ * - Are added to the Error enum in core/error/error_list.h
+ * - Have a description added to error_names in core/error/error_list.cpp
+ * - Are bound with BIND_CORE_ENUM_CONSTANT() in core/core_constants.cpp
*/
enum Error {
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index 49570cd1c1..a8547a0090 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -39,6 +39,13 @@
#ifdef TOOLS_ENABLED
static String get_type_name(const PropertyInfo &p_info) {
+ if (p_info.type == Variant::INT && (p_info.hint == PROPERTY_HINT_INT_IS_POINTER)) {
+ if (p_info.hint_string == "") {
+ return "void*";
+ } else {
+ return p_info.hint_string + "*";
+ }
+ }
if (p_info.type == Variant::INT && (p_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM)) {
return String("enum::") + String(p_info.class_name);
}
@@ -653,7 +660,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
ClassDB::get_method_list(class_name, &method_list, true);
for (const MethodInfo &F : method_list) {
StringName method_name = F.name;
- if (F.flags & METHOD_FLAG_VIRTUAL) {
+ if ((F.flags & METHOD_FLAG_VIRTUAL) && !(F.flags & METHOD_FLAG_OBJECT_CORE)) {
//virtual method
const MethodInfo &mi = F;
Dictionary d2;
@@ -831,6 +838,20 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
}
}
+ {
+ Array native_structures;
+
+ {
+ Dictionary d;
+ d["name"] = "AudioFrame";
+ d["format"] = "float left,float right";
+
+ native_structures.push_back(d);
+ }
+
+ api_dump["native_structures"] = native_structures;
+ }
+
return api_dump;
}
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 72563cc40a..9195f7d8b5 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -240,18 +240,12 @@ bool Input::is_joy_button_pressed(int p_device, JoyButton p_button) const {
}
bool Input::is_action_pressed(const StringName &p_action, bool p_exact) const {
-#ifdef DEBUG_ENABLED
- bool has_action = InputMap::get_singleton()->has_action(p_action);
- ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
-#endif
+ ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
return action_state.has(p_action) && action_state[p_action].pressed && (p_exact ? action_state[p_action].exact : true);
}
bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) const {
-#ifdef DEBUG_ENABLED
- bool has_action = InputMap::get_singleton()->has_action(p_action);
- ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
-#endif
+ ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) {
return false;
@@ -269,10 +263,7 @@ bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) con
}
bool Input::is_action_just_released(const StringName &p_action, bool p_exact) const {
-#ifdef DEBUG_ENABLED
- bool has_action = InputMap::get_singleton()->has_action(p_action);
- ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
-#endif
+ ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) {
return false;
@@ -290,10 +281,7 @@ bool Input::is_action_just_released(const StringName &p_action, bool p_exact) co
}
float Input::get_action_strength(const StringName &p_action, bool p_exact) const {
-#ifdef DEBUG_ENABLED
- bool has_action = InputMap::get_singleton()->has_action(p_action);
- ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
-#endif
+ ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), 0.0, InputMap::get_singleton()->suggest_actions(p_action));
const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) {
return 0.0f;
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index 325cdf2127..50b2099236 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -31,8 +31,8 @@
#include "input_event.h"
#include "core/input/input_map.h"
+#include "core/input/shortcut.h"
#include "core/os/keyboard.h"
-#include "scene/gui/shortcut.h"
const int InputEvent::DEVICE_ID_TOUCH_MOUSE = -1;
const int InputEvent::DEVICE_ID_INTERNAL = -2;
@@ -1545,6 +1545,13 @@ Ref<Shortcut> InputEventShortcut::get_shortcut() {
return shortcut;
}
+void InputEventShortcut::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_shortcut", "shortcut"), &InputEventShortcut::set_shortcut);
+ ClassDB::bind_method(D_METHOD("get_shortcut"), &InputEventShortcut::get_shortcut);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "Shortcut"), "set_shortcut", "get_shortcut");
+}
+
bool InputEventShortcut::is_pressed() const {
return true;
}
diff --git a/core/input/input_event.h b/core/input/input_event.h
index 517d63eb40..3fc8078a09 100644
--- a/core/input/input_event.h
+++ b/core/input/input_event.h
@@ -548,6 +548,9 @@ class InputEventShortcut : public InputEvent {
Ref<Shortcut> shortcut;
+protected:
+ static void _bind_methods();
+
public:
void set_shortcut(Ref<Shortcut> p_shortcut);
Ref<Shortcut> get_shortcut();
diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp
index 83ec70757e..c7ca65f61a 100644
--- a/core/input/input_map.cpp
+++ b/core/input/input_map.cpp
@@ -59,7 +59,7 @@ void InputMap::_bind_methods() {
* Returns an nonexistent action error message with a suggestion of the closest
* matching action name (if possible).
*/
-String InputMap::_suggest_actions(const StringName &p_action) const {
+String InputMap::suggest_actions(const StringName &p_action) const {
List<StringName> actions = get_actions();
StringName closest_action;
float closest_similarity = 0.0;
@@ -93,7 +93,7 @@ void InputMap::add_action(const StringName &p_action, float p_deadzone) {
}
void InputMap::erase_action(const StringName &p_action) {
- ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
+ ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action));
input_map.erase(p_action);
}
@@ -147,20 +147,20 @@ bool InputMap::has_action(const StringName &p_action) const {
}
float InputMap::action_get_deadzone(const StringName &p_action) {
- ERR_FAIL_COND_V_MSG(!input_map.has(p_action), 0.0f, _suggest_actions(p_action));
+ ERR_FAIL_COND_V_MSG(!input_map.has(p_action), 0.0f, suggest_actions(p_action));
return input_map[p_action].deadzone;
}
void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone) {
- ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
+ ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action));
input_map[p_action].deadzone = p_deadzone;
}
void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object.");
- ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
+ ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action));
if (_find_event(input_map[p_action], p_event, true)) {
return; // Already added.
}
@@ -169,12 +169,12 @@ void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent
}
bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
- ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, _suggest_actions(p_action));
+ ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, suggest_actions(p_action));
return (_find_event(input_map[p_action], p_event, true) != nullptr);
}
void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
- ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
+ ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action));
List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event, true);
if (E) {
@@ -186,7 +186,7 @@ void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEve
}
void InputMap::action_erase_events(const StringName &p_action) {
- ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
+ ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action));
input_map[p_action].inputs.clear();
}
@@ -218,7 +218,7 @@ bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName
bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
OrderedHashMap<StringName, Action>::Element E = input_map.find(p_action);
- ERR_FAIL_COND_V_MSG(!E, false, _suggest_actions(p_action));
+ ERR_FAIL_COND_V_MSG(!E, false, suggest_actions(p_action));
Ref<InputEventAction> input_event_action = p_event;
if (input_event_action.is_valid()) {
diff --git a/core/input/input_map.h b/core/input/input_map.h
index 0e0567464a..a2d3952f94 100644
--- a/core/input/input_map.h
+++ b/core/input/input_map.h
@@ -61,7 +61,6 @@ private:
Array _action_get_events(const StringName &p_action);
Array _get_actions();
- String _suggest_actions(const StringName &p_action) const;
protected:
static void _bind_methods();
@@ -89,6 +88,8 @@ public:
void load_from_project_settings();
void load_default();
+ String suggest_actions(const StringName &p_action) const;
+
String get_builtin_display_name(const String &p_name) const;
// Use an Ordered Map so insertion order is preserved. We want the elements to be 'grouped' somewhat.
const OrderedHashMap<String, List<Ref<InputEvent>>> &get_builtins();
diff --git a/core/input/shortcut.cpp b/core/input/shortcut.cpp
new file mode 100644
index 0000000000..d0cb08724e
--- /dev/null
+++ b/core/input/shortcut.cpp
@@ -0,0 +1,76 @@
+/*************************************************************************/
+/* shortcut.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "shortcut.h"
+#include "core/os/keyboard.h"
+
+void Shortcut::set_event(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND_MSG(Object::cast_to<InputEventShortcut>(*p_event), "Cannot set a shortcut event to an instance of InputEventShortcut.");
+ event = p_event;
+ emit_changed();
+}
+
+Ref<InputEvent> Shortcut::get_event() const {
+ return event;
+}
+
+bool Shortcut::matches_event(const Ref<InputEvent> &p_event) const {
+ Ref<InputEventShortcut> ies = p_event;
+ if (ies.is_valid()) {
+ if (ies->get_shortcut().ptr() == this) {
+ return true;
+ }
+ }
+ return event.is_valid() && event->is_match(p_event, true);
+}
+
+String Shortcut::get_as_text() const {
+ if (event.is_valid()) {
+ return event->as_text();
+ } else {
+ return "None";
+ }
+}
+
+bool Shortcut::has_valid_event() const {
+ return event.is_valid();
+}
+
+void Shortcut::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_event", "event"), &Shortcut::set_event);
+ ClassDB::bind_method(D_METHOD("get_event"), &Shortcut::get_event);
+
+ ClassDB::bind_method(D_METHOD("has_valid_event"), &Shortcut::has_valid_event);
+
+ ClassDB::bind_method(D_METHOD("matches_event", "event"), &Shortcut::matches_event);
+ ClassDB::bind_method(D_METHOD("get_as_text"), &Shortcut::get_as_text);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), "set_event", "get_event");
+}
diff --git a/core/input/shortcut.h b/core/input/shortcut.h
new file mode 100644
index 0000000000..249dd1971f
--- /dev/null
+++ b/core/input/shortcut.h
@@ -0,0 +1,54 @@
+/*************************************************************************/
+/* shortcut.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef SHORTCUT_H
+#define SHORTCUT_H
+
+#include "core/input/input_event.h"
+#include "core/io/resource.h"
+
+class Shortcut : public Resource {
+ GDCLASS(Shortcut, Resource);
+
+ Ref<InputEvent> event;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_event(const Ref<InputEvent> &p_shortcut);
+ Ref<InputEvent> get_event() const;
+ bool matches_event(const Ref<InputEvent> &p_event) const;
+ bool has_valid_event() const;
+
+ String get_as_text() const;
+};
+
+#endif // SHORTCUT_H
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index 0262655927..87b4d7195d 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -352,9 +352,8 @@ Node *Resource::get_local_scene() const {
}
void Resource::setup_local_to_scene() {
- if (get_script_instance()) {
- get_script_instance()->call("_setup_local_to_scene");
- }
+ // Can't use GDVIRTUAL in Resource, so this will have to be done with a signal
+ emit_signal(SNAME("setup_local_to_scene_requested"));
}
Node *(*Resource::_get_local_scene_func)() = nullptr;
@@ -422,12 +421,12 @@ void Resource::_bind_methods() {
ClassDB::bind_method(D_METHOD("duplicate", "subresources"), &Resource::duplicate, DEFVAL(false));
ADD_SIGNAL(MethodInfo("changed"));
+ ADD_SIGNAL(MethodInfo("setup_local_to_scene_requested"));
+
ADD_GROUP("Resource", "resource_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resource_local_to_scene"), "set_local_to_scene", "is_local_to_scene");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "resource_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_path", "get_path");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "resource_name"), "set_name", "get_name");
-
- BIND_VMETHOD(MethodInfo("_setup_local_to_scene"));
}
Resource::Resource() :
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index d02d827443..64237f3b15 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -68,25 +68,28 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_
}
bool ResourceFormatLoader::handles_type(const String &p_type) const {
- if (get_script_instance() && get_script_instance()->has_method("_handles_type")) {
- // I guess custom loaders for custom resources should use "Resource"
- return get_script_instance()->call("_handles_type", p_type);
+ bool success;
+ if (GDVIRTUAL_CALL(_handles_type, p_type, success)) {
+ return success;
}
return false;
}
String ResourceFormatLoader::get_resource_type(const String &p_path) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_resource_type")) {
- return get_script_instance()->call("_get_resource_type", p_path);
+ String ret;
+
+ if (GDVIRTUAL_CALL(_get_resource_type, p_path, ret)) {
+ return ret;
}
return "";
}
ResourceUID::ID ResourceFormatLoader::get_resource_uid(const String &p_path) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_resource_uid")) {
- return get_script_instance()->call("_get_resource_uid", p_path);
+ int64_t uid;
+ if (GDVIRTUAL_CALL(_get_resource_uid, p_path, uid)) {
+ return uid;
}
return ResourceUID::INVALID_ID;
@@ -105,27 +108,26 @@ void ResourceLoader::get_recognized_extensions_for_type(const String &p_type, Li
}
bool ResourceFormatLoader::exists(const String &p_path) const {
+ bool success;
+ if (GDVIRTUAL_CALL(_exists, p_path, success)) {
+ return success;
+ }
return FileAccess::exists(p_path); //by default just check file
}
void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_recognized_extensions")) {
- PackedStringArray exts = get_script_instance()->call("_get_recognized_extensions");
-
- {
- const String *r = exts.ptr();
- for (int i = 0; i < exts.size(); ++i) {
- p_extensions->push_back(r[i]);
- }
+ PackedStringArray exts;
+ if (GDVIRTUAL_CALL(_get_recognized_extensions, exts)) {
+ const String *r = exts.ptr();
+ for (int i = 0; i < exts.size(); ++i) {
+ p_extensions->push_back(r[i]);
}
}
}
RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
- // Check user-defined loader if there's any. Hard fail if it returns an error.
- if (get_script_instance() && get_script_instance()->has_method("_load")) {
- Variant res = get_script_instance()->call("_load", p_path, p_original_path, p_use_sub_threads, p_cache_mode);
-
+ Variant res;
+ if (GDVIRTUAL_CALL(_load, p_path, p_original_path, p_use_sub_threads, p_cache_mode, res)) {
if (res.get_type() == Variant::INT) { // Error code, abort.
if (r_error) {
*r_error = (Error)res.operator int64_t();
@@ -143,48 +145,42 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa
}
void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
- if (get_script_instance() && get_script_instance()->has_method("_get_dependencies")) {
- PackedStringArray deps = get_script_instance()->call("_get_dependencies", p_path, p_add_types);
-
- {
- const String *r = deps.ptr();
- for (int i = 0; i < deps.size(); ++i) {
- p_dependencies->push_back(r[i]);
- }
+ PackedStringArray deps;
+ if (GDVIRTUAL_CALL(_get_dependencies, p_path, p_add_types, deps)) {
+ const String *r = deps.ptr();
+ for (int i = 0; i < deps.size(); ++i) {
+ p_dependencies->push_back(r[i]);
}
}
}
Error ResourceFormatLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
- if (get_script_instance() && get_script_instance()->has_method("_rename_dependencies")) {
- Dictionary deps_dict;
- for (Map<String, String>::Element *E = p_map.front(); E; E = E->next()) {
- deps_dict[E->key()] = E->value();
- }
+ Dictionary deps_dict;
+ for (Map<String, String>::Element *E = p_map.front(); E; E = E->next()) {
+ deps_dict[E->key()] = E->value();
+ }
- int64_t res = get_script_instance()->call("_rename_dependencies", deps_dict);
- return (Error)res;
+ int64_t err;
+ if (GDVIRTUAL_CALL(_rename_dependencies, p_path, deps_dict, err)) {
+ return (Error)err;
}
return OK;
}
void ResourceFormatLoader::_bind_methods() {
- {
- MethodInfo info = MethodInfo(Variant::NIL, "_load", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "original_path"), PropertyInfo(Variant::BOOL, "use_sub_threads"), PropertyInfo(Variant::INT, "cache_mode"));
- info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
- BIND_VMETHOD(info);
- }
-
- BIND_VMETHOD(MethodInfo(Variant::PACKED_STRING_ARRAY, "_get_recognized_extensions"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_handles_type", PropertyInfo(Variant::STRING_NAME, "typename")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_resource_type", PropertyInfo(Variant::STRING, "path")));
- BIND_VMETHOD(MethodInfo("_get_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "add_types")));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_rename_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "renames")));
-
BIND_ENUM_CONSTANT(CACHE_MODE_IGNORE);
BIND_ENUM_CONSTANT(CACHE_MODE_REUSE);
BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE);
+
+ GDVIRTUAL_BIND(_get_recognized_extensions);
+ GDVIRTUAL_BIND(_handles_type, "type");
+ GDVIRTUAL_BIND(_get_resource_type, "path");
+ GDVIRTUAL_BIND(_get_resource_uid, "path");
+ GDVIRTUAL_BIND(_get_dependencies, "path", "add_types");
+ GDVIRTUAL_BIND(_rename_dependencies, "path", "renames");
+ GDVIRTUAL_BIND(_exists, "path");
+ GDVIRTUAL_BIND(_load, "path", "original_path", "use_sub_threads", "cache_mode");
}
///////////////////////////////////
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index e525e80a9d..f1d9815635 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -32,6 +32,8 @@
#define RESOURCE_LOADER_H
#include "core/io/resource.h"
+#include "core/object/gdvirtual.gen.inc"
+#include "core/object/script_language.h"
#include "core/os/semaphore.h"
#include "core/os/thread.h"
@@ -48,6 +50,16 @@ public:
protected:
static void _bind_methods();
+ GDVIRTUAL0RC(Vector<String>, _get_recognized_extensions)
+ GDVIRTUAL1RC(bool, _handles_type, StringName)
+ GDVIRTUAL1RC(String, _get_resource_type, String)
+ GDVIRTUAL1RC(ResourceUID::ID, _get_resource_uid, String)
+ GDVIRTUAL2RC(Vector<String>, _get_dependencies, String, bool)
+ GDVIRTUAL2RC(int64_t, _rename_dependencies, String, Dictionary)
+ GDVIRTUAL1RC(bool, _exists, String)
+
+ GDVIRTUAL4RC(Variant, _load, String, String, bool, int)
+
public:
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual bool exists(const String &p_path) const;
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index 564de5ee69..823b5f75b1 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -42,44 +42,37 @@ ResourceSavedCallback ResourceSaver::save_callback = nullptr;
ResourceSaverGetResourceIDForPath ResourceSaver::save_get_id_for_path = nullptr;
Error ResourceFormatSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
- if (get_script_instance() && get_script_instance()->has_method("_save")) {
- return (Error)get_script_instance()->call("_save", p_path, p_resource, p_flags).operator int64_t();
+ int64_t res;
+ if (GDVIRTUAL_CALL(_save, p_path, p_resource, p_flags, res)) {
+ return (Error)res;
}
return ERR_METHOD_NOT_FOUND;
}
bool ResourceFormatSaver::recognize(const RES &p_resource) const {
- if (get_script_instance() && get_script_instance()->has_method("_recognize")) {
- return get_script_instance()->call("_recognize", p_resource);
+ bool success;
+ if (GDVIRTUAL_CALL(_recognize, p_resource, success)) {
+ return success;
}
return false;
}
void ResourceFormatSaver::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_recognized_extensions")) {
- PackedStringArray exts = get_script_instance()->call("_get_recognized_extensions", p_resource);
-
- {
- const String *r = exts.ptr();
- for (int i = 0; i < exts.size(); ++i) {
- p_extensions->push_back(r[i]);
- }
+ PackedStringArray exts;
+ if (GDVIRTUAL_CALL(_get_recognized_extensions, p_resource, exts)) {
+ const String *r = exts.ptr();
+ for (int i = 0; i < exts.size(); ++i) {
+ p_extensions->push_back(r[i]);
}
}
}
void ResourceFormatSaver::_bind_methods() {
- {
- PropertyInfo arg0 = PropertyInfo(Variant::STRING, "path");
- PropertyInfo arg1 = PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource");
- PropertyInfo arg2 = PropertyInfo(Variant::INT, "flags");
- BIND_VMETHOD(MethodInfo(Variant::INT, "_save", arg0, arg1, arg2));
- }
-
- BIND_VMETHOD(MethodInfo(Variant::PACKED_STRING_ARRAY, "_get_recognized_extensions", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_recognize", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
+ GDVIRTUAL_BIND(_save, "path", "resource", "flags");
+ GDVIRTUAL_BIND(_recognize, "resource");
+ GDVIRTUAL_BIND(_get_recognized_extensions, "resource");
}
Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h
index 2fc8d32126..fcde835dab 100644
--- a/core/io/resource_saver.h
+++ b/core/io/resource_saver.h
@@ -32,6 +32,8 @@
#define RESOURCE_SAVER_H
#include "core/io/resource.h"
+#include "core/object/gdvirtual.gen.inc"
+#include "core/object/script_language.h"
class ResourceFormatSaver : public RefCounted {
GDCLASS(ResourceFormatSaver, RefCounted);
@@ -39,6 +41,10 @@ class ResourceFormatSaver : public RefCounted {
protected:
static void _bind_methods();
+ GDVIRTUAL3R(int64_t, _save, String, RES, uint32_t)
+ GDVIRTUAL1RC(bool, _recognize, RES)
+ GDVIRTUAL1RC(Vector<String>, _get_recognized_extensions, RES)
+
public:
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual bool recognize(const RES &p_resource) const;
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 322eb7ac61..b380860522 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -382,8 +382,9 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
}
real_t AStar::_estimate_cost(int p_from_id, int p_to_id) {
- if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) {
- return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id);
+ real_t scost;
+ if (GDVIRTUAL_CALL(_estimate_cost, p_from_id, p_to_id, scost)) {
+ return scost;
}
Point *from_point;
@@ -398,8 +399,9 @@ real_t AStar::_estimate_cost(int p_from_id, int p_to_id) {
}
real_t AStar::_compute_cost(int p_from_id, int p_to_id) {
- if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) {
- return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id);
+ real_t scost;
+ if (GDVIRTUAL_CALL(_compute_cost, p_from_id, p_to_id, scost)) {
+ return scost;
}
Point *from_point;
@@ -557,8 +559,8 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStar::get_point_path);
ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStar::get_id_path);
- BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
- BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
+ GDVIRTUAL_BIND(_estimate_cost, "from_id", "to_id")
+ GDVIRTUAL_BIND(_compute_cost, "from_id", "to_id")
}
AStar::~AStar() {
@@ -654,8 +656,9 @@ Vector2 AStar2D::get_closest_position_in_segment(const Vector2 &p_point) const {
}
real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) {
- if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) {
- return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id);
+ real_t scost;
+ if (GDVIRTUAL_CALL(_estimate_cost, p_from_id, p_to_id, scost)) {
+ return scost;
}
AStar::Point *from_point;
@@ -670,8 +673,9 @@ real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) {
}
real_t AStar2D::_compute_cost(int p_from_id, int p_to_id) {
- if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) {
- return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id);
+ real_t scost;
+ if (GDVIRTUAL_CALL(_compute_cost, p_from_id, p_to_id, scost)) {
+ return scost;
}
AStar::Point *from_point;
@@ -875,6 +879,6 @@ void AStar2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStar2D::get_point_path);
ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStar2D::get_id_path);
- BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
- BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
+ GDVIRTUAL_BIND(_estimate_cost, "from_id", "to_id")
+ GDVIRTUAL_BIND(_compute_cost, "from_id", "to_id")
}
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 44758cb046..64fa32a325 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -31,7 +31,9 @@
#ifndef A_STAR_H
#define A_STAR_H
+#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
+#include "core/object/script_language.h"
#include "core/templates/oa_hash_map.h"
/**
@@ -122,6 +124,9 @@ protected:
virtual real_t _estimate_cost(int p_from_id, int p_to_id);
virtual real_t _compute_cost(int p_from_id, int p_to_id);
+ GDVIRTUAL2RC(real_t, _estimate_cost, int64_t, int64_t)
+ GDVIRTUAL2RC(real_t, _compute_cost, int64_t, int64_t)
+
public:
int get_available_point_id() const;
@@ -169,6 +174,9 @@ protected:
virtual real_t _estimate_cost(int p_from_id, int p_to_id);
virtual real_t _compute_cost(int p_from_id, int p_to_id);
+ GDVIRTUAL2RC(real_t, _estimate_cost, int64_t, int64_t)
+ GDVIRTUAL2RC(real_t, _compute_cost, int64_t, int64_t)
+
public:
int get_available_point_id() const;
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 66c18f7b3c..8066a59281 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -341,8 +341,8 @@ bool CameraMatrix::get_endpoints(const Transform3D &p_transform, Vector3 *p_8poi
Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform) const {
/** Fast Plane Extraction from combined modelview/projection matrices.
* References:
- * https://web.archive.org/web/20011221205252/http://www.markmorley.com/opengl/frustumculling.html
- * https://web.archive.org/web/20061020020112/http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
+ * https://web.archive.org/web/20011221205252/https://www.markmorley.com/opengl/frustumculling.html
+ * https://web.archive.org/web/20061020020112/https://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
*/
Vector<Plane> planes;
diff --git a/core/math/convex_hull.h b/core/math/convex_hull.h
index ba7be9c5e8..a860d60b02 100644
--- a/core/math/convex_hull.h
+++ b/core/math/convex_hull.h
@@ -49,7 +49,7 @@ subject to the following restrictions:
#include "core/templates/vector.h"
/// Convex hull implementation based on Preparata and Hong
-/// See http://code.google.com/p/bullet/issues/detail?id=275
+/// See https://code.google.com/p/bullet/issues/detail?id=275
/// Ole Kniemeyer, MAXON Computer GmbH
class ConvexHullComputer {
public:
diff --git a/core/math/dynamic_bvh.h b/core/math/dynamic_bvh.h
index 0b6286cd9d..d63132b4da 100644
--- a/core/math/dynamic_bvh.h
+++ b/core/math/dynamic_bvh.h
@@ -41,7 +41,7 @@
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2013 Erwin Coumans http://bulletphysics.org
+Copyright (c) 2003-2013 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h
index cadfdc13d1..345e0fade0 100644
--- a/core/math/transform_3d.h
+++ b/core/math/transform_3d.h
@@ -155,7 +155,7 @@ _FORCE_INLINE_ Plane Transform3D::xform_inv(const Plane &p_plane) const {
}
_FORCE_INLINE_ AABB Transform3D::xform(const AABB &p_aabb) const {
- /* http://dev.theomader.com/transform-bounding-boxes/ */
+ /* https://dev.theomader.com/transform-bounding-boxes/ */
Vector3 min = p_aabb.position;
Vector3 max = p_aabb.position + p_aabb.size;
Vector3 tmin, tmax;
diff --git a/core/math/triangulate.h b/core/math/triangulate.h
index 55dc4e8e7d..249ca6238f 100644
--- a/core/math/triangulate.h
+++ b/core/math/triangulate.h
@@ -34,7 +34,7 @@
#include "core/math/vector2.h"
/*
-http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
+https://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
*/
class Triangulate {
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index 75145e1b65..b29b2bd421 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -1421,7 +1421,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const c
return p_bind;
}
-void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual) {
+void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual, const Vector<String> &p_arg_names, bool p_object_core) {
ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'.");
OBJTYPE_WLOCK;
@@ -1431,6 +1431,19 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_
if (p_virtual) {
mi.flags |= METHOD_FLAG_VIRTUAL;
}
+ if (p_object_core) {
+ mi.flags |= METHOD_FLAG_OBJECT_CORE;
+ }
+ if (p_arg_names.size()) {
+ if (p_arg_names.size() != mi.arguments.size()) {
+ WARN_PRINT("Mismatch argument name count for virtual function: " + String(p_class) + "::" + p_method.name);
+ } else {
+ for (int i = 0; i < p_arg_names.size(); i++) {
+ mi.arguments[i].name = p_arg_names[i];
+ }
+ }
+ }
+
classes[p_class].virtual_methods.push_back(mi);
classes[p_class].virtual_methods_map[p_method.name] = mi;
diff --git a/core/object/class_db.h b/core/object/class_db.h
index 8add0285f7..45572517be 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -372,7 +372,7 @@ public:
static bool get_method_info(const StringName &p_class, const StringName &p_method, MethodInfo *r_info, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
static MethodBind *get_method(const StringName &p_class, const StringName &p_name);
- static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true);
+ static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true, const Vector<String> &p_arg_names = Vector<String>(), bool p_object_core = false);
static void get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false);
static void bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int p_constant);
@@ -425,17 +425,6 @@ public:
#endif
-#ifdef TOOLS_ENABLED
-
-#define BIND_VMETHOD(m_method) \
- ::ClassDB::add_virtual_method(get_class_static(), m_method);
-
-#else
-
-#define BIND_VMETHOD(m_method)
-
-#endif
-
#define GDREGISTER_CLASS(m_class) \
if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \
::ClassDB::register_class<m_class>(); \
diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py
index 9948620c73..65a421cfb2 100644
--- a/core/object/make_virtuals.py
+++ b/core/object/make_virtuals.py
@@ -1,8 +1,8 @@
proto = """
#define GDVIRTUAL$VER($RET m_name $ARG) \\
StringName _gdvirtual_##m_name##_sn = #m_name;\\
-bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
- GDNativeExtensionClassCallVirtual _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\
+GDNativeExtensionClassCallVirtual _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\
+_FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
ScriptInstance *script_instance = ((Object*)(this))->get_script_instance();\\
if (script_instance) {\\
Callable::CallError ce; \\
@@ -23,6 +23,16 @@ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
\\
return false;\\
}\\
+_FORCE_INLINE_ bool _gdvirtual_##m_name##_overriden() const { \\
+ ScriptInstance *script_instance = ((Object*)(this))->get_script_instance();\\
+ if (script_instance) {\\
+ return script_instance->has_method(_gdvirtual_##m_name##_sn);\\
+ }\\
+ if (_gdvirtual_##m_name) {\\
+ return true;\\
+ }\\
+ return false;\\
+}\\
\\
_FORCE_INLINE_ static MethodInfo _gdvirtual_##m_name##_get_method_info() { \\
MethodInfo method_info;\\
@@ -32,7 +42,6 @@ _FORCE_INLINE_ static MethodInfo _gdvirtual_##m_name##_get_method_info() { \\
return method_info;\\
}
-
"""
@@ -77,7 +86,7 @@ def generate_version(argcount, const=False, returns=False):
callptrargs += "\t\t"
callptrargsptr += ", "
argtext += "m_type" + str(i + 1)
- callargtext += "const m_type" + str(i + 1) + "& arg" + str(i + 1)
+ callargtext += "m_type" + str(i + 1) + " arg" + str(i + 1)
callsiargs += "Variant(arg" + str(i + 1) + ")"
callsiargptrs += "&vargs[" + str(i) + "]"
callptrargs += (
@@ -103,7 +112,7 @@ def generate_version(argcount, const=False, returns=False):
if returns:
if argcount > 0:
callargtext += ","
- callargtext += " m_ret& r_ret"
+ callargtext += " m_ret& r_ret"
s = s.replace("$CALLSIBEGIN", "Variant ret = ")
s = s.replace("$CALLSIRET", "r_ret = ret;")
s = s.replace("$CALLPTRRETPASS", "&ret")
diff --git a/core/object/method_bind.h b/core/object/method_bind.h
index 92b964772a..b0b379873e 100644
--- a/core/object/method_bind.h
+++ b/core/object/method_bind.h
@@ -43,6 +43,7 @@ enum MethodFlags {
METHOD_FLAG_FROM_SCRIPT = 64,
METHOD_FLAG_VARARG = 128,
METHOD_FLAG_STATIC = 256,
+ METHOD_FLAG_OBJECT_CORE = 512,
METHOD_FLAGS_DEFAULT = METHOD_FLAG_NORMAL,
};
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 2bb4b981b9..3335942fb3 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -1619,22 +1619,25 @@ void Object::_bind_methods() {
ADD_SIGNAL(MethodInfo("script_changed"));
ADD_SIGNAL(MethodInfo("property_list_changed"));
- BIND_VMETHOD(MethodInfo("_notification", PropertyInfo(Variant::INT, "what")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value")));
+#define BIND_OBJ_CORE_METHOD(m_method) \
+ ::ClassDB::add_virtual_method(get_class_static(), m_method, true, Vector<String>(), true);
+
+ BIND_OBJ_CORE_METHOD(MethodInfo("_notification", PropertyInfo(Variant::INT, "what")));
+ BIND_OBJ_CORE_METHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value")));
#ifdef TOOLS_ENABLED
MethodInfo miget("_get", PropertyInfo(Variant::STRING_NAME, "property"));
miget.return_val.name = "Variant";
miget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
- BIND_VMETHOD(miget);
+ BIND_OBJ_CORE_METHOD(miget);
MethodInfo plget("_get_property_list");
plget.return_val.type = Variant::ARRAY;
- BIND_VMETHOD(plget);
+ BIND_OBJ_CORE_METHOD(plget);
#endif
- BIND_VMETHOD(MethodInfo("_init"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_to_string"));
+ BIND_OBJ_CORE_METHOD(MethodInfo("_init"));
+ BIND_OBJ_CORE_METHOD(MethodInfo(Variant::STRING, "_to_string"));
BIND_CONSTANT(NOTIFICATION_POSTINITIALIZE);
BIND_CONSTANT(NOTIFICATION_PREDELETE);
diff --git a/core/object/object.h b/core/object/object.h
index 94531f1cd0..a53143158b 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -97,6 +97,7 @@ enum PropertyHint {
PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog
PROPERTY_HINT_INT_IS_OBJECTID,
PROPERTY_HINT_ARRAY_TYPE,
+ PROPERTY_HINT_INT_IS_POINTER,
PROPERTY_HINT_MAX,
// When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit
};
@@ -282,7 +283,14 @@ struct ObjectNativeExtension {
};
#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call(__VA_ARGS__)
-#define GDVIRTUAL_BIND(m_name) ::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info());
+#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call(__VA_ARGS__)
+#ifdef DEBUG_METHODS_ENABLED
+#define GDVIRTUAL_BIND(m_name, ...) ::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info(), true, sarray(__VA_ARGS__));
+#else
+#define GDVIRTUAL_BIND(m_name, ...)
+#endif
+#define GDVIRTUAL_IS_OVERRIDEN(m_name) _gdvirtual_##m_name##_overriden()
+#define GDVIRTUAL_IS_OVERRIDEN_PTR(m_obj, m_name) m_obj->_gdvirtual_##m_name##_overriden()
/*
the following is an incomprehensible blob of hacks and workarounds to compensate for many of the fallencies in C++. As a plus, this macro pretty much alone defines the object model.
diff --git a/core/object/ref_counted.h b/core/object/ref_counted.h
index e0af2c18bb..f2dd2aa324 100644
--- a/core/object/ref_counted.h
+++ b/core/object/ref_counted.h
@@ -274,8 +274,6 @@ struct PtrToArg<const Ref<T> &> {
}
};
-#ifdef DEBUG_METHODS_ENABLED
-
template <class T>
struct GetTypeInfo<Ref<T>> {
static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
@@ -296,6 +294,4 @@ struct GetTypeInfo<const Ref<T> &> {
}
};
-#endif // DEBUG_METHODS_ENABLED
-
#endif // REF_COUNTED_H
diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp
index 3c0e56f5a8..0ba69a8d47 100644
--- a/core/os/main_loop.cpp
+++ b/core/os/main_loop.cpp
@@ -33,11 +33,6 @@
#include "core/object/script_language.h"
void MainLoop::_bind_methods() {
- BIND_VMETHOD(MethodInfo("_initialize"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_physics_process", PropertyInfo(Variant::FLOAT, "delta")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_process", PropertyInfo(Variant::FLOAT, "delta")));
- BIND_VMETHOD(MethodInfo("_finalize"));
-
BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
@@ -50,7 +45,12 @@ void MainLoop::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_TEXT_SERVER_CHANGED);
ADD_SIGNAL(MethodInfo("on_request_permissions_result", PropertyInfo(Variant::STRING, "permission"), PropertyInfo(Variant::BOOL, "granted")));
-};
+
+ GDVIRTUAL_BIND(_initialize);
+ GDVIRTUAL_BIND(_physics_process, "delta");
+ GDVIRTUAL_BIND(_process, "delta");
+ GDVIRTUAL_BIND(_finalize);
+}
void MainLoop::set_initialize_script(const Ref<Script> &p_initialize_script) {
initialize_script = p_initialize_script;
@@ -61,30 +61,31 @@ void MainLoop::initialize() {
set_script(initialize_script);
}
- if (get_script_instance()) {
- get_script_instance()->call("_initialize");
- }
+ GDVIRTUAL_CALL(_initialize);
}
bool MainLoop::physics_process(double p_time) {
- if (get_script_instance()) {
- return get_script_instance()->call("_physics_process", p_time);
+ bool quit;
+ if (GDVIRTUAL_CALL(_physics_process, p_time, quit)) {
+ return quit;
}
return false;
}
bool MainLoop::process(double p_time) {
- if (get_script_instance()) {
- return get_script_instance()->call("_process", p_time);
+ bool quit;
+ if (GDVIRTUAL_CALL(_process, p_time, quit)) {
+ return quit;
}
return false;
}
void MainLoop::finalize() {
+ GDVIRTUAL_CALL(_finalize);
+
if (get_script_instance()) {
- get_script_instance()->call("_finalize");
set_script(Variant()); //clear script
}
}
diff --git a/core/os/main_loop.h b/core/os/main_loop.h
index b42e9b18ff..4da01d767e 100644
--- a/core/os/main_loop.h
+++ b/core/os/main_loop.h
@@ -32,6 +32,7 @@
#define MAIN_LOOP_H
#include "core/input/input_event.h"
+#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
#include "core/object/script_language.h"
@@ -44,6 +45,11 @@ class MainLoop : public Object {
protected:
static void _bind_methods();
+ GDVIRTUAL0(_initialize)
+ GDVIRTUAL1R(bool, _physics_process, double)
+ GDVIRTUAL1R(bool, _process, double)
+ GDVIRTUAL0(_finalize)
+
public:
enum {
//make sure these are replicated in Node
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index e2a097f883..35f4532abb 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -41,6 +41,7 @@
#include "core/extension/native_extension_manager.h"
#include "core/input/input.h"
#include "core/input/input_map.h"
+#include "core/input/shortcut.h"
#include "core/io/config_file.h"
#include "core/io/dtls_server.h"
#include "core/io/http_client.h"
@@ -145,10 +146,12 @@ void register_core_types() {
GDREGISTER_CLASS(Resource);
GDREGISTER_CLASS(Image);
+ GDREGISTER_CLASS(Shortcut);
GDREGISTER_VIRTUAL_CLASS(InputEvent);
GDREGISTER_VIRTUAL_CLASS(InputEventWithModifiers);
GDREGISTER_VIRTUAL_CLASS(InputEventFromWindow);
GDREGISTER_CLASS(InputEventKey);
+ GDREGISTER_CLASS(InputEventShortcut);
GDREGISTER_VIRTUAL_CLASS(InputEventMouse);
GDREGISTER_CLASS(InputEventMouseButton);
GDREGISTER_CLASS(InputEventMouseMotion);
diff --git a/core/templates/map.h b/core/templates/map.h
index a47547d355..badb407e5d 100644
--- a/core/templates/map.h
+++ b/core/templates/map.h
@@ -36,7 +36,7 @@
#include "core/templates/pair.h"
// based on the very nice implementation of rb-trees by:
-// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
+// https://web.archive.org/web/20120507164830/https://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
template <class K, class V, class C = Comparator<K>, class A = DefaultAllocator>
class Map {
diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h
index 8d139551ef..e947d2211c 100644
--- a/core/templates/rid_owner.h
+++ b/core/templates/rid_owner.h
@@ -53,14 +53,16 @@ protected:
return rid;
}
- static uint64_t _gen_id() {
- return base_id.increment();
- }
-
static RID _gen_rid() {
return _make_from_id(_gen_id());
}
+ friend struct VariantUtilityFunctions;
+
+ static uint64_t _gen_id() {
+ return base_id.increment();
+ }
+
public:
virtual ~RID_AllocBase() {}
};
diff --git a/core/templates/set.h b/core/templates/set.h
index 9261d2d3d2..0a80ceefb5 100644
--- a/core/templates/set.h
+++ b/core/templates/set.h
@@ -35,7 +35,7 @@
#include "core/typedefs.h"
// based on the very nice implementation of rb-trees by:
-// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
+// https://web.archive.org/web/20120507164830/https://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
template <class T, class C = Comparator<T>, class A = DefaultAllocator>
class Set {
diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h
index 8836e257a9..98304621f2 100644
--- a/core/variant/method_ptrcall.h
+++ b/core/variant/method_ptrcall.h
@@ -191,6 +191,7 @@ struct PtrToArg<ObjectID> {
// This is for the special cases used by Variant.
+// No EncodeT because direct pointer conversion not possible.
#define MAKE_VECARG(m_type) \
template <> \
struct PtrToArg<Vector<m_type>> { \
@@ -236,6 +237,7 @@ struct PtrToArg<ObjectID> {
} \
}
+// No EncodeT because direct pointer conversion not possible.
#define MAKE_VECARG_ALT(m_type, m_type_alt) \
template <> \
struct PtrToArg<Vector<m_type_alt>> { \
@@ -285,6 +287,7 @@ MAKE_VECARG_ALT(String, StringName);
// For stuff that gets converted to Array vectors.
+// No EncodeT because direct pointer conversion not possible.
#define MAKE_VECARR(m_type) \
template <> \
struct PtrToArg<Vector<m_type>> { \
@@ -325,6 +328,7 @@ MAKE_VECARR(Variant);
MAKE_VECARR(RID);
MAKE_VECARR(Plane);
+// No EncodeT because direct pointer conversion not possible.
#define MAKE_DVECARR(m_type) \
template <> \
struct PtrToArg<Vector<m_type>> { \
@@ -372,6 +376,7 @@ MAKE_VECARR(Plane);
// Special case for IPAddress.
+// No EncodeT because direct pointer conversion not possible.
#define MAKE_STRINGCONV_BY_REFERENCE(m_type) \
template <> \
struct PtrToArg<m_type> { \
@@ -395,6 +400,7 @@ MAKE_VECARR(Plane);
MAKE_STRINGCONV_BY_REFERENCE(IPAddress);
+// No EncodeT because direct pointer conversion not possible.
template <>
struct PtrToArg<Vector<Face3>> {
_FORCE_INLINE_ static Vector<Face3> convert(const void *p_ptr) {
@@ -429,6 +435,7 @@ struct PtrToArg<Vector<Face3>> {
}
};
+// No EncodeT because direct pointer conversion not possible.
template <>
struct PtrToArg<const Vector<Face3> &> {
_FORCE_INLINE_ static Vector<Face3> convert(const void *p_ptr) {
diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h
new file mode 100644
index 0000000000..b4ec0df7d6
--- /dev/null
+++ b/core/variant/native_ptr.h
@@ -0,0 +1,130 @@
+/*************************************************************************/
+/* native_ptr.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef NATIVE_PTR_H
+#define NATIVE_PTR_H
+
+#include "core/math/audio_frame.h"
+#include "core/variant/method_ptrcall.h"
+#include "core/variant/type_info.h"
+
+template <class T>
+struct GDNativeConstPtr {
+ const T *data = nullptr;
+ GDNativeConstPtr(const T *p_assign) { data = p_assign; }
+ static const char *get_name() { return "const void"; }
+ operator const T *() const { return data; }
+ operator Variant() const { return uint64_t(data); }
+};
+
+template <class T>
+struct GDNativePtr {
+ T *data = nullptr;
+ GDNativePtr(T *p_assign) { data = p_assign; }
+ static const char *get_name() { return "void"; }
+ operator T *() const { return data; }
+ operator Variant() const { return uint64_t(data); }
+};
+
+#define GDVIRTUAL_NATIVE_PTR(m_type) \
+ template <> \
+ struct GDNativeConstPtr<m_type> { \
+ const m_type *data = nullptr; \
+ GDNativeConstPtr(const m_type *p_assign) { data = p_assign; } \
+ static const char *get_name() { return "const " #m_type; } \
+ operator const m_type *() const { return data; } \
+ operator Variant() const { return uint64_t(data); } \
+ }; \
+ template <> \
+ struct GDNativePtr<m_type> { \
+ m_type *data = nullptr; \
+ GDNativePtr(m_type *p_assign) { data = p_assign; } \
+ static const char *get_name() { return #m_type; } \
+ operator m_type *() const { return data; } \
+ operator Variant() const { return uint64_t(data); } \
+ };
+
+template <class T>
+struct GetTypeInfo<GDNativeConstPtr<T>> {
+ static const Variant::Type VARIANT_TYPE = Variant::NIL;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
+ static inline PropertyInfo get_class_info() {
+ return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_INT_IS_POINTER, GDNativeConstPtr<T>::get_name());
+ }
+};
+
+template <class T>
+struct GetTypeInfo<GDNativePtr<T>> {
+ static const Variant::Type VARIANT_TYPE = Variant::NIL;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
+ static inline PropertyInfo get_class_info() {
+ return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_INT_IS_POINTER, GDNativePtr<T>::get_name());
+ }
+};
+
+template <class T>
+struct PtrToArg<GDNativeConstPtr<T>> {
+ _FORCE_INLINE_ static GDNativeConstPtr<T> convert(const void *p_ptr) {
+ return GDNativeConstPtr<T>(reinterpret_cast<const T *>(p_ptr));
+ }
+ typedef const T *EncodeT;
+ _FORCE_INLINE_ static void encode(GDNativeConstPtr<T> p_val, void *p_ptr) {
+ *((const T **)p_ptr) = p_val.data;
+ }
+};
+template <class T>
+struct PtrToArg<GDNativePtr<T>> {
+ _FORCE_INLINE_ static GDNativePtr<T> convert(const void *p_ptr) {
+ return GDNativePtr<T>(reinterpret_cast<const T *>(p_ptr));
+ }
+ typedef T *EncodeT;
+ _FORCE_INLINE_ static void encode(GDNativePtr<T> p_val, void *p_ptr) {
+ *((T **)p_ptr) = p_val.data;
+ }
+};
+
+GDVIRTUAL_NATIVE_PTR(AudioFrame)
+GDVIRTUAL_NATIVE_PTR(bool)
+GDVIRTUAL_NATIVE_PTR(char)
+GDVIRTUAL_NATIVE_PTR(char16_t)
+GDVIRTUAL_NATIVE_PTR(char32_t)
+GDVIRTUAL_NATIVE_PTR(wchar_t)
+GDVIRTUAL_NATIVE_PTR(uint8_t)
+GDVIRTUAL_NATIVE_PTR(int8_t)
+GDVIRTUAL_NATIVE_PTR(uint16_t)
+GDVIRTUAL_NATIVE_PTR(int16_t)
+GDVIRTUAL_NATIVE_PTR(uint32_t)
+GDVIRTUAL_NATIVE_PTR(int32_t)
+GDVIRTUAL_NATIVE_PTR(int64_t)
+GDVIRTUAL_NATIVE_PTR(uint64_t)
+GDVIRTUAL_NATIVE_PTR(float)
+GDVIRTUAL_NATIVE_PTR(double)
+
+#endif // NATIVE_PTR_H
diff --git a/core/variant/typed_array.h b/core/variant/typed_array.h
index 900dcf7689..2e96f4e445 100644
--- a/core/variant/typed_array.h
+++ b/core/variant/typed_array.h
@@ -125,7 +125,7 @@ struct PtrToArg<TypedArray<T>> {
_FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) {
return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr));
}
-
+ typedef Array EncodeT;
_FORCE_INLINE_ static void encode(TypedArray<T> p_val, void *p_ptr) {
*(Array *)p_ptr = p_val;
}
@@ -133,13 +133,13 @@ struct PtrToArg<TypedArray<T>> {
template <class T>
struct PtrToArg<const TypedArray<T> &> {
- _FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) {
+ typedef Array EncodeT;
+ _FORCE_INLINE_ static TypedArray<T>
+ convert(const void *p_ptr) {
return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr));
}
};
-#ifdef DEBUG_METHODS_ENABLED
-
template <class T>
struct GetTypeInfo<TypedArray<T>> {
static const Variant::Type VARIANT_TYPE = Variant::ARRAY;
@@ -218,6 +218,4 @@ MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
-#endif
-
#endif // TYPED_ARRAY_H
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index c3481d4896..a4817eb7d2 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1422,6 +1422,7 @@ static void _register_variant_builtin_methods() {
bind_method(String, is_absolute_path, sarray(), varray());
bind_method(String, is_rel_path, sarray(), varray());
+ bind_method(String, simplify_path, sarray(), varray());
bind_method(String, get_base_dir, sarray(), varray());
bind_method(String, get_file, sarray(), varray());
bind_method(String, xml_escape, sarray("escape_quotes"), varray(false));
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index 6c57d1de10..f5cb2d40d6 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -35,6 +35,8 @@
#include "core/object/ref_counted.h"
#include "core/os/os.h"
#include "core/templates/oa_hash_map.h"
+#include "core/templates/rid.h"
+#include "core/templates/rid_owner.h"
#include "core/variant/binder_common.h"
#include "core/variant/variant_parser.h"
@@ -728,6 +730,13 @@ struct VariantUtilityFunctions {
}
return p_instance.get_validated_object() != nullptr;
}
+
+ static inline uint64_t rid_allocate_id() {
+ return RID_AllocBase::_gen_id();
+ }
+ static inline RID rid_from_int64(uint64_t p_base) {
+ return RID::from_uint64(p_base);
+ }
};
#ifdef DEBUG_METHODS_ENABLED
@@ -1265,6 +1274,9 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(instance_from_id, sarray("instance_id"), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDR(is_instance_id_valid, sarray("id"), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDR(is_instance_valid, sarray("instance"), Variant::UTILITY_FUNC_TYPE_GENERAL);
+
+ FUNCBINDR(rid_allocate_id, Vector<String>(), Variant::UTILITY_FUNC_TYPE_GENERAL);
+ FUNCBINDR(rid_from_int64, sarray("base"), Variant::UTILITY_FUNC_TYPE_GENERAL);
}
void Variant::_unregister_variant_utility_functions() {