internal static void RegisterManagedClass(IntPtr classAddress, Type type) { UClass existingClass; if (classes.TryGetValue(type, out existingClass)) { classes.Remove(type); classesByAddress.Remove(existingClass.Address); } seenClasses.Remove(type); classesByAddress[classAddress] = type; UClass unrealClass = GCHelper.Find <UClass>(classAddress); if (unrealClass != null) { classes[type] = unrealClass; } else { classesByAddress.Remove(classAddress); } // If this is an interface add it to UnrealInterfacePool so that we can create instances of this // interface which are implemented in Blueprint if (type.IsInterface) { UnrealInterfacePool.LoadType(type); } }
public unsafe T GetInterface <T>() where T : class, IInterface { T result = this as T; if (result != null) { return(result); } if (injectedInterfaces == null) { // If the injected interfaces haven't been set up set them up now if (objRef == null) { return(null); } UClass unrealClass = GetClass(); if (unrealClass as USharpClass != null) { // This is a C# defined type. We know if it implements the target interface or not due to the // above "this as T". There isn't any need to inject interfaces into the UObject. return(null); } FScriptArray *interfacesPtr = (FScriptArray *)Native_UClass.Get_InterfacesRef(unrealClass.Address); if (interfacesPtr->ArrayNum != 0) { injectedInterfaces = new Dictionary <Type, IInterface>(); foreach (FImplementedInterface implementedInterface in unrealClass.Interfaces) { if (implementedInterface.InterfaceClassAddress != IntPtr.Zero) { Type type = UClass.GetTypeFromClassAddress(implementedInterface.InterfaceClassAddress); if (type != null) { IInterface instance = UnrealInterfacePool.New(type, objRef); if (instance != null) { injectedInterfaces[type] = instance; if (type == typeof(T)) { result = instance as T; } } } } } } } else { // Try and get the interface from the injected interfaces. IInterface instance; injectedInterfaces.TryGetValue(typeof(T), out instance); result = instance as T; } return(result); }
private void ReleaseInjectedInterfaces() { if (injectedInterfaces != null) { foreach (IInterface instance in injectedInterfaces.Values) { UnrealInterfacePool.ReturnObject(instance); } injectedInterfaces = null; } }
/// <summary> /// Loads underlying native type info for the given generated type (types tagged with UMetaPath) /// This loads the class address/properties/functions/offsets /// </summary> private static void LoadNative(Type type, UMetaPathAttribute pathAttribute) { UnrealInterfacePool.LoadType(type); bool lazyLoad = LazyLoadingEnabled && !HasCCtorBeenCalled(type); if (!lazyLoad) { // If this is an interface get the default implementation type which will hold the loader method Type targetType = type; if (pathAttribute.InterfaceImpl != null) { targetType = pathAttribute.InterfaceImpl; } MethodInfo method = targetType.GetMethod(CodeGeneratorSettings.LoadNativeTypeMethodName, BindingFlags.Static | BindingFlags.NonPublic); if (method != null) { method.Invoke(null, null); } } }