示例#1
0
 /// <summary>
 /// Handler for if a child string changes
 /// </summary>
 /// <param name="elementID">Element Id</param>
 /// <param name="newValue">New Value</param>
 protected virtual void OnStringElementChanged(long elementID, XString newValue)
 {
     if (primitiveMap.ContainsKey(elementID))
     {
         SyncPrimitive primitive = primitiveMap[elementID];
         primitive.UpdateFromRemote(newValue);
         NotifyPrimitiveChanged(primitive);
     }
     else
     {
         LogUnknownElement(elementID.ToString(), newValue.GetString(), typeof(string));
     }
 }
示例#2
0
 /// <summary>
 /// Handler for if a child double changes
 /// </summary>
 /// <param name="elementID">Element Id</param>
 /// <param name="newValue">New Value</param>
 protected virtual void OnDoubleElementChanged(long elementID, double newValue)
 {
     if (primitiveMap.ContainsKey(elementID))
     {
         SyncPrimitive primitive = primitiveMap[elementID];
         primitive.UpdateFromRemote(newValue);
         NotifyPrimitiveChanged(primitive);
     }
     else
     {
         LogUnknownElement(elementID.ToString(), newValue.ToString(CultureInfo.InvariantCulture), typeof(double));
     }
 }
示例#3
0
        /// <summary>
        /// Register a new data model primitive as part of this object.  Can be called multiple times on the same child.
        /// </summary>
        /// <param name="data">Sync Primitive Data</param>
        protected void AddChild(SyncPrimitive data)
        {
            if (data.HasNetworkElement)
            {
                long guid = data.Guid;
                Assert.AreNotEqual(SharingClient.kInvalidXGuid, guid, "A primitive GUID should never be invalid if it is networked.");
                primitiveMap.Add(guid, data);
            }

            if (!primitives.Contains(data))
            {
                primitives.Add(data);
            }
        }
示例#4
0
        /// <summary>
        /// Remove a child primitive that belongs to this object.
        /// </summary>
        /// <param name="data">Sync Primitive Data</param>
        protected void RemoveChild(SyncPrimitive data)
        {
            // Manually remove from maps
            if (primitives.Remove(data) && data.HasNetworkElement)
            {
                primitiveMap.Remove(data.NetworkElement.GetGUID());

                // Object has been removed internally, notify network
                ObjectElement parentElement = ObjectElement.Cast(data.NetworkElement.GetParent());
                if (parentElement != null)
                {
                    parentElement.RemoveElement(data.NetworkElement);
                }
            }
        }
示例#5
0
        /// <summary>
        /// Initializes this object for local use.  Doesn't wait for network initialization.
        /// </summary>
        /// <param name="parentElement">Parent element of this SyncObject.</param>
        public override void InitializeLocal(ObjectElement parentElement)
        {
            // Auto create element if needed
            if (Element == null)
            {
                Element        = parentElement.CreateObjectElement(XStringFieldName, GetType().FullName, Owner);
                NetworkElement = Element;
            }

            // Initialize all primitives
            for (int i = 0; i < primitives.Count; i++)
            {
                SyncPrimitive data = primitives[i];
                data.InitializeLocal(Element);
                primitiveMap[data.Guid] = data;
            }

            // Complete the initialization
            if (InitializationComplete != null)
            {
                InitializationComplete(this);
            }
        }
示例#6
0
 protected virtual void NotifyPrimitiveChanged(SyncPrimitive primitive)
 {
     ObjectChanged.RaiseEvent(this);
 }
示例#7
0
        private void InitializePrimitives()
        {
            primitiveMap = new Dictionary <long, SyncPrimitive>();
            primitives   = new List <SyncPrimitive>();

            // Scan the type of object this is a look for the SyncDataAttribute
            Type baseType = GetType();

#if WINDOWS_UWP
            var typeFields = baseType.GetRuntimeFields();
#else
            var typeFields = baseType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
#endif

            foreach (FieldInfo typeField in typeFields)
            {
                SyncDataAttribute attribute = null;

#if WINDOWS_UWP
                attribute = typeField.GetCustomAttribute <SyncDataAttribute>(true);
#else
                object[] customAttributes = typeField.GetCustomAttributes(typeof(SyncDataAttribute), true);
                if (customAttributes.Length > 0)
                {
                    attribute = customAttributes[0] as SyncDataAttribute;
                }
#endif

                if (attribute != null)
                {
                    Type   fieldType  = typeField.FieldType;
                    string memberName = typeField.Name;

                    // Override the member name if provided
                    if (!string.IsNullOrEmpty(attribute.CustomFieldName))
                    {
                        memberName = attribute.CustomFieldName;
                    }

                    // Auto instantiate the primitive if it doesn't already exist
                    SyncPrimitive dataPrimitive = typeField.GetValue(this) as SyncPrimitive;
                    if (dataPrimitive == null)
                    {
                        try
                        {
                            // Constructors are not inherited, as per Section 1.6.7.1 of the C# Language Specification.
                            // This means that if a class subclasses Object or Primitive, they must either declare a constructor
                            // that takes the "memberName" property or use the default (parameter less constructor).

                            // First check if there is a constructor that takes the member name and if so call it
                            bool hasConstructor = fieldType.GetConstructor(new[] { typeof(string) }) != null;
                            if (hasConstructor)
                            {
                                dataPrimitive = (SyncPrimitive)Activator.CreateInstance(fieldType, memberName);
                            }
                            else
                            {
                                // Fallback on using the default constructor and manually assign the member name
                                dataPrimitive           = (SyncPrimitive)Activator.CreateInstance(fieldType, null);
                                dataPrimitive.FieldName = memberName;
                            }

                            typeField.SetValue(this, dataPrimitive);
                        }
                        catch (Exception ex)
                        {
                            Debug.LogWarningFormat("Unable to create SyncPrimitive of type {0}.  Exception: {1}", memberName, ex);
                        }
                    }

                    if (dataPrimitive != null)
                    {
                        // Register the child
                        AddChild(dataPrimitive);
                    }
                }
            }
        }