mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 21:51:22 +00:00 
			
		
		
		
	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Rémi Verschelde
						Rémi Verschelde