mirror of
https://github.com/godotengine/godot.git
synced 2024-11-27 09:16:35 +08:00
C#: New RPCAttribute
Replace old RPC attributes with a new single `RPCAttribute` which works like the GDScript `@rpc` annotation.
This commit is contained in:
parent
76d0a99707
commit
8131358b71
@ -3063,16 +3063,11 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) {
|
||||
Vector<GDMonoMethod *> methods = top->get_all_methods();
|
||||
for (int i = 0; i < methods.size(); i++) {
|
||||
if (!methods[i]->is_static()) {
|
||||
Multiplayer::RPCMode mode = p_script->_member_get_rpc_mode(methods[i]);
|
||||
if (Multiplayer::RPC_MODE_DISABLED != mode) {
|
||||
Multiplayer::RPCConfig nd;
|
||||
nd.name = methods[i]->get_name();
|
||||
nd.rpc_mode = mode;
|
||||
// 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);
|
||||
Multiplayer::RPCConfig rpc_config = p_script->_member_get_rpc_config(methods[i]);
|
||||
if (rpc_config.rpc_mode != Multiplayer::RPC_MODE_DISABLED) {
|
||||
// RPC annotations can only be used once per method
|
||||
if (p_script->rpc_functions.find(rpc_config) == -1) {
|
||||
p_script->rpc_functions.push_back(rpc_config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3507,15 +3502,19 @@ int CSharpScript::get_member_line(const StringName &p_member) const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Multiplayer::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const {
|
||||
if (p_member->has_attribute(CACHED_CLASS(AnyPeerAttribute))) {
|
||||
return Multiplayer::RPC_MODE_ANY_PEER;
|
||||
}
|
||||
if (p_member->has_attribute(CACHED_CLASS(AuthorityAttribute))) {
|
||||
return Multiplayer::RPC_MODE_AUTHORITY;
|
||||
Multiplayer::RPCConfig CSharpScript::_member_get_rpc_config(IMonoClassMember *p_member) const {
|
||||
Multiplayer::RPCConfig rpc_config;
|
||||
|
||||
MonoObject *rpc_attribute = p_member->get_attribute(CACHED_CLASS(RPCAttribute));
|
||||
if (rpc_attribute != nullptr) {
|
||||
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 {
|
||||
|
@ -179,7 +179,7 @@ private:
|
||||
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);
|
||||
|
||||
Multiplayer::RPCMode _member_get_rpc_mode(IMonoClassMember *p_member) const;
|
||||
Multiplayer::RPCConfig _member_get_rpc_config(IMonoClassMember *p_member) const;
|
||||
|
||||
protected:
|
||||
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\ExportAttribute.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\SignalAttribute.cs" />
|
||||
<Compile Include="Core\Attributes\ToolAttribute.cs" />
|
||||
|
@ -140,8 +140,11 @@ void CachedData::clear_godot_api_cache() {
|
||||
field_ExportAttribute_hintString = nullptr;
|
||||
class_SignalAttribute = nullptr;
|
||||
class_ToolAttribute = nullptr;
|
||||
class_AnyPeerAttribute = nullptr;
|
||||
class_AuthorityAttribute = nullptr;
|
||||
class_RPCAttribute = nullptr;
|
||||
property_RPCAttribute_Mode = nullptr;
|
||||
property_RPCAttribute_CallLocal = nullptr;
|
||||
property_RPCAttribute_TransferMode = nullptr;
|
||||
property_RPCAttribute_TransferChannel = nullptr;
|
||||
class_GodotMethodAttribute = nullptr;
|
||||
field_GodotMethodAttribute_methodName = 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_CLASS_AND_CHECK(SignalAttribute, GODOT_API_CLASS(SignalAttribute));
|
||||
CACHE_CLASS_AND_CHECK(ToolAttribute, GODOT_API_CLASS(ToolAttribute));
|
||||
CACHE_CLASS_AND_CHECK(AnyPeerAttribute, GODOT_API_CLASS(AnyPeerAttribute));
|
||||
CACHE_CLASS_AND_CHECK(AuthorityAttribute, GODOT_API_CLASS(AuthorityAttribute));
|
||||
CACHE_CLASS_AND_CHECK(RPCAttribute, GODOT_API_CLASS(RPCAttribute));
|
||||
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_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName"));
|
||||
CACHE_CLASS_AND_CHECK(ScriptPathAttribute, GODOT_API_CLASS(ScriptPathAttribute));
|
||||
|
@ -111,8 +111,11 @@ struct CachedData {
|
||||
GDMonoField *field_ExportAttribute_hintString = nullptr;
|
||||
GDMonoClass *class_SignalAttribute = nullptr;
|
||||
GDMonoClass *class_ToolAttribute = nullptr;
|
||||
GDMonoClass *class_AnyPeerAttribute = nullptr;
|
||||
GDMonoClass *class_AuthorityAttribute = nullptr;
|
||||
GDMonoClass *class_RPCAttribute = 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;
|
||||
GDMonoField *field_GodotMethodAttribute_methodName = nullptr;
|
||||
GDMonoClass *class_ScriptPathAttribute = nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user