/* * Copyright(c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Reflection; namespace Tizen.NUI.Binding.Internals { /// /// For internal use. /// /// /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public class Registrar where TRegistrable : class { readonly Dictionary _handlers = new Dictionary(); /// /// Register. /// /// The type of the view /// The type of the render. /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public void Register(Type tview, Type trender) { //avoid caching null renderers if (trender == null) return; _handlers[tview] = trender; } internal TRegistrable GetHandler(Type type) { Type handlerType = GetHandlerType(type); if (handlerType == null) return null; object handler = DependencyResolver.ResolveOrCreate(handlerType); return (TRegistrable)handler; } internal TRegistrable GetHandler(Type type, params object[] args) { if (args.Length == 0) { return GetHandler(type); } Type handlerType = GetHandlerType(type); if (handlerType == null) return null; return (TRegistrable)DependencyResolver.ResolveOrCreate(handlerType, args); } /// /// For internal use. Returns handler. /// /// The type of the handler /// The type. /// The handler instance. /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public TOut GetHandler(Type type) where TOut : TRegistrable { return (TOut)GetHandler(type); } /// /// For internal use. Returns handler. /// /// The type of the handler /// The type. /// The args of the type /// The handler instance. /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public TOut GetHandler(Type type, params object[] args) where TOut : TRegistrable { return (TOut)GetHandler(type, args); } /// /// For internal use. Return the handler of the object. /// /// The type /// The object instance. /// The handle of the obj. /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public TOut GetHandlerForObject(object obj) where TOut : TRegistrable { if (obj == null) throw new ArgumentNullException(nameof(obj)); var reflectableType = obj as IReflectableType; var type = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : obj.GetType(); return (TOut)GetHandler(type); } /// /// For internal use. Return the handler of the object. /// /// The type /// The object instance /// The args of the type /// The handler of the object. /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public TOut GetHandlerForObject(object obj, params object[] args) where TOut : TRegistrable { if (obj == null) throw new ArgumentNullException(nameof(obj)); var reflectableType = obj as IReflectableType; var type = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : obj.GetType(); return (TOut)GetHandler(type, args); } /// /// For internal use. Returns the handle type. /// /// The view type. /// The type of the handle. /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public Type GetHandlerType(Type viewType) { Type type; if (LookupHandlerType(viewType, out type)) return type; // lazy load render-view association with RenderWithAttribute (as opposed to using ExportRenderer) var attribute = viewType.GetTypeInfo().GetCustomAttribute(); if (attribute == null) { Register(viewType, null); // Cache this result so we don't have to do GetCustomAttribute again return null; } type = attribute.Type; if (type.Name.StartsWith("_", StringComparison.Ordinal)) { // TODO: Remove attribute2 once renderer names have been unified across all platforms var attribute2 = type.GetTypeInfo().GetCustomAttribute(); if (attribute2 != null) type = attribute2.Type; if (type.Name.StartsWith("_", StringComparison.Ordinal)) { Register(viewType, null); // Cache this result so we don't work through this chain again return null; } } Register(viewType, type); // Register this so we don't have to look for the RenderWith Attribute again in the future return type; } /// /// For internal use. Return the handle type of the object /// /// The object instance. /// The type of the handler. /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public Type GetHandlerTypeForObject(object obj) { if (obj == null) throw new ArgumentNullException(nameof(obj)); var reflectableType = obj as IReflectableType; var type = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : obj.GetType(); return GetHandlerType(type); } bool LookupHandlerType(Type viewType, out Type handlerType) { Type type = viewType; while (type != null) { if (_handlers.ContainsKey(type)) { handlerType = _handlers[type]; return true; } type = type.GetTypeInfo().BaseType; } handlerType = null; return false; } } /// /// For internal use /// /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static class Registrar { static Registrar() { } internal static Dictionary Effects { get; } = new Dictionary(); /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static IEnumerable ExtraAssemblies { get; set; } } }