mirror of
https://github.com/godotengine/godot.git
synced 2025-10-22 17:33:33 +00:00
[Net] Single rpc
annotation. "sync" no longer part of mode.
- Move the "sync" property for RPCs to RPCConfig. - Unify GDScript annotations into a single one: - `@rpc(master)` # default - `@rpc(puppet)` - `@rpc(any)` # former `@remote` - Implement three additional `@rpc` options: - The second parameter is the "sync" option (which also calls the function locally when RPCing). One of "sync", "nosync". - The third parameter is the transfer mode (reliable, unreliable, ordered). - The third parameter is the channel (unused for now).
This commit is contained in:
parent
8b1c60c1a3
commit
ddb68f76ff
17 changed files with 72 additions and 127 deletions
|
@ -168,12 +168,7 @@ GDScriptParser::GDScriptParser() {
|
|||
register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>);
|
||||
register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>);
|
||||
// Networking.
|
||||
register_annotation(MethodInfo("@remote"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_REMOTE>);
|
||||
register_annotation(MethodInfo("@master"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_MASTER>);
|
||||
register_annotation(MethodInfo("@puppet"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_PUPPET>);
|
||||
register_annotation(MethodInfo("@remotesync"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_REMOTESYNC>);
|
||||
register_annotation(MethodInfo("@mastersync"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_MASTERSYNC>);
|
||||
register_annotation(MethodInfo("@puppetsync"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_PUPPETSYNC>);
|
||||
register_annotation(MethodInfo("@rpc", { Variant::STRING, "mode" }, { Variant::STRING, "sync" }, { Variant::STRING, "transfer_mode" }, { Variant::INT, "transfer_channel" }), AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_MASTER>, 4, true);
|
||||
// TODO: Warning annotations.
|
||||
}
|
||||
|
||||
|
@ -3430,27 +3425,60 @@ template <MultiplayerAPI::RPCMode t_mode>
|
|||
bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Node *p_node) {
|
||||
ERR_FAIL_COND_V_MSG(p_node->type != Node::VARIABLE && p_node->type != Node::FUNCTION, false, vformat(R"("%s" annotation can only be applied to variables and functions.)", p_annotation->name));
|
||||
|
||||
switch (p_node->type) {
|
||||
case Node::VARIABLE: {
|
||||
VariableNode *variable = static_cast<VariableNode *>(p_node);
|
||||
if (variable->rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) {
|
||||
push_error(R"(RPC annotations can only be used once per variable.)", p_annotation);
|
||||
MultiplayerAPI::RPCConfig rpc_config;
|
||||
rpc_config.rpc_mode = t_mode;
|
||||
for (int i = 0; i < p_annotation->resolved_arguments.size(); i++) {
|
||||
if (i == 0) {
|
||||
String mode = p_annotation->resolved_arguments[i].operator String();
|
||||
if (mode == "any") {
|
||||
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_REMOTE;
|
||||
} else if (mode == "master") {
|
||||
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_MASTER;
|
||||
} else if (mode == "puppet") {
|
||||
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_PUPPET;
|
||||
} else {
|
||||
push_error(R"(Invalid RPC mode. Must be one of: 'any', 'master', or 'puppet')", p_annotation);
|
||||
return false;
|
||||
}
|
||||
variable->rpc_mode = t_mode;
|
||||
break;
|
||||
} else if (i == 1) {
|
||||
String sync = p_annotation->resolved_arguments[i].operator String();
|
||||
if (sync == "sync") {
|
||||
rpc_config.sync = true;
|
||||
} else if (sync == "nosync") {
|
||||
rpc_config.sync = false;
|
||||
} else {
|
||||
push_error(R"(Invalid RPC sync mode. Must be one of: 'sync' or 'nosync')", p_annotation);
|
||||
return false;
|
||||
}
|
||||
} else if (i == 2) {
|
||||
String mode = p_annotation->resolved_arguments[i].operator String();
|
||||
if (mode == "reliable") {
|
||||
rpc_config.transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
|
||||
} else if (mode == "unreliable") {
|
||||
rpc_config.transfer_mode = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE;
|
||||
} else if (mode == "ordered") {
|
||||
rpc_config.transfer_mode = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE_ORDERED;
|
||||
} else {
|
||||
push_error(R"(Invalid RPC transfer mode. Must be one of: 'reliable', 'unreliable', 'ordered')", p_annotation);
|
||||
return false;
|
||||
}
|
||||
} else if (i == 3) {
|
||||
rpc_config.channel = p_annotation->resolved_arguments[i].operator int();
|
||||
}
|
||||
}
|
||||
switch (p_node->type) {
|
||||
case Node::FUNCTION: {
|
||||
FunctionNode *function = static_cast<FunctionNode *>(p_node);
|
||||
if (function->rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) {
|
||||
if (function->rpc_config.rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) {
|
||||
push_error(R"(RPC annotations can only be used once per function.)", p_annotation);
|
||||
return false;
|
||||
}
|
||||
function->rpc_mode = t_mode;
|
||||
function->rpc_config = rpc_config;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false; // Unreachable.
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue