private static T LoadComponents <T>(T value, Type type, IImportProvider ip, LoadMethodFunction methodFn, LoadFieldFunction <T> fieldFn = null) { (MemberInfo[] members, ImportAttribute[] attributes) = type.GetAnnotated <ImportAttribute>(); int lim = attributes.Length; if (lim == default) { return(value); } for (int i = 0; i < lim; i++) { var attr = attributes[i]; var mem = members[i]; // Resolve the symbol string id = ResolveIdentifier(attr, mem); Pointer <byte> addr = ip.GetAddress(id); switch (mem.MemberType) { case MemberTypes.Property: var propInfo = (PropertyInfo)mem; var get = propInfo.GetMethod; methodFn(attr, get, addr); break; case MemberTypes.Method: // The import is a function or (ctor) methodFn(attr, (MethodInfo)mem, addr); break; case MemberTypes.Field: fieldFn?.Invoke(ref value, ip, id, (MetaField)mem, attr); break; default: throw Guard.NotSupportedMemberFail(mem); } Global.Value.WriteVerbose(null, "Loaded member {Id} @ {Addr}", id, addr); } return(value); }
private void LoadField <T>(ref T value, IImportProvider ip, string identifier, MetaField field, ImportAttribute attr) { var ifld = (ImportFieldAttribute)attr; Pointer <byte> ptr = ip.GetAddress(identifier); var options = ifld.FieldOptions; Pointer <byte> fieldAddr = field.GetValueAddress(ref value); object fieldValue; Global.Value.WriteDebug(Id, "Loading field {Id} with {Option}", field.Name, options); switch (options) { case ImportFieldOptions.CopyIn: fieldValue = CopyInField(ifld, field, ptr); break; case ImportFieldOptions.Proxy: fieldValue = ProxyLoadField(ifld, field, ptr); break; case ImportFieldOptions.Fast: FastLoadField(field, ptr, fieldAddr); return; default: throw new ArgumentOutOfRangeException(); } if (field.FieldType.IsAnyPointer) { ptr.WritePointer((Pointer <byte>)fieldValue); } else { ptr.WriteAny(field.FieldType.RuntimeType, fieldValue); } }