- #if !DEBUG || PROFILER
- #define DISABLE_CHECKS
- using System.Diagnostics;
- #endif
- using System;
- using System.Reflection;
-
- namespace Svelto.ECS
- {
- internal static class EntityBuilderUtilities
- {
- const string MSG = "Entity Structs field and Entity View Struct components must hold value types.";
-
-
- #if DISABLE_CHECKS
- [Conditional("_CHECKS_DISABLED")]
- #endif
- public static void CheckFields(Type entityStructType, bool needsReflection, bool isStringAllowed = false)
- {
- if (entityStructType == ENTITY_STRUCT_INFO_VIEW ||
- entityStructType == EGIDType ||
- entityStructType == EXCLUSIVEGROUPSTRUCTTYPE ||
- entityStructType == SERIALIZABLE_ENTITY_STRUCT)
- {
- return;
- }
-
- if (needsReflection == false)
- {
- if (entityStructType.IsClass)
- {
- throw new EntityStructException("EntityStructs must be structs.", entityStructType);
- }
-
- FieldInfo[] fields = entityStructType.GetFields(BindingFlags.Public | BindingFlags.Instance);
-
- for (var i = fields.Length - 1; i >= 0; --i)
- {
- FieldInfo fieldInfo = fields[i];
- Type fieldType = fieldInfo.FieldType;
-
- SubCheckFields(fieldType, entityStructType, isStringAllowed);
- }
- }
- else
- {
- FieldInfo[] fields = entityStructType.GetFields(BindingFlags.Public | BindingFlags.Instance);
-
- if (fields.Length < 1)
- {
- ProcessError("Entity View Structs must hold only entity components interfaces.", entityStructType);
- }
-
- for (int i = fields.Length - 1; i >= 0; --i)
- {
- FieldInfo fieldInfo = fields[i];
-
- if (fieldInfo.FieldType.IsInterfaceEx() == false)
- {
- ProcessError("Entity View Structs must hold only entity components interfaces.",
- entityStructType);
- }
-
- PropertyInfo[] properties = fieldInfo.FieldType.GetProperties(
- BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
-
- for (int j = properties.Length - 1; j >= 0; --j)
- {
- if (properties[j].PropertyType.IsGenericType)
- {
- Type genericTypeDefinition = properties[j].PropertyType.GetGenericTypeDefinition();
- if (genericTypeDefinition == DISPATCHONSETTYPE ||
- genericTypeDefinition == DISPATCHONCHANGETYPE)
- {
- continue;
- }
- }
-
- Type propertyType = properties[j].PropertyType;
- if (propertyType != STRINGTYPE)
- {
- //for EntityViewStructs, component fields that are structs that hold strings
- //are allowed
- SubCheckFields(propertyType, entityStructType, isStringAllowed: true);
- }
- }
- }
- }
- }
-
- static void SubCheckFields(Type fieldType, Type entityStructType, bool isStringAllowed = false)
- {
- if (fieldType.IsPrimitive || fieldType.IsValueType || (isStringAllowed == true && fieldType == STRINGTYPE))
- {
- if (fieldType.IsValueType && !fieldType.IsEnum && fieldType.IsPrimitive == false)
- {
- CheckFields(fieldType, false, isStringAllowed);
- }
-
- return;
- }
-
- ProcessError(MSG, entityStructType, fieldType);
- }
-
- static void ProcessError(string message, Type entityViewType, Type fieldType = null)
- {
- if (fieldType != null)
- {
- throw new EntityStructException(message, entityViewType, fieldType);
- }
-
- throw new EntityStructException(message, entityViewType);
- }
-
- static readonly Type DISPATCHONCHANGETYPE = typeof(DispatchOnChange<>);
- static readonly Type DISPATCHONSETTYPE = typeof(DispatchOnSet<>);
- static readonly Type EGIDType = typeof(EGID);
- static readonly Type EXCLUSIVEGROUPSTRUCTTYPE = typeof(ExclusiveGroup.ExclusiveGroupStruct);
- static readonly Type SERIALIZABLE_ENTITY_STRUCT = typeof(SerializableEntityStruct);
- static readonly Type STRINGTYPE = typeof(string);
-
- internal static readonly Type ENTITY_STRUCT_INFO_VIEW = typeof(EntityStructInfoView);
- }
-
- public class EntityStructException : Exception
- {
- public EntityStructException(string message, Type entityViewType, Type type) :
- base(message.FastConcat(" entity view: '", entityViewType.ToString(), "', field: '", type.ToString()))
- {
- }
-
- public EntityStructException(string message, Type entityViewType) :
- base(message.FastConcat(" entity view: ", entityViewType.ToString()))
- {
- }
- }
- }
|