static ContainerClass GetContainerInfo(Type t) { lock (_cLock) { ContainerClass cinfo; if (containerclasses.TryGetValue(t, out cinfo)) { return(cinfo); } cinfo = new ContainerClass(); var sections = new List <ReflectionSection>(); foreach (var field in t.GetFields(F_CLASSMEMBERS)) { foreach (var attr in field.GetCustomAttributes <SectionAttribute>()) { var s = new ReflectionSection() { Name = attr.Name }; s.AttachToParent = attr.Child; var fieldType = field.FieldType; //Handle lists if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(List <>)) { fieldType = fieldType.GetGenericArguments()[0]; // use this... s.IsList = true; } if (attr.Type != null) { s.Type = GetSectionInfo(attr.Type); } else { if (fieldType.IsAbstract) { throw new Exception(t.Name + " section " + attr.Name + " inits abstract class " + fieldType.Name); } s.Type = GetSectionInfo(fieldType); } s.Field = field; s.Delimiters = attr.Delimiters; sections.Add(s); } } foreach (var attr in t.GetCustomAttributes <SelfSectionAttribute>()) { var s = new ReflectionSection() { Name = attr.Name }; s.Type = GetSectionInfo(t); sections.Add(s); } cinfo.Sections = sections.ToArray(); cinfo.SectionHashes = new uint[cinfo.Sections.Length]; for (int i = 0; i < cinfo.SectionHashes.Length; i++) { cinfo.SectionHashes[i] = Hash(cinfo.Sections[i].Name); } return(cinfo); } }
static ReflectionInfo GetSectionInfo(Type t) { lock (_sLock) { ReflectionInfo info; if (sectionclasses.TryGetValue(t, out info)) { return(info); } info = new ReflectionInfo() { Type = t }; foreach (var field in t.GetFields(F_CLASSMEMBERS)) { var attrs = field.GetCustomAttributes <EntryAttribute>(); foreach (var a in attrs) { info.Fields.Add(new ReflectionField() { Attr = a, Field = field, NullableType = Nullable.GetUnderlyingType(field.FieldType) }); if (a.Required) { info.RequiredFields |= (1ul << (info.Fields.Count - 1)); } } foreach (var attr in field.GetCustomAttributes <SectionAttribute>()) { if (!attr.Child) { continue; } var fieldType = field.FieldType; //Handle lists if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(List <>)) { var s = new ReflectionSection() { Name = attr.Name }; s.Field = field; s.IsList = true; info.ChildSections.Add(s); } else { throw new Exception("Child sections can only be lists"); } } } //This should never be tripped if (info.Fields.Count > 64) { throw new Exception("Too many fields!! Edit bitmask code & raise limit"); } info.FieldHashes = new uint[info.Fields.Count]; for (int i = 0; i < info.Fields.Count; i++) { info.FieldHashes[i] = Hash(info.Fields[i].Attr.Name); } sectionclasses.Add(t, info); return(info); } }