Merge pull request #62805 from raulsntos/csharp-rpc
This commit is contained in:
commit
31974aaae2
7 changed files with 76 additions and 41 deletions
|
@ -3069,16 +3069,11 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) {
|
||||||
Vector<GDMonoMethod *> methods = top->get_all_methods();
|
Vector<GDMonoMethod *> methods = top->get_all_methods();
|
||||||
for (int i = 0; i < methods.size(); i++) {
|
for (int i = 0; i < methods.size(); i++) {
|
||||||
if (!methods[i]->is_static()) {
|
if (!methods[i]->is_static()) {
|
||||||
Multiplayer::RPCMode mode = p_script->_member_get_rpc_mode(methods[i]);
|
Multiplayer::RPCConfig rpc_config = p_script->_member_get_rpc_config(methods[i]);
|
||||||
if (Multiplayer::RPC_MODE_DISABLED != mode) {
|
if (rpc_config.rpc_mode != Multiplayer::RPC_MODE_DISABLED) {
|
||||||
Multiplayer::RPCConfig nd;
|
// RPC annotations can only be used once per method
|
||||||
nd.name = methods[i]->get_name();
|
if (p_script->rpc_functions.find(rpc_config) == -1) {
|
||||||
nd.rpc_mode = mode;
|
p_script->rpc_functions.push_back(rpc_config);
|
||||||
// TODO Transfer mode, channel
|
|
||||||
nd.transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE;
|
|
||||||
nd.channel = 0;
|
|
||||||
if (-1 == p_script->rpc_functions.find(nd)) {
|
|
||||||
p_script->rpc_functions.push_back(nd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3513,15 +3508,19 @@ int CSharpScript::get_member_line(const StringName &p_member) const {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Multiplayer::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const {
|
Multiplayer::RPCConfig CSharpScript::_member_get_rpc_config(IMonoClassMember *p_member) const {
|
||||||
if (p_member->has_attribute(CACHED_CLASS(AnyPeerAttribute))) {
|
Multiplayer::RPCConfig rpc_config;
|
||||||
return Multiplayer::RPC_MODE_ANY_PEER;
|
|
||||||
}
|
MonoObject *rpc_attribute = p_member->get_attribute(CACHED_CLASS(RPCAttribute));
|
||||||
if (p_member->has_attribute(CACHED_CLASS(AuthorityAttribute))) {
|
if (rpc_attribute != nullptr) {
|
||||||
return Multiplayer::RPC_MODE_AUTHORITY;
|
rpc_config.name = p_member->get_name();
|
||||||
|
rpc_config.rpc_mode = (Multiplayer::RPCMode)CACHED_PROPERTY(RPCAttribute, Mode)->get_int_value(rpc_attribute);
|
||||||
|
rpc_config.call_local = CACHED_PROPERTY(RPCAttribute, CallLocal)->get_bool_value(rpc_attribute);
|
||||||
|
rpc_config.transfer_mode = (Multiplayer::TransferMode)CACHED_PROPERTY(RPCAttribute, TransferMode)->get_int_value(rpc_attribute);
|
||||||
|
rpc_config.channel = CACHED_PROPERTY(RPCAttribute, TransferChannel)->get_int_value(rpc_attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Multiplayer::RPC_MODE_DISABLED;
|
return rpc_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector<Multiplayer::RPCConfig> CSharpScript::get_rpc_methods() const {
|
const Vector<Multiplayer::RPCConfig> CSharpScript::get_rpc_methods() const {
|
||||||
|
|
|
@ -179,7 +179,7 @@ private:
|
||||||
static void update_script_class_info(Ref<CSharpScript> p_script);
|
static void update_script_class_info(Ref<CSharpScript> p_script);
|
||||||
static void initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native);
|
static void initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native);
|
||||||
|
|
||||||
Multiplayer::RPCMode _member_get_rpc_mode(IMonoClassMember *p_member) const;
|
Multiplayer::RPCConfig _member_get_rpc_config(IMonoClassMember *p_member) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Godot
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute that changes the RPC mode for the annotated <c>method</c> to the given <see cref="Mode"/>,
|
||||||
|
/// optionally specifying the <see cref="TransferMode"/> and <see cref="TransferChannel"/> (on supported peers).
|
||||||
|
/// See <see cref="RPCMode"/> and <see cref="TransferMode"/>. By default, methods are not exposed to networking
|
||||||
|
/// (and RPCs).
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
||||||
|
public class RPCAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// RPC mode for the annotated method.
|
||||||
|
/// </summary>
|
||||||
|
public RPCMode Mode { get; } = RPCMode.Disabled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the method will also be called locally; otherwise, it is only called remotely.
|
||||||
|
/// </summary>
|
||||||
|
public bool CallLocal { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transfer mode for the annotated method.
|
||||||
|
/// </summary>
|
||||||
|
public TransferMode TransferMode { get; set; } = TransferMode.Reliable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transfer channel for the annotated mode.
|
||||||
|
/// </summary>
|
||||||
|
public int TransferChannel { get; set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a <see cref="RPCAttribute"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mode">The RPC mode to use.</param>
|
||||||
|
public RPCAttribute(RPCMode mode = RPCMode.Authority)
|
||||||
|
{
|
||||||
|
Mode = mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Godot
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new AnyPeerAttribute instance. Members with the AnyPeerAttribute are given authority over their own player.
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Method)]
|
|
||||||
public class AnyPeerAttribute : Attribute { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new AuthorityAttribute instance. Members with the AuthorityAttribute are given authority over the game.
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Method)]
|
|
||||||
public class AuthorityAttribute : Attribute { }
|
|
||||||
}
|
|
|
@ -18,7 +18,7 @@
|
||||||
<Compile Include="Core\Attributes\DisableGodotGeneratorsAttribute.cs" />
|
<Compile Include="Core\Attributes\DisableGodotGeneratorsAttribute.cs" />
|
||||||
<Compile Include="Core\Attributes\ExportAttribute.cs" />
|
<Compile Include="Core\Attributes\ExportAttribute.cs" />
|
||||||
<Compile Include="Core\Attributes\GodotMethodAttribute.cs" />
|
<Compile Include="Core\Attributes\GodotMethodAttribute.cs" />
|
||||||
<Compile Include="Core\Attributes\RPCAttributes.cs" />
|
<Compile Include="Core\Attributes\RPCAttribute.cs" />
|
||||||
<Compile Include="Core\Attributes\ScriptPathAttribute.cs" />
|
<Compile Include="Core\Attributes\ScriptPathAttribute.cs" />
|
||||||
<Compile Include="Core\Attributes\SignalAttribute.cs" />
|
<Compile Include="Core\Attributes\SignalAttribute.cs" />
|
||||||
<Compile Include="Core\Attributes\ToolAttribute.cs" />
|
<Compile Include="Core\Attributes\ToolAttribute.cs" />
|
||||||
|
|
|
@ -140,8 +140,11 @@ void CachedData::clear_godot_api_cache() {
|
||||||
field_ExportAttribute_hintString = nullptr;
|
field_ExportAttribute_hintString = nullptr;
|
||||||
class_SignalAttribute = nullptr;
|
class_SignalAttribute = nullptr;
|
||||||
class_ToolAttribute = nullptr;
|
class_ToolAttribute = nullptr;
|
||||||
class_AnyPeerAttribute = nullptr;
|
class_RPCAttribute = nullptr;
|
||||||
class_AuthorityAttribute = nullptr;
|
property_RPCAttribute_Mode = nullptr;
|
||||||
|
property_RPCAttribute_CallLocal = nullptr;
|
||||||
|
property_RPCAttribute_TransferMode = nullptr;
|
||||||
|
property_RPCAttribute_TransferChannel = nullptr;
|
||||||
class_GodotMethodAttribute = nullptr;
|
class_GodotMethodAttribute = nullptr;
|
||||||
field_GodotMethodAttribute_methodName = nullptr;
|
field_GodotMethodAttribute_methodName = nullptr;
|
||||||
class_ScriptPathAttribute = nullptr;
|
class_ScriptPathAttribute = nullptr;
|
||||||
|
@ -268,8 +271,11 @@ void update_godot_api_cache() {
|
||||||
CACHE_FIELD_AND_CHECK(ExportAttribute, hintString, CACHED_CLASS(ExportAttribute)->get_field("hintString"));
|
CACHE_FIELD_AND_CHECK(ExportAttribute, hintString, CACHED_CLASS(ExportAttribute)->get_field("hintString"));
|
||||||
CACHE_CLASS_AND_CHECK(SignalAttribute, GODOT_API_CLASS(SignalAttribute));
|
CACHE_CLASS_AND_CHECK(SignalAttribute, GODOT_API_CLASS(SignalAttribute));
|
||||||
CACHE_CLASS_AND_CHECK(ToolAttribute, GODOT_API_CLASS(ToolAttribute));
|
CACHE_CLASS_AND_CHECK(ToolAttribute, GODOT_API_CLASS(ToolAttribute));
|
||||||
CACHE_CLASS_AND_CHECK(AnyPeerAttribute, GODOT_API_CLASS(AnyPeerAttribute));
|
CACHE_CLASS_AND_CHECK(RPCAttribute, GODOT_API_CLASS(RPCAttribute));
|
||||||
CACHE_CLASS_AND_CHECK(AuthorityAttribute, GODOT_API_CLASS(AuthorityAttribute));
|
CACHE_PROPERTY_AND_CHECK(RPCAttribute, Mode, CACHED_CLASS(RPCAttribute)->get_property("Mode"));
|
||||||
|
CACHE_PROPERTY_AND_CHECK(RPCAttribute, CallLocal, CACHED_CLASS(RPCAttribute)->get_property("CallLocal"));
|
||||||
|
CACHE_PROPERTY_AND_CHECK(RPCAttribute, TransferMode, CACHED_CLASS(RPCAttribute)->get_property("TransferMode"));
|
||||||
|
CACHE_PROPERTY_AND_CHECK(RPCAttribute, TransferChannel, CACHED_CLASS(RPCAttribute)->get_property("TransferChannel"));
|
||||||
CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute));
|
CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute));
|
||||||
CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName"));
|
CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName"));
|
||||||
CACHE_CLASS_AND_CHECK(ScriptPathAttribute, GODOT_API_CLASS(ScriptPathAttribute));
|
CACHE_CLASS_AND_CHECK(ScriptPathAttribute, GODOT_API_CLASS(ScriptPathAttribute));
|
||||||
|
|
|
@ -111,8 +111,11 @@ struct CachedData {
|
||||||
GDMonoField *field_ExportAttribute_hintString = nullptr;
|
GDMonoField *field_ExportAttribute_hintString = nullptr;
|
||||||
GDMonoClass *class_SignalAttribute = nullptr;
|
GDMonoClass *class_SignalAttribute = nullptr;
|
||||||
GDMonoClass *class_ToolAttribute = nullptr;
|
GDMonoClass *class_ToolAttribute = nullptr;
|
||||||
GDMonoClass *class_AnyPeerAttribute = nullptr;
|
GDMonoClass *class_RPCAttribute = nullptr;
|
||||||
GDMonoClass *class_AuthorityAttribute = nullptr;
|
GDMonoProperty *property_RPCAttribute_Mode = nullptr;
|
||||||
|
GDMonoProperty *property_RPCAttribute_CallLocal = nullptr;
|
||||||
|
GDMonoProperty *property_RPCAttribute_TransferMode = nullptr;
|
||||||
|
GDMonoProperty *property_RPCAttribute_TransferChannel = nullptr;
|
||||||
GDMonoClass *class_GodotMethodAttribute = nullptr;
|
GDMonoClass *class_GodotMethodAttribute = nullptr;
|
||||||
GDMonoField *field_GodotMethodAttribute_methodName = nullptr;
|
GDMonoField *field_GodotMethodAttribute_methodName = nullptr;
|
||||||
GDMonoClass *class_ScriptPathAttribute = nullptr;
|
GDMonoClass *class_ScriptPathAttribute = nullptr;
|
||||||
|
|
Loading…
Reference in a new issue