Merge pull request #63049 from Faless/mp/4.x_as_module
This commit is contained in:
commit
14d021287b
80 changed files with 1819 additions and 1388 deletions
|
|
@ -954,8 +954,8 @@ void GDScript::get_members(HashSet<StringName> *p_members) {
|
|||
}
|
||||
}
|
||||
|
||||
const Vector<Multiplayer::RPCConfig> GDScript::get_rpc_methods() const {
|
||||
return rpc_functions;
|
||||
const Variant GDScript::get_rpc_config() const {
|
||||
return rpc_config;
|
||||
}
|
||||
|
||||
Variant GDScript::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
|
||||
|
|
@ -1212,9 +1212,9 @@ void GDScript::_save_orphaned_subclasses() {
|
|||
|
||||
void GDScript::_init_rpc_methods_properties() {
|
||||
// Copy the base rpc methods so we don't mask their IDs.
|
||||
rpc_functions.clear();
|
||||
rpc_config.clear();
|
||||
if (base.is_valid()) {
|
||||
rpc_functions = base->rpc_functions;
|
||||
rpc_config = base->rpc_config.duplicate();
|
||||
}
|
||||
|
||||
GDScript *cscript = this;
|
||||
|
|
@ -1222,12 +1222,9 @@ void GDScript::_init_rpc_methods_properties() {
|
|||
while (cscript) {
|
||||
// RPC Methods
|
||||
for (KeyValue<StringName, GDScriptFunction *> &E : cscript->member_functions) {
|
||||
Multiplayer::RPCConfig config = E.value->get_rpc_config();
|
||||
if (config.rpc_mode != Multiplayer::RPC_MODE_DISABLED) {
|
||||
config.name = E.value->get_name();
|
||||
if (rpc_functions.find(config) == -1) {
|
||||
rpc_functions.push_back(config);
|
||||
}
|
||||
Variant config = E.value->get_rpc_config();
|
||||
if (config.get_type() != Variant::NIL) {
|
||||
rpc_config[E.value->get_name()] = config;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1241,9 +1238,6 @@ void GDScript::_init_rpc_methods_properties() {
|
|||
cscript = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort so we are 100% that they are always the same.
|
||||
rpc_functions.sort_custom<Multiplayer::SortRPCConfig>();
|
||||
}
|
||||
|
||||
GDScript::~GDScript() {
|
||||
|
|
@ -1408,9 +1402,7 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
|
|||
while (sl) {
|
||||
HashMap<StringName, GDScriptFunction *>::ConstIterator E = sl->member_functions.find(p_name);
|
||||
if (E) {
|
||||
Multiplayer::RPCConfig config;
|
||||
config.name = p_name;
|
||||
if (sptr->rpc_functions.find(config) != -1) {
|
||||
if (sptr->rpc_config.has(p_name)) {
|
||||
r_ret = Callable(memnew(GDScriptRPCCallable(this->owner, E->key)));
|
||||
} else {
|
||||
r_ret = Callable(this->owner, E->key);
|
||||
|
|
@ -1629,8 +1621,8 @@ ScriptLanguage *GDScriptInstance::get_language() {
|
|||
return GDScriptLanguage::get_singleton();
|
||||
}
|
||||
|
||||
const Vector<Multiplayer::RPCConfig> GDScriptInstance::get_rpc_methods() const {
|
||||
return script->get_rpc_methods();
|
||||
const Variant GDScriptInstance::get_rpc_config() const {
|
||||
return script->get_rpc_config();
|
||||
}
|
||||
|
||||
void GDScriptInstance::reload_members() {
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ class GDScript : public Script {
|
|||
HashMap<StringName, MemberInfo> member_indices; //members are just indices to the instantiated script.
|
||||
HashMap<StringName, Ref<GDScript>> subclasses;
|
||||
HashMap<StringName, Vector<StringName>> _signals;
|
||||
Vector<Multiplayer::RPCConfig> rpc_functions;
|
||||
Dictionary rpc_config;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
|
|
@ -250,7 +250,7 @@ public:
|
|||
virtual void get_constants(HashMap<StringName, Variant> *p_constants) override;
|
||||
virtual void get_members(HashSet<StringName> *p_members) override;
|
||||
|
||||
virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override;
|
||||
virtual const Variant get_rpc_config() const override;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
virtual bool is_placeholder_fallback_enabled() const override { return placeholder_fallback_enabled; }
|
||||
|
|
@ -304,7 +304,7 @@ public:
|
|||
|
||||
void reload_members();
|
||||
|
||||
virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const;
|
||||
virtual const Variant get_rpc_config() const;
|
||||
|
||||
GDScriptInstance();
|
||||
~GDScriptInstance();
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ void GDScriptByteCodeGenerator::end_parameters() {
|
|||
function->default_arguments.reverse();
|
||||
}
|
||||
|
||||
void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Multiplayer::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) {
|
||||
void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Variant p_rpc_config, const GDScriptDataType &p_return_type) {
|
||||
function = memnew(GDScriptFunction);
|
||||
debug_stack = EngineDebugger::is_active();
|
||||
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ public:
|
|||
virtual void start_block() override;
|
||||
virtual void end_block() override;
|
||||
|
||||
virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Multiplayer::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) override;
|
||||
virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Variant p_rpc_config, const GDScriptDataType &p_return_type) override;
|
||||
virtual GDScriptFunction *write_end() override;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#ifndef GDSCRIPT_CODEGEN_H
|
||||
#define GDSCRIPT_CODEGEN_H
|
||||
|
||||
#include "core/multiplayer/multiplayer.h"
|
||||
#include "core/string/string_name.h"
|
||||
#include "core/variant/variant.h"
|
||||
#include "gdscript_function.h"
|
||||
|
|
@ -80,7 +79,7 @@ public:
|
|||
virtual void start_block() = 0;
|
||||
virtual void end_block() = 0;
|
||||
|
||||
virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Multiplayer::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) = 0;
|
||||
virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Variant p_rpc_config, const GDScriptDataType &p_return_type) = 0;
|
||||
virtual GDScriptFunction *write_end() = 0;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
|
|
|||
|
|
@ -1975,7 +1975,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
|
|||
|
||||
StringName func_name;
|
||||
bool is_static = false;
|
||||
Multiplayer::RPCConfig rpc_config;
|
||||
Variant rpc_config;
|
||||
GDScriptDataType return_type;
|
||||
return_type.has_type = true;
|
||||
return_type.kind = GDScriptDataType::BUILTIN;
|
||||
|
|
|
|||
|
|
@ -477,7 +477,7 @@ private:
|
|||
|
||||
int _initial_line = 0;
|
||||
bool _static = false;
|
||||
Multiplayer::RPCConfig rpc_config;
|
||||
Variant rpc_config;
|
||||
|
||||
GDScript *_script = nullptr;
|
||||
|
||||
|
|
@ -599,7 +599,7 @@ public:
|
|||
void disassemble(const Vector<String> &p_code_lines) const;
|
||||
#endif
|
||||
|
||||
_FORCE_INLINE_ Multiplayer::RPCConfig get_rpc_config() const { return rpc_config; }
|
||||
_FORCE_INLINE_ const Variant get_rpc_config() const { return rpc_config; }
|
||||
GDScriptFunction();
|
||||
~GDScriptFunction();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "core/io/resource_loader.h"
|
||||
#include "core/math/math_defs.h"
|
||||
#include "gdscript.h"
|
||||
#include "scene/main/multiplayer_api.h"
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
#include "core/os/os.h"
|
||||
|
|
@ -145,7 +146,7 @@ GDScriptParser::GDScriptParser() {
|
|||
// Warning annotations.
|
||||
register_annotation(MethodInfo("@warning_ignore", PropertyInfo(Variant::STRING, "warning")), AnnotationInfo::CLASS | AnnotationInfo::VARIABLE | AnnotationInfo::SIGNAL | AnnotationInfo::CONSTANT | AnnotationInfo::FUNCTION | AnnotationInfo::STATEMENT, &GDScriptParser::warning_annotations, varray(), true);
|
||||
// Networking.
|
||||
register_annotation(MethodInfo("@rpc", PropertyInfo(Variant::STRING, "mode"), PropertyInfo(Variant::STRING, "sync"), PropertyInfo(Variant::STRING, "transfer_mode"), PropertyInfo(Variant::INT, "transfer_channel")), AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<Multiplayer::RPC_MODE_AUTHORITY>, varray("", "", "", 0), true);
|
||||
register_annotation(MethodInfo("@rpc", PropertyInfo(Variant::STRING, "mode"), PropertyInfo(Variant::STRING, "sync"), PropertyInfo(Variant::STRING, "transfer_mode"), PropertyInfo(Variant::INT, "transfer_channel")), AnnotationInfo::FUNCTION, &GDScriptParser::rpc_annotation, varray("", "", "", 0), true);
|
||||
}
|
||||
|
||||
GDScriptParser::~GDScriptParser() {
|
||||
|
|
@ -3867,16 +3868,21 @@ bool GDScriptParser::warning_annotations(const AnnotationNode *p_annotation, Nod
|
|||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
template <Multiplayer::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));
|
||||
bool GDScriptParser::rpc_annotation(const AnnotationNode *p_annotation, Node *p_node) {
|
||||
ERR_FAIL_COND_V_MSG(p_node->type != Node::FUNCTION, false, vformat(R"("%s" annotation can only be applied to functions.)", p_annotation->name));
|
||||
|
||||
Multiplayer::RPCConfig rpc_config;
|
||||
rpc_config.rpc_mode = t_mode;
|
||||
FunctionNode *function = static_cast<FunctionNode *>(p_node);
|
||||
if (function->rpc_config.get_type() != Variant::NIL) {
|
||||
push_error(R"(RPC annotations can only be used once per function.)", p_annotation);
|
||||
return false;
|
||||
}
|
||||
|
||||
Dictionary rpc_config;
|
||||
rpc_config["rpc_mode"] = MultiplayerAPI::RPC_MODE_AUTHORITY;
|
||||
if (p_annotation->resolved_arguments.size()) {
|
||||
int last = p_annotation->resolved_arguments.size() - 1;
|
||||
if (p_annotation->resolved_arguments[last].get_type() == Variant::INT) {
|
||||
rpc_config.channel = p_annotation->resolved_arguments[last].operator int();
|
||||
rpc_config["channel"] = p_annotation->resolved_arguments[last].operator int();
|
||||
last -= 1;
|
||||
}
|
||||
if (last > 3) {
|
||||
|
|
@ -3886,37 +3892,25 @@ bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Nod
|
|||
for (int i = last; i >= 0; i--) {
|
||||
String mode = p_annotation->resolved_arguments[i].operator String();
|
||||
if (mode == "any_peer") {
|
||||
rpc_config.rpc_mode = Multiplayer::RPC_MODE_ANY_PEER;
|
||||
rpc_config["rpc_mode"] = MultiplayerAPI::RPC_MODE_ANY_PEER;
|
||||
} else if (mode == "authority") {
|
||||
rpc_config.rpc_mode = Multiplayer::RPC_MODE_AUTHORITY;
|
||||
rpc_config["rpc_mode"] = MultiplayerAPI::RPC_MODE_AUTHORITY;
|
||||
} else if (mode == "call_local") {
|
||||
rpc_config.call_local = true;
|
||||
rpc_config["call_local"] = true;
|
||||
} else if (mode == "call_remote") {
|
||||
rpc_config.call_local = false;
|
||||
rpc_config["call_local"] = false;
|
||||
} else if (mode == "reliable") {
|
||||
rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE;
|
||||
rpc_config["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
|
||||
} else if (mode == "unreliable") {
|
||||
rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_UNRELIABLE;
|
||||
rpc_config["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE;
|
||||
} else if (mode == "unreliable_ordered") {
|
||||
rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED;
|
||||
rpc_config["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE_ORDERED;
|
||||
} else {
|
||||
push_error(R"(Invalid RPC argument. Must be one of: 'call_local'/'call_remote' (local calls), 'any_peer'/'authority' (permission), 'reliable'/'unreliable'/'unreliable_ordered' (transfer mode).)", p_annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (p_node->type) {
|
||||
case Node::FUNCTION: {
|
||||
FunctionNode *function = static_cast<FunctionNode *>(p_node);
|
||||
if (function->rpc_config.rpc_mode != Multiplayer::RPC_MODE_DISABLED) {
|
||||
push_error(R"(RPC annotations can only be used once per function.)", p_annotation);
|
||||
return false;
|
||||
}
|
||||
function->rpc_config = rpc_config;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false; // Unreachable.
|
||||
}
|
||||
function->rpc_config = rpc_config;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
#define GDSCRIPT_PARSER_H
|
||||
|
||||
#include "core/io/resource.h"
|
||||
#include "core/multiplayer/multiplayer.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
#include "core/object/script_language.h"
|
||||
#include "core/string/string_name.h"
|
||||
|
|
@ -750,7 +749,7 @@ public:
|
|||
SuiteNode *body = nullptr;
|
||||
bool is_static = false;
|
||||
bool is_coroutine = false;
|
||||
Multiplayer::RPCConfig rpc_config;
|
||||
Variant rpc_config;
|
||||
MethodInfo info;
|
||||
LambdaNode *source_lambda = nullptr;
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
|
@ -1371,8 +1370,7 @@ private:
|
|||
template <PropertyUsageFlags t_usage>
|
||||
bool export_group_annotations(const AnnotationNode *p_annotation, Node *p_target);
|
||||
bool warning_annotations(const AnnotationNode *p_annotation, Node *p_target);
|
||||
template <Multiplayer::RPCMode t_mode>
|
||||
bool network_annotations(const AnnotationNode *p_annotation, Node *p_target);
|
||||
bool rpc_annotation(const AnnotationNode *p_annotation, Node *p_target);
|
||||
// Statements.
|
||||
Node *parse_statement();
|
||||
VariableNode *parse_variable();
|
||||
|
|
|
|||
|
|
@ -76,11 +76,11 @@ GDScriptRPCCallable::GDScriptRPCCallable(Object *p_object, const StringName &p_m
|
|||
ERR_FAIL_COND_MSG(!node, "RPC can only be defined on class that extends Node.");
|
||||
}
|
||||
|
||||
void GDScriptRPCCallable::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const {
|
||||
Error GDScriptRPCCallable::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const {
|
||||
if (unlikely(!node)) {
|
||||
r_call_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
|
||||
return;
|
||||
return ERR_UNCONFIGURED;
|
||||
}
|
||||
r_call_error.error = Callable::CallError::CALL_OK;
|
||||
node->rpcp(p_peer_id, method, p_arguments, p_argcount);
|
||||
return node->rpcp(p_peer_id, method, p_arguments, p_argcount);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public:
|
|||
CompareLessFunc get_compare_less_func() const override;
|
||||
ObjectID get_object() const override;
|
||||
void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
|
||||
void rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override;
|
||||
Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override;
|
||||
|
||||
GDScriptRPCCallable(Object *p_object, const StringName &p_method);
|
||||
virtual ~GDScriptRPCCallable() = default;
|
||||
|
|
|
|||
|
|
@ -690,9 +690,7 @@ Dictionary ExtendGDScriptParser::dump_function_api(const GDScriptParser::Functio
|
|||
ERR_FAIL_NULL_V(p_func, func);
|
||||
func["name"] = p_func->identifier->name;
|
||||
func["return_type"] = p_func->get_datatype().to_string();
|
||||
func["rpc_mode"] = p_func->rpc_config.rpc_mode;
|
||||
func["rpc_transfer_mode"] = p_func->rpc_config.transfer_mode;
|
||||
func["rpc_transfer_channel"] = p_func->rpc_config.channel;
|
||||
func["rpc_config"] = p_func->rpc_config;
|
||||
Array parameters;
|
||||
for (int i = 0; i < p_func->parameters.size(); i++) {
|
||||
Dictionary arg;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue