예제 #1
0
        /// <summary>
        /// Retrieve the Data Drawer object that will be used to display the supplied data
        /// </summary>
        /// <param name="data">The SerialData object that contains the type information that needs to be displayed</param>
        /// <returns>Returns a data drawer that will be used to show the information</returns>
        private IDataDrawer GetDrawerForData(SerialData data)
        {
            // Determine if the there is a modifier drawer that is needed for this type
            if (data.Modifier != null)
            {
                // Check if there is a data drawer that can be used for the
                IDataDrawer modDrawer = GetDrawerForType(data.Modifier.GetType());
                if (modDrawer != null)
                {
                    return(modDrawer);
                }
            }

            // Check if there is a drawer setup for the data type itself
            IDataDrawer valDrawer = GetDrawerForType(data.DataType);

            if (valDrawer != null)
            {
                return(valDrawer);
            }

            // If got this far, we're displaying with the default drawer
            return(defaultDrawer);
        }
예제 #2
0
        /// <summary>
        /// Setup the required elements needed to display the current data elements within the inspector
        /// </summary>
        /// <param name="serialDataProperty">The property that defines the location of the data to retrieve</param>
        /// <param name="data">Passes out the data actual objects that are being shown within the inspector</param>
        /// <param name="valueProperty">Passes out the serial value property that is being displayed within the inspector</param>
        /// <param name="storage">Passes out the storage objects that will hold the data values that are being shown</param>
        /// <param name="dataDrawer">Passes out the Drawer instance that will be used to display the required information</param>
        private void SetupDataForDisplay(SerializedProperty serialDataProperty, out SerialData[] data, out SerializedProperty valueProperty, out SerialStorage[] storage, out IDataDrawer dataDrawer)
        {
            // Retrieve the data objects that are to be shown
            data = GetPropertyValues(serialDataProperty);

            // If the data can be displayed, find a useful data drawer
            if (CanDataBeDisplayed(data, out valueProperty, out storage, out dataDrawer))
            {
                dataDrawer = GetDrawerForData(data[0]);
            }

            // If there is a data object, apply it's settings to the drawer
            if (data[0] != null)
            {
                dataDrawer.DataType = data[0].DataType;
                dataDrawer.Modifier = data[0].Modifier;
            }
        }
예제 #3
0
        /// <summary>
        /// Determine if the specified data objects can be displayed using a drawer
        /// </summary>
        /// <param name="data">The data objects that are to be shown within the inspector</param>
        /// <param name="valueProperty">The serialised value property that is to be displayed</param>
        /// <param name="storage">The storage elements that are being used to hold the display values</param>
        /// <param name="invalidDrawer">A Drawer that will be used in the case that will be used in the case the data can't be shown</param>
        /// <returns>Returns true if the data can be shown to inspector window</returns>
        private bool CanDataBeDisplayed(SerialData[] data, out SerializedProperty valueProperty, out SerialStorage[] storage, out IDataDrawer invalidDrawer)
        {
            // Set the default out values
            valueProperty = null;
            storage       = null;
            invalidDrawer = null;

            // Check that all of the data objects are valid for display
            SerialData baseLine = null;

            if (data != null)
            {
                for (int i = 0; i < data.Length; ++i)
                {
                    // If this value is null then we have a problem
                    if (data == null)
                    {
                        baseLine = null;
                        break;
                    }

                    // If there is no baseline instance, use this
                    else if (baseLine == null)
                    {
                        baseLine = data[i];
                    }

                    // If there is a type mismatch then we have a problem
                    else if (baseLine.DataType != data[i].DataType ||
                             !object.Equals(baseLine.Modifier, data[i].Modifier))
                    {
                        baseLine = null;
                        break;
                    }
                }
            }

            // If there is no baseline then there is a type mismatch that can't be resolved
            if (baseLine == null)
            {
                invalidDrawer = mismatchDrawer;
                return(false);
            }

            // If the data isn't serialisable then can't display
            if (!baseLine.IsValid)
            {
                invalidDrawer = nonSerialDrawer;
                return(false);
            }

            // Get the collection of storage objects that will be used for display
            storage = GetStorageForData(baseLine.DataType, data.Length);
            if (storage == null)
            {
                invalidDrawer = generateDrawer;
                return(false);
            }

            // Assign the data to the storage objects for display
            for (int i = 0; i < data.Length; ++i)
            {
                // Ensure the live value reflects the serial data properly
                data[i].OnAfterDeserialize();

                // Assign the specified value to the storage element
                if (!storage[i].SetValue(data[i].Value))
                {
                    Debug.LogErrorFormat("Unable to assign the value '{0}' to the storage object '{1}'. Check storage asset is compatible with this type", data[i].Value, storage[i]);
                    storage       = null;
                    invalidDrawer = generateDrawer;
                    return(false);
                }
            }

            // Try to serialise the storage objects for display
            SerializedObject serialStorage = new SerializedObject(storage);

            valueProperty = serialStorage.FindProperty(storage[0].GetValuePropertyName());
            if (valueProperty == null)
            {
                storage       = null;
                invalidDrawer = missingSerialDrawer;
                return(false);
            }

            // If got this far, valid
            return(true);
        }
예제 #4
0
        /*----------Functions----------*/
        //PRIVATE

        /// <summary>
        /// Identify the object elements within the currently loaded assembly for display
        /// </summary>
        static SerialDataPropertyDrawer()
        {
            // Find all of the drawer types that can be used
            Type drawerAttributeType             = typeof(CustomDataDrawerAttribute);
            TypeMarkerAttributeComparer comparer = new TypeMarkerAttributeComparer();

            dataDrawerTypes = new Dictionary <TypeMarkerAttribute, Type>(comparer);
            foreach (Type type in AssemblyTypeScanner.GetTypesWithinAssembly <IDataDrawer>())
            {
                // Look for the drawer marker attribute for use
                object[] atts = type.GetCustomAttributes(drawerAttributeType, false);
                if (atts == null || atts.Length == 0)
                {
                    continue;
                }

                // Get the attribute that will be used to identify the type it will be used for
                CustomDataDrawerAttribute att = null;
                for (int i = 0; i < atts.Length; ++i)
                {
                    att = atts[i] as CustomDataDrawerAttribute;
                    if (att != null)
                    {
                        break;
                    }
                }
                if (att == null || att.AssociatedType == null)
                {
                    continue;
                }

                // Check that this type can be created for use
                if (type.IsAbstract)
                {
                    Debug.LogErrorFormat("Unable to use Drawer type '{0}' for the type '{1}' as the drawer is abstract", type, att.AssociatedType);
                    continue;
                }
                else if (type.GetConstructor(Type.EmptyTypes) == null)
                {
                    Debug.LogErrorFormat("Unable to use Drawer type '{0}' for the type '{1}' as the drawer has no default constructor", type, att.AssociatedType);
                    continue;
                }

                // If there is an existing drawer for this type, warn of override
                if (dataDrawerTypes.ContainsKey(att))
                {
                    Debug.LogWarningFormat("Drawer Type '{0}' is overriding '{1}' for use to draw '{2}'", type, dataDrawerTypes[att], att);
                }
                dataDrawerTypes[att] = type;
            }

            // Find all of the serial storage types that can be used
            Type serialAttributeType = typeof(CustomSerialStorageAttribute);

            dataStorageTypes = new Dictionary <TypeMarkerAttribute, Type>(comparer);
            foreach (Type type in AssemblyTypeScanner.GetTypesWithinAssembly <SerialStorage>())
            {
                // Look for the storage attribute for use
                object[] atts = type.GetCustomAttributes(serialAttributeType, false);
                if (atts == null || atts.Length == 0)
                {
                    continue;
                }

                // Get the attribute that will be used to identify the type it will be used for
                CustomSerialStorageAttribute att = null;
                for (int i = 0; i < atts.Length; ++i)
                {
                    att = atts[i] as CustomSerialStorageAttribute;
                    if (att != null)
                    {
                        break;
                    }
                }
                if (att == null || att.AssociatedType == null)
                {
                    continue;
                }

                // If there is an existing storage type for the value type, warn of override
                if (dataStorageTypes.ContainsKey(att))
                {
                    Debug.LogWarningFormat("Storage Type '{0}' is overriding '{1}' for storage of type '{2}'", type, dataStorageTypes[att], att.AssociatedType);
                }
                dataStorageTypes[att] = type;
            }

            // Create the management drawer objects
            mismatchDrawer      = new TypeMismatchDataDrawer();
            nonSerialDrawer     = new NonSerialDataDrawer();
            generateDrawer      = new GenerateStorageDataDrawer();
            missingSerialDrawer = new MissingSerialPropertyDrawer();
            defaultDrawer       = new DefaultDataDrawer();
        }