-
Notifications
You must be signed in to change notification settings - Fork 241
/
Registrar.cs
executable file
·238 lines (204 loc) · 8.99 KB
/
Registrar.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/*
* 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
{
/// <summary>
/// For internal use.
/// </summary>
/// <typeparam name="TRegistrable"></typeparam>
/// 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<TRegistrable> where TRegistrable : class
{
readonly Dictionary<Type, Type> _handlers = new Dictionary<Type, Type>();
/// <summary>
/// Register.
/// </summary>
/// <param name="tview">The type of the view</param>
/// <param name="trender">The type of the render.</param>
/// 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);
}
/// <summary>
/// For internal use. Returns handler.
/// </summary>
/// <typeparam name="TOut">The type of the handler</typeparam>
/// <param name="type">The type.</param>
/// <returns>The handler instance.</returns>
/// 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<TOut>(Type type) where TOut : TRegistrable
{
return (TOut)GetHandler(type);
}
/// <summary>
/// For internal use. Returns handler.
/// </summary>
/// <typeparam name="TOut">The type of the handler</typeparam>
/// <param name="type">The type.</param>
/// <param name="args">The args of the type</param>
/// <returns>The handler instance.</returns>
/// 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<TOut>(Type type, params object[] args) where TOut : TRegistrable
{
return (TOut)GetHandler(type, args);
}
/// <summary>
/// For internal use. Return the handler of the object.
/// </summary>
/// <typeparam name="TOut">The type</typeparam>
/// <param name="obj">The object instance.</param>
/// <returns>The handle of the obj.</returns>
/// 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<TOut>(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);
}
/// <summary>
/// For internal use. Return the handler of the object.
/// </summary>
/// <typeparam name="TOut">The type</typeparam>
/// <param name="obj">The object instance</param>
/// <param name="args">The args of the type</param>
/// <returns>The handler of the object.</returns>
/// 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<TOut>(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);
}
/// <summary>
/// For internal use. Returns the handle type.
/// </summary>
/// <param name="viewType">The view type.</param>
/// <returns>The type of the handle.</returns>
/// 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<RenderWithAttribute>();
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<RenderWithAttribute>();
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;
}
/// <summary>
/// For internal use. Return the handle type of the object
/// </summary>
/// <param name="obj">The object instance.</param>
/// <returns>The type of the handler.</returns>
/// 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;
}
}
/// <summary>
/// For internal use
/// </summary>
/// 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<string, Type> Effects { get; } = new Dictionary<string, Type>();
/// 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<Assembly> ExtraAssemblies { get; set; }
}
}