Replace BIND_VMETHOD by new GDVIRTUAL syntax

* New syntax is type safe.
* New syntax allows for type safe virtuals in native extensions.
* New syntax permits extremely fast calling.

Note: Everything was replaced where possible except for `_gui_input` `_input` and `_unhandled_input`.
These will require API rework on a separate PR as they work different than the rest of the functions.

Added a new method flag METHOD_FLAG_OBJECT_CORE, used internally. Allows to not dump the core virtuals like `_notification` to the json API, since each language will implement those as it is best fits.
This commit is contained in:
reduz 2021-08-21 22:52:44 -03:00
parent 2a5c64f2a1
commit 3682978aee
104 changed files with 1389 additions and 1227 deletions

View file

@ -2825,36 +2825,41 @@ VisualScriptSelf::VisualScriptSelf() {
//////////////////////////////////////////
int VisualScriptCustomNode::get_output_sequence_port_count() const {
if (get_script_instance() && get_script_instance()->has_method("_get_output_sequence_port_count")) {
return get_script_instance()->call("_get_output_sequence_port_count");
int ret;
if (GDVIRTUAL_CALL(_get_output_sequence_port_count, ret)) {
return ret;
}
return 0;
}
bool VisualScriptCustomNode::has_input_sequence_port() const {
if (get_script_instance() && get_script_instance()->has_method("_has_input_sequence_port")) {
return get_script_instance()->call("_has_input_sequence_port");
bool ret;
if (GDVIRTUAL_CALL(_has_input_sequence_port, ret)) {
return ret;
}
return false;
}
int VisualScriptCustomNode::get_input_value_port_count() const {
if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_count")) {
return get_script_instance()->call("_get_input_value_port_count");
int ret;
if (GDVIRTUAL_CALL(_get_input_value_port_count, ret)) {
return ret;
}
return 0;
}
int VisualScriptCustomNode::get_output_value_port_count() const {
if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_count")) {
return get_script_instance()->call("_get_output_value_port_count");
int ret;
if (GDVIRTUAL_CALL(_get_output_value_port_count, ret)) {
return ret;
}
return 0;
}
String VisualScriptCustomNode::get_output_sequence_port_text(int p_port) const {
if (get_script_instance() && get_script_instance()->has_method("_get_output_sequence_port_text")) {
return get_script_instance()->call("_get_output_sequence_port_text", p_port);
String ret;
if (GDVIRTUAL_CALL(_get_output_sequence_port_text, p_port, ret)) {
return ret;
}
return String();
@ -2862,34 +2867,61 @@ String VisualScriptCustomNode::get_output_sequence_port_text(int p_port) const {
PropertyInfo VisualScriptCustomNode::get_input_value_port_info(int p_idx) const {
PropertyInfo info;
if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_type")) {
info.type = Variant::Type(int(get_script_instance()->call("_get_input_value_port_type", p_idx)));
{
int type;
if (GDVIRTUAL_CALL(_get_input_value_port_type, p_idx, type)) {
info.type = Variant::Type(type);
}
}
if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_name")) {
info.name = get_script_instance()->call("_get_input_value_port_name", p_idx);
{
String name;
if (GDVIRTUAL_CALL(_get_input_value_port_name, p_idx, name)) {
info.name = name;
}
}
if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_hint")) {
info.hint = PropertyHint(int(get_script_instance()->call("_get_input_value_port_hint", p_idx)));
{
int hint;
if (GDVIRTUAL_CALL(_get_input_value_port_hint, p_idx, hint)) {
info.hint = PropertyHint(hint);
}
}
if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_hint_string")) {
info.hint_string = get_script_instance()->call("_get_input_value_port_hint_string", p_idx);
{
String hint_string;
if (GDVIRTUAL_CALL(_get_input_value_port_hint_string, p_idx, hint_string)) {
info.hint_string = hint_string;
}
}
return info;
}
PropertyInfo VisualScriptCustomNode::get_output_value_port_info(int p_idx) const {
PropertyInfo info;
if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_type")) {
info.type = Variant::Type(int(get_script_instance()->call("_get_output_value_port_type", p_idx)));
{
int type;
if (GDVIRTUAL_CALL(_get_output_value_port_type, p_idx, type)) {
info.type = Variant::Type(type);
}
}
if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_name")) {
info.name = get_script_instance()->call("_get_output_value_port_name", p_idx);
{
String name;
if (GDVIRTUAL_CALL(_get_output_value_port_name, p_idx, name)) {
info.name = name;
}
}
if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_hint")) {
info.hint = PropertyHint(int(get_script_instance()->call("_get_output_value_port_hint", p_idx)));
{
int hint;
if (GDVIRTUAL_CALL(_get_output_value_port_hint, p_idx, hint)) {
info.hint = PropertyHint(hint);
}
}
if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_hint_string")) {
info.hint_string = get_script_instance()->call("_get_output_value_port_hint_string", p_idx);
{
String hint_string;
if (GDVIRTUAL_CALL(_get_output_value_port_hint_string, p_idx, hint_string)) {
info.hint_string = hint_string;
}
}
return info;
}
@ -2911,22 +2943,25 @@ VisualScriptCustomNode::TypeGuess VisualScriptCustomNode::guess_output_type(Type
}
String VisualScriptCustomNode::get_caption() const {
if (get_script_instance() && get_script_instance()->has_method("_get_caption")) {
return get_script_instance()->call("_get_caption");
String ret;
if (GDVIRTUAL_CALL(_get_caption, ret)) {
return ret;
}
return "CustomNode";
}
String VisualScriptCustomNode::get_text() const {
if (get_script_instance() && get_script_instance()->has_method("_get_text")) {
return get_script_instance()->call("_get_text");
String ret;
if (GDVIRTUAL_CALL(_get_text, ret)) {
return ret;
}
return "";
}
String VisualScriptCustomNode::get_category() const {
if (get_script_instance() && get_script_instance()->has_method("_get_category")) {
return get_script_instance()->call("_get_category");
String ret;
if (GDVIRTUAL_CALL(_get_category, ret)) {
return ret;
}
return "Custom";
}
@ -2941,14 +2976,7 @@ public:
virtual int get_working_memory_size() const { return work_mem_size; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (node->get_script_instance()) {
#ifdef DEBUG_ENABLED
if (!node->get_script_instance()->has_method(VisualScriptLanguage::singleton->_step)) {
r_error_str = RTR("Custom node has no _step() method, can't process graph.");
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return 0;
}
#endif
if (GDVIRTUAL_IS_OVERRIDEN_PTR(node, _step)) {
Array in_values;
Array out_values;
Array work_mem;
@ -2969,7 +2997,8 @@ public:
int ret_out;
Variant ret = node->get_script_instance()->call(VisualScriptLanguage::singleton->_step, in_values, out_values, p_start_mode, work_mem);
Variant ret;
GDVIRTUAL_CALL_PTR(node, _step, in_values, out_values, p_start_mode, work_mem, ret);
if (ret.get_type() == Variant::STRING) {
r_error_str = ret;
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@ -2995,6 +3024,9 @@ public:
}
return ret_out;
} else {
r_error_str = RTR("Custom node has no _step() method, can't process graph.");
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
}
return 0;
@ -3008,11 +3040,8 @@ VisualScriptNodeInstance *VisualScriptCustomNode::instantiate(VisualScriptInstan
instance->in_count = get_input_value_port_count();
instance->out_count = get_output_value_port_count();
if (get_script_instance() && get_script_instance()->has_method("_get_working_memory_size")) {
instance->work_mem_size = get_script_instance()->call("_get_working_memory_size");
} else {
instance->work_mem_size = 0;
}
instance->work_mem_size = 0;
GDVIRTUAL_CALL(_get_working_memory_size, instance->work_mem_size);
return instance;
}
@ -3022,32 +3051,29 @@ void VisualScriptCustomNode::_script_changed() {
}
void VisualScriptCustomNode::_bind_methods() {
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_sequence_port_count"));
BIND_VMETHOD(MethodInfo(Variant::BOOL, "_has_input_sequence_port"));
GDVIRTUAL_BIND(_get_output_sequence_port_count);
GDVIRTUAL_BIND(_has_input_sequence_port);
GDVIRTUAL_BIND(_get_output_sequence_port_text, "seq_idx");
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_sequence_port_text", PropertyInfo(Variant::INT, "idx")));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_value_port_count"));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_value_port_count"));
GDVIRTUAL_BIND(_get_input_value_port_count);
GDVIRTUAL_BIND(_get_input_value_port_type, "input_idx");
GDVIRTUAL_BIND(_get_input_value_port_name, "input_idx");
GDVIRTUAL_BIND(_get_input_value_port_hint, "input_idx");
GDVIRTUAL_BIND(_get_input_value_port_hint_string, "input_idx");
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_value_port_type", PropertyInfo(Variant::INT, "idx")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_input_value_port_name", PropertyInfo(Variant::INT, "idx")));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_value_port_hint", PropertyInfo(Variant::INT, "idx")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_input_value_port_hint_string", PropertyInfo(Variant::INT, "idx")));
GDVIRTUAL_BIND(_get_output_value_port_count);
GDVIRTUAL_BIND(_get_output_value_port_type, "output_idx");
GDVIRTUAL_BIND(_get_output_value_port_name, "output_idx");
GDVIRTUAL_BIND(_get_output_value_port_hint, "output_idx");
GDVIRTUAL_BIND(_get_output_value_port_hint_string, "output_idx");
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_value_port_type", PropertyInfo(Variant::INT, "idx")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_value_port_name", PropertyInfo(Variant::INT, "idx")));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_value_port_hint", PropertyInfo(Variant::INT, "idx")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_value_port_hint_string", PropertyInfo(Variant::INT, "idx")));
GDVIRTUAL_BIND(_get_caption);
GDVIRTUAL_BIND(_get_text);
GDVIRTUAL_BIND(_get_category);
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_caption"));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_text"));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category"));
GDVIRTUAL_BIND(_get_working_memory_size);
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_working_memory_size"));
MethodInfo stepmi(Variant::NIL, "_step", PropertyInfo(Variant::ARRAY, "inputs"), PropertyInfo(Variant::ARRAY, "outputs"), PropertyInfo(Variant::INT, "start_mode"), PropertyInfo(Variant::ARRAY, "working_mem"));
stepmi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
BIND_VMETHOD(stepmi);
GDVIRTUAL_BIND(_step, "inputs", "outputs", "start_mode", "working_mem");
BIND_ENUM_CONSTANT(START_MODE_BEGIN_SEQUENCE);
BIND_ENUM_CONSTANT(START_MODE_CONTINUE_SEQUENCE);
@ -3170,9 +3196,7 @@ VisualScriptNodeInstance *VisualScriptSubCall::instantiate(VisualScriptInstance
}
void VisualScriptSubCall::_bind_methods() {
MethodInfo scmi(Variant::NIL, "_subcall", PropertyInfo(Variant::NIL, "arguments"));
scmi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
BIND_VMETHOD(scmi);
// Since this is script only, registering virtual function is no longer valid. Will have to go in docs.
}
VisualScriptSubCall::VisualScriptSubCall() {