/// <summary> /// Checks if we should replicate this to other clients and sets our internal state accordingly. /// </summary> public void CheckIfShouldReplicate() { MasterAttribute MasterAtr = MDReflectionCache.GetCustomAttribute <MasterAttribute>(Member) as MasterAttribute; MasterSyncAttribute MasterSyncAtr = MDReflectionCache.GetCustomAttribute <MasterSyncAttribute>(Member) as MasterSyncAttribute; Node Node = NodeRef.GetRef() as Node; bool IsMaster = MDStatics.GetPeerId() == Node.GetNetworkMaster(); IsShouldReplicate = (IsMaster && MasterAtr == null && MasterSyncAtr == null) || (IsMaster == false && (MasterAtr != null || MasterSyncAtr != null)); }
private bool HasRPCModeSet(MemberInfo Member) { MasterAttribute MasterAtr = MDReflectionCache.GetCustomAttribute <MasterAttribute>(Member) as MasterAttribute; MasterSyncAttribute MasterSyncAtr = MDReflectionCache.GetCustomAttribute <MasterSyncAttribute>(Member) as MasterSyncAttribute; PuppetAttribute PuppetAtr = MDReflectionCache.GetCustomAttribute <PuppetAttribute>(Member) as PuppetAttribute; PuppetSyncAttribute PuppetSyncAtr = MDReflectionCache.GetCustomAttribute <PuppetSyncAttribute>(Member) as PuppetSyncAttribute; RemoteAttribute RemoteAtr = MDReflectionCache.GetCustomAttribute <RemoteAttribute>(Member) as RemoteAttribute; RemoteSyncAttribute RemoteSyncAtr = MDReflectionCache.GetCustomAttribute <RemoteSyncAttribute>(Member) as RemoteSyncAttribute; return(MasterAtr != null || MasterSyncAtr != null || PuppetAtr != null || PuppetSyncAtr != null || RemoteAtr != null || RemoteSyncAtr != null); }
public static void PopulateBindNodes(Node Instance) { IList <MemberInfo> Members = MDStatics.GetTypeMemberInfos(Instance); foreach (MemberInfo Member in Members) { MDBindNode BindAttr = MDReflectionCache.GetCustomAttribute <MDBindNode>(Member) as MDBindNode; if (BindAttr == null) { continue; } Type MemberType = null; FieldInfo Field = Member as FieldInfo; PropertyInfo Property = Member as PropertyInfo; if (Field != null) { MemberType = Field.FieldType; } else if (Property != null) { MemberType = Property.PropertyType; } if (!MDStatics.IsSameOrSubclass(MemberType, typeof(Node))) { MDLog.Error(LOG_CAT, $"Not Node-Type field [{Member.Name}] on Node {Instance.Name} with Type [{Instance.GetType().Name}] was marked with [MDBindNode()]"); continue; } string PathToNode = BindAttr.GetNodePath(Member.Name); Node BoundNode = Instance.MDFindNode(PathToNode); if (BoundNode == null) { continue; } if (Field != null) { Field.SetValue(Instance, BoundNode); } else if (Property != null) { Property.SetValue(Instance, BoundNode); } } }
/// <summary> /// Unregisters all the methods marked with an MDCommand of the given type /// </summary> /// <param name="ObjType">The type</param> /// <param name="Instance">The object to unregister for</param> public static void UnregisterCommandAttributes(Type ObjType, object Instance = null) { if (MDStatics.IsInGodotNamespace(ObjType)) { return; } IList <MethodInfo> Methods = ObjType.GetMethodInfos(); foreach (MethodInfo Method in Methods) { MDCommand CmdAttr = MDReflectionCache.GetCustomAttribute <MDCommand>(Method) as MDCommand; if (CmdAttr != null) { UnregisterCommand(Instance, Method); } } }
/// <summary> /// Find all methods with the given attribute inside the type /// </summary> /// <param name="Type">The type to search inside</param> /// <typeparam name="T">The attribute to search for</typeparam> /// <returns>List of MethodInfos that has the attribute or an empty list</returns> public static List <MethodInfo> GetAllMethodsWithAttribute <T>(this Type Type) where T : Attribute { IList <MethodInfo> Methods = Type.GetMethodInfos(); List <MethodInfo> ReturnList = new List <MethodInfo>(); foreach (MethodInfo Method in Methods) { T RepAttribute = MDReflectionCache.GetCustomAttribute <T>(Method) as T;; if (RepAttribute == null) { continue; } ReturnList.Add(Method); } return(ReturnList); }
private void ExtractMembers() { if (Members == null) { Members = new List <MemberInfo>(); DataConverters = new List <IMDDataConverter>(); IList <MemberInfo> MemberInfos = typeof(T).GetMemberInfos(); foreach (MemberInfo Member in MemberInfos) { MDReplicated RepAttribute = MDReflectionCache.GetCustomAttribute <MDReplicated>(Member) as MDReplicated; if (RepAttribute == null) { continue; } Members.Add(Member); DataConverters.Add(MDStatics.GetConverterForType(Member.GetUnderlyingType())); } } }
/// <summary> /// Get rpc type of a method /// </summary> /// <param name="Node">The node to check</param> /// <param name="Method">The method name</param> /// <param name="Parameters">The parameters the method takes</param> /// <returns>The rpc type</returns> public static MDRemoteMode GetMethodRpcType(Node Node, string Method, params object[] Parameters) { MethodInfo Info = GetMethodInfo(Node, Method, Parameters); if (Info == null) { return(MDRemoteMode.Unknown); } if (MDReflectionCache.GetCustomAttribute <RemoteAttribute>(Info) != null) { return(MDRemoteMode.Remote); } if (MDReflectionCache.GetCustomAttribute <RemoteSyncAttribute>(Info) != null) { return(MDRemoteMode.RemoteSync); } if (MDReflectionCache.GetCustomAttribute <PuppetAttribute>(Info) != null) { return(MDRemoteMode.Puppet); } if (MDReflectionCache.GetCustomAttribute <PuppetSyncAttribute>(Info) != null) { return(MDRemoteMode.PuppetSync); } if (MDReflectionCache.GetCustomAttribute <MasterAttribute>(Info) != null) { return(MDRemoteMode.Master); } if (MDReflectionCache.GetCustomAttribute <MasterSyncAttribute>(Info) != null) { return(MDRemoteMode.MasterSync); } return(MDRemoteMode.Unknown); }
/// <summary> /// Get the RPC type of a member /// </summary> /// <param name="Node">The node the member belongs to</param> /// <param name="MemberName">The name of the member</param> /// <returns>The rpc type as an enum</returns> public static MDRemoteMode GetMemberRpcType(Node Node, string MemberName) { MemberInfo Info = GetMemberInfo(Node, MemberName); if (Info == null) { return(MDRemoteMode.Unknown); } if (MDReflectionCache.GetCustomAttribute <RemoteAttribute>(Info) != null) { return(MDRemoteMode.Remote); } if (MDReflectionCache.GetCustomAttribute <RemoteSyncAttribute>(Info) != null) { return(MDRemoteMode.RemoteSync); } if (MDReflectionCache.GetCustomAttribute <PuppetAttribute>(Info) != null) { return(MDRemoteMode.Puppet); } if (MDReflectionCache.GetCustomAttribute <PuppetSyncAttribute>(Info) != null) { return(MDRemoteMode.PuppetSync); } if (MDReflectionCache.GetCustomAttribute <MasterAttribute>(Info) != null) { return(MDRemoteMode.Master); } if (MDReflectionCache.GetCustomAttribute <MasterSyncAttribute>(Info) != null) { return(MDRemoteMode.MasterSync); } return(MDRemoteMode.Unknown); }
/// <summary> /// Returns the attribute object for the specified type, /// climbing the hierarchy until Node is reached or the attribute is found /// </summary> /// <param name="InstanceType">The type to search</param> /// <typeparam name="T">The type to find</typeparam> /// <returns>The attribute object for the specified type or null if not found</returns> public static T FindClassAttributeInNode <T>(Type InstanceType) where T : Attribute { return(MDReflectionCache.FindClassAttributeInNode <T>(InstanceType)); }
/// <summary> /// Returns a list of all the unique methods for a Node, including the hierarchy /// </summary> /// <param name="Instance">The object type to find for</param> /// <returns>List of methodss</returns> public static IList <MethodInfo> GetMethodInfos(this Type Instance) { return(MDReflectionCache.GetMethodInfos(Instance)); }
/// <summary> /// Registers the given instance's fields marked with [MDReplicated()] /// </summary> /// <param name="Instance">The node to register</param> public void RegisterReplication(Node Instance) { IList <MemberInfo> Members = MDStatics.GetTypeMemberInfos(Instance); List <MDReplicatedMember> NodeMembers = new List <MDReplicatedMember>(); foreach (MemberInfo Member in Members) { MDReplicated RepAttribute = MDReflectionCache.GetCustomAttribute <MDReplicated>(Member) as MDReplicated; if (RepAttribute == null) { continue; } MDReplicatedSetting[] Settings = GetSettings(Member); MDReplicatedMember NodeMember = CreateReplicatedMember(Member, RepAttribute, Instance, Settings); NodeMembers.Add(NodeMember); ProcessSettingsForMember(NodeMember, ParseParameters(typeof(Settings), Settings)); GroupManager.AddReplicatedMember(NodeMember); MDLog.Debug(LOG_CAT, $"Adding Replicated Node {Instance.Name} Member {Member.Name}"); if (HasRPCModeSet(Member) == false) { Instance.RsetConfig(Member.Name, MultiplayerAPI.RPCMode.Puppet); } } if (NodeMembers.Count > 0) { NodeList.Add(new ReplicatedNode(Instance, NodeMembers)); List <object> networkIdUpdates = new List <object>(); foreach (MDReplicatedMember member in NodeMembers) { string MemberUniqueKey = member.GetUniqueKey(); KeyToMemberMap.Add(MemberUniqueKey, member); // Check if we have a buffer waiting for this member if (NetworkIdKeyMap.ContainsKey(MemberUniqueKey)) { NetworkIdKeyMap.CheckBuffer(NetworkIdKeyMap.GetValue(MemberUniqueKey), member); } if (MDStatics.IsServer()) { if (!NetworkIdKeyMap.ContainsKey(member.GetUniqueKey())) { uint networkid = GetReplicationId(); MDLog.Debug(LOG_CAT, $"Adding NetworkIdKeyMap key [{member.GetUniqueKey()}] with id [{networkid}]"); NetworkIdKeyMap.AddNetworkKeyIdPair(networkid, member.GetUniqueKey()); NetworkIdKeyMap.CheckBuffer(networkid, member); networkIdUpdates.Add(networkid); networkIdUpdates.Add(member.GetUniqueKey()); } } } if (MDStatics.IsNetworkActive() && networkIdUpdates.Count > 0) { Rpc(nameof(UpdateNetworkIdMap), networkIdUpdates); } } }
// Returns an array of settings for the member private MDReplicatedSetting[] GetSettings(MemberInfo Member) { object[] Settings = MDReflectionCache.GetCustomAttributes <MDReplicatedSetting>(Member, true); return(Array.ConvertAll(Settings, item => (MDReplicatedSetting)item)); }