// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace HoloToolkit.Sharing.SyncModel { /// <summary> /// Collection of sharing sync settings, used by the HoloToolkit Sharing sync system /// to figure out which data model classes need to be instantiated when receiving /// data that inherits from SyncObject. /// </summary> public class SyncSettings { #if UNITY_WSA && !UNITY_EDITOR private readonly Dictionary<TypeInfo, string> dataModelTypeToName = new Dictionary<TypeInfo, string>(); private readonly Dictionary<string, TypeInfo> dataModelNameToType = new Dictionary<string, TypeInfo>(); #else private readonly Dictionary<Type, string> dataModelTypeToName = new Dictionary<Type, string>(); private readonly Dictionary<string, Type> dataModelNameToType = new Dictionary<string, Type>(); #endif private static SyncSettings instance; public static SyncSettings Instance { get { if (instance == null) { instance = new SyncSettings(); } return instance; } } public string GetDataModelName(Type type) { var typeInfo = type.GetTypeInfo(); string retVal; dataModelTypeToName.TryGetValue(typeInfo, out retVal); return retVal; } #if UNITY_WSA && !UNITY_EDITOR public TypeInfo GetDataModelType(string name) { TypeInfo retVal; #else public Type GetDataModelType(string name) { Type retVal; #endif dataModelNameToType.TryGetValue(name, out retVal); return retVal; } public void Initialize() { dataModelNameToType.Clear(); dataModelTypeToName.Clear(); foreach (var assembly in GetAssemblies()) { // We currently skip all assemblies except Unity-generated ones // This could be modified to be customizable by the user if (!assembly.FullName.StartsWith("Assembly-")) { continue; } #if UNITY_WSA && !UNITY_EDITOR foreach (TypeInfo type in assembly.GetTypes()) #else foreach (Type type in assembly.GetTypes()) #endif { object customAttribute = type.GetCustomAttributes(typeof(SyncDataClassAttribute), false).FirstOrDefault(); SyncDataClassAttribute attribute = customAttribute as SyncDataClassAttribute; if (attribute != null) { string dataModelName = type.Name; // Override the class name if provided if (!string.IsNullOrEmpty(attribute.CustomClassName)) { dataModelName = attribute.CustomClassName; } dataModelNameToType.Add(dataModelName, type); dataModelTypeToName.Add(type, dataModelName); } } } } private static Assembly[] GetAssemblies() { #if UNITY_WSA && !UNITY_EDITOR return new Assembly[] { typeof(SyncSettings).GetTypeInfo().Assembly }; #else return AppDomain.CurrentDomain.GetAssemblies(); #endif } } }