[Net] Refactor RPCs, remove RSETs

In this PR:
- Removed rset
- rpc_config can now optionally configure transfer mode
  (reliable/unreliable/ordered) and channel (channels are not actually
  implemented yet.)
- Refactor how the RPC id is computed to minimize the logic in Node and
  scripts that now only needs a single `get_rpc_methods` function.
This commit is contained in:
Fabio Alessandrelli
2021-05-26 14:07:57 +02:00
parent 0aabfb341a
commit d779b5aa3e
23 changed files with 251 additions and 1545 deletions

View File

@@ -70,8 +70,7 @@ void GDAPI godot_nativescript_register_class(void *p_gdnative_handle, const char
const NativeScriptDesc *b = desc.base_data;
while (b) {
desc.rpc_count += b->rpc_count;
desc.rset_count += b->rset_count;
desc.rpc_methods.append_array(b->rpc_methods);
b = b->base_data;
}
@@ -94,8 +93,6 @@ void GDAPI godot_nativescript_register_tool_class(void *p_gdnative_handle, const
desc.destroy_func = p_destroy_func;
desc.is_tool = true;
desc.base = p_base;
desc.rpc_count = 0;
desc.rset_count = 0;
if (classes->has(p_base)) {
desc.base_data = &(*classes)[p_base];
@@ -103,8 +100,7 @@ void GDAPI godot_nativescript_register_tool_class(void *p_gdnative_handle, const
const NativeScriptDesc *b = desc.base_data;
while (b) {
desc.rpc_count += b->rpc_count;
desc.rset_count += b->rset_count;
desc.rpc_methods.append_array(b->rpc_methods);
b = b->base_data;
}
@@ -126,13 +122,16 @@ void GDAPI godot_nativescript_register_method(void *p_gdnative_handle, const cha
method.method = p_method;
method.rpc_mode = p_attr.rpc_type;
method.rpc_method_id = UINT16_MAX;
if (p_attr.rpc_type != GODOT_METHOD_RPC_MODE_DISABLED) {
method.rpc_method_id = E->get().rpc_count;
E->get().rpc_count += 1;
}
method.info = MethodInfo(p_function_name);
E->get().methods.insert(p_function_name, method);
if (p_attr.rpc_type != GODOT_METHOD_RPC_MODE_DISABLED) {
MultiplayerAPI::RPCConfig nd;
nd.name = String(p_name);
nd.rpc_mode = MultiplayerAPI::RPCMode(p_attr.rpc_type);
E->get().rpc_methods.push_back(nd);
}
}
void GDAPI godot_nativescript_register_property(void *p_gdnative_handle, const char *p_name, const char *p_path, godot_nativescript_property_attributes *p_attr, godot_nativescript_property_set_func p_set_func, godot_nativescript_property_get_func p_get_func) {
@@ -144,11 +143,6 @@ void GDAPI godot_nativescript_register_property(void *p_gdnative_handle, const c
NativeScriptDesc::Property property;
property.default_value = *(Variant *)&p_attr->default_value;
property.getter = p_get_func;
property.rset_mode = p_attr->rset_type;
if (p_attr->rset_type != GODOT_METHOD_RPC_MODE_DISABLED) {
property.rset_property_id = E->get().rset_count;
E->get().rset_count += 1;
}
property.setter = p_set_func;
property.info = PropertyInfo((Variant::Type)p_attr->type,
p_path,

View File

@@ -415,245 +415,11 @@ void NativeScript::get_script_property_list(List<PropertyInfo> *p_list) const {
}
}
Vector<ScriptNetData> NativeScript::get_rpc_methods() const {
Vector<ScriptNetData> v;
const Vector<MultiplayerAPI::RPCConfig> NativeScript::get_rpc_methods() const {
NativeScriptDesc *script_data = get_script_desc();
ERR_FAIL_COND_V(!script_data, Vector<MultiplayerAPI::RPCConfig>());
while (script_data) {
for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
if (E->get().rpc_mode != GODOT_METHOD_RPC_MODE_DISABLED) {
ScriptNetData nd;
nd.name = E->key();
nd.mode = MultiplayerAPI::RPCMode(E->get().rpc_mode);
v.push_back(nd);
}
}
script_data = script_data->base_data;
}
return v;
}
uint16_t NativeScript::get_rpc_method_id(const StringName &p_method) const {
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method);
if (E) {
return E->get().rpc_method_id;
}
script_data = script_data->base_data;
}
return UINT16_MAX;
}
StringName NativeScript::get_rpc_method(uint16_t p_id) const {
ERR_FAIL_COND_V(p_id == UINT16_MAX, StringName());
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
if (E->get().rpc_method_id == p_id) {
return E->key();
}
}
script_data = script_data->base_data;
}
return StringName();
}
MultiplayerAPI::RPCMode NativeScript::get_rpc_mode_by_id(uint16_t p_id) const {
ERR_FAIL_COND_V(p_id == UINT16_MAX, MultiplayerAPI::RPC_MODE_DISABLED);
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
if (E->get().rpc_method_id == p_id) {
switch (E->get().rpc_mode) {
case GODOT_METHOD_RPC_MODE_DISABLED:
return MultiplayerAPI::RPC_MODE_DISABLED;
case GODOT_METHOD_RPC_MODE_REMOTE:
return MultiplayerAPI::RPC_MODE_REMOTE;
case GODOT_METHOD_RPC_MODE_MASTER:
return MultiplayerAPI::RPC_MODE_MASTER;
case GODOT_METHOD_RPC_MODE_PUPPET:
return MultiplayerAPI::RPC_MODE_PUPPET;
case GODOT_METHOD_RPC_MODE_REMOTESYNC:
return MultiplayerAPI::RPC_MODE_REMOTESYNC;
case GODOT_METHOD_RPC_MODE_MASTERSYNC:
return MultiplayerAPI::RPC_MODE_MASTERSYNC;
case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
default:
return MultiplayerAPI::RPC_MODE_DISABLED;
}
}
}
script_data = script_data->base_data;
}
return MultiplayerAPI::RPC_MODE_DISABLED;
}
MultiplayerAPI::RPCMode NativeScript::get_rpc_mode(const StringName &p_method) const {
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method);
if (E) {
switch (E->get().rpc_mode) {
case GODOT_METHOD_RPC_MODE_DISABLED:
return MultiplayerAPI::RPC_MODE_DISABLED;
case GODOT_METHOD_RPC_MODE_REMOTE:
return MultiplayerAPI::RPC_MODE_REMOTE;
case GODOT_METHOD_RPC_MODE_MASTER:
return MultiplayerAPI::RPC_MODE_MASTER;
case GODOT_METHOD_RPC_MODE_PUPPET:
return MultiplayerAPI::RPC_MODE_PUPPET;
case GODOT_METHOD_RPC_MODE_REMOTESYNC:
return MultiplayerAPI::RPC_MODE_REMOTESYNC;
case GODOT_METHOD_RPC_MODE_MASTERSYNC:
return MultiplayerAPI::RPC_MODE_MASTERSYNC;
case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
default:
return MultiplayerAPI::RPC_MODE_DISABLED;
}
}
script_data = script_data->base_data;
}
return MultiplayerAPI::RPC_MODE_DISABLED;
}
Vector<ScriptNetData> NativeScript::get_rset_properties() const {
Vector<ScriptNetData> v;
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
if (E.get().rset_mode != GODOT_METHOD_RPC_MODE_DISABLED) {
ScriptNetData nd;
nd.name = E.key();
nd.mode = MultiplayerAPI::RPCMode(E.get().rset_mode);
v.push_back(nd);
}
}
script_data = script_data->base_data;
}
return v;
}
uint16_t NativeScript::get_rset_property_id(const StringName &p_variable) const {
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable);
if (E) {
return E.get().rset_property_id;
}
script_data = script_data->base_data;
}
return UINT16_MAX;
}
StringName NativeScript::get_rset_property(uint16_t p_id) const {
ERR_FAIL_COND_V(p_id == UINT16_MAX, StringName());
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
if (E.get().rset_property_id == p_id) {
return E.key();
}
}
script_data = script_data->base_data;
}
return StringName();
}
MultiplayerAPI::RPCMode NativeScript::get_rset_mode_by_id(uint16_t p_id) const {
ERR_FAIL_COND_V(p_id == UINT16_MAX, MultiplayerAPI::RPC_MODE_DISABLED);
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
if (E.get().rset_property_id == p_id) {
switch (E.get().rset_mode) {
case GODOT_METHOD_RPC_MODE_DISABLED:
return MultiplayerAPI::RPC_MODE_DISABLED;
case GODOT_METHOD_RPC_MODE_REMOTE:
return MultiplayerAPI::RPC_MODE_REMOTE;
case GODOT_METHOD_RPC_MODE_MASTER:
return MultiplayerAPI::RPC_MODE_MASTER;
case GODOT_METHOD_RPC_MODE_PUPPET:
return MultiplayerAPI::RPC_MODE_PUPPET;
case GODOT_METHOD_RPC_MODE_REMOTESYNC:
return MultiplayerAPI::RPC_MODE_REMOTESYNC;
case GODOT_METHOD_RPC_MODE_MASTERSYNC:
return MultiplayerAPI::RPC_MODE_MASTERSYNC;
case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
default:
return MultiplayerAPI::RPC_MODE_DISABLED;
}
}
}
script_data = script_data->base_data;
}
return MultiplayerAPI::RPC_MODE_DISABLED;
}
MultiplayerAPI::RPCMode NativeScript::get_rset_mode(const StringName &p_variable) const {
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable);
if (E) {
switch (E.get().rset_mode) {
case GODOT_METHOD_RPC_MODE_DISABLED:
return MultiplayerAPI::RPC_MODE_DISABLED;
case GODOT_METHOD_RPC_MODE_REMOTE:
return MultiplayerAPI::RPC_MODE_REMOTE;
case GODOT_METHOD_RPC_MODE_MASTER:
return MultiplayerAPI::RPC_MODE_MASTER;
case GODOT_METHOD_RPC_MODE_PUPPET:
return MultiplayerAPI::RPC_MODE_PUPPET;
case GODOT_METHOD_RPC_MODE_REMOTESYNC:
return MultiplayerAPI::RPC_MODE_REMOTESYNC;
case GODOT_METHOD_RPC_MODE_MASTERSYNC:
return MultiplayerAPI::RPC_MODE_MASTERSYNC;
case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
default:
return MultiplayerAPI::RPC_MODE_DISABLED;
}
}
script_data = script_data->base_data;
}
return MultiplayerAPI::RPC_MODE_DISABLED;
return script_data->rpc_methods;
}
String NativeScript::get_class_documentation() const {
@@ -1046,46 +812,10 @@ Ref<Script> NativeScriptInstance::get_script() const {
return script;
}
Vector<ScriptNetData> NativeScriptInstance::get_rpc_methods() const {
const Vector<MultiplayerAPI::RPCConfig> NativeScriptInstance::get_rpc_methods() const {
return script->get_rpc_methods();
}
uint16_t NativeScriptInstance::get_rpc_method_id(const StringName &p_method) const {
return script->get_rpc_method_id(p_method);
}
StringName NativeScriptInstance::get_rpc_method(uint16_t p_id) const {
return script->get_rpc_method(p_id);
}
MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode_by_id(uint16_t p_id) const {
return script->get_rpc_mode_by_id(p_id);
}
MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const {
return script->get_rpc_mode(p_method);
}
Vector<ScriptNetData> NativeScriptInstance::get_rset_properties() const {
return script->get_rset_properties();
}
uint16_t NativeScriptInstance::get_rset_property_id(const StringName &p_variable) const {
return script->get_rset_property_id(p_variable);
}
StringName NativeScriptInstance::get_rset_property(uint16_t p_id) const {
return script->get_rset_property(p_id);
}
MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode_by_id(uint16_t p_id) const {
return script->get_rset_mode_by_id(p_id);
}
MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const {
return script->get_rset_mode(p_variable);
}
ScriptLanguage *NativeScriptInstance::get_language() {
return NativeScriptLanguage::get_singleton();
}

View File

@@ -62,8 +62,6 @@ struct NativeScriptDesc {
godot_nativescript_property_get_func getter;
PropertyInfo info;
Variant default_value;
int rset_mode = 0;
uint16_t rset_property_id;
String documentation;
};
@@ -72,9 +70,8 @@ struct NativeScriptDesc {
String documentation;
};
uint16_t rpc_count = 0;
Map<StringName, Method> methods;
uint16_t rset_count = 0;
Vector<MultiplayerAPI::RPCConfig> rpc_methods;
OrderedHashMap<StringName, Property> properties;
Map<StringName, Signal> signals_; // QtCreator doesn't like the name signals
StringName base;
@@ -178,17 +175,7 @@ public:
virtual void get_script_method_list(List<MethodInfo> *p_list) const override;
virtual void get_script_property_list(List<PropertyInfo> *p_list) const override;
virtual Vector<ScriptNetData> get_rpc_methods() const override;
virtual uint16_t get_rpc_method_id(const StringName &p_method) const override;
virtual StringName get_rpc_method(uint16_t p_id) const override;
virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const override;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override;
virtual Vector<ScriptNetData> get_rset_properties() const override;
virtual uint16_t get_rset_property_id(const StringName &p_variable) const override;
virtual StringName get_rset_property(uint16_t p_id) const override;
virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const override;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override;
virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const override;
String get_class_documentation() const;
String get_method_documentation(const StringName &p_method) const;
@@ -226,17 +213,7 @@ public:
String to_string(bool *r_valid);
virtual Ref<Script> get_script() const;
virtual Vector<ScriptNetData> get_rpc_methods() const;
virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
virtual StringName get_rpc_method(uint16_t p_id) const;
virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
virtual Vector<ScriptNetData> get_rset_properties() const;
virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
virtual StringName get_rset_property(uint16_t p_id) const;
virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const;
virtual ScriptLanguage *get_language();