public void OnActive()
{
- if (null != childOp && childOp.ValueList.Count > 2 && (childOp.ValueList[0] is Instance instance) && (childOp.ValueList[1] is Instance child))
+ if (null != childOp && childOp.ValueList.Count > 2 && (childOp.ValueList[0] is Instance instance))
{
int parentIndex = instance.Index;
- int childIndex = child.Index;
+ var child = childOp.ValueList[1];
int methodIndex = (int)childOp.ValueList[2];
- globalDataList.Operations.Add(new CallAddMethod(globalDataList, parentIndex, childIndex, methodIndex));
+ globalDataList.Operations.Add(new CallAddMethod(globalDataList, parentIndex, child, methodIndex));
}
}
}
--- /dev/null
+/*
+ * 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.Text;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Binding.Internals;
+
+namespace Tizen.NUI.EXaml
+{
+ internal class OtherActions : Action
+ {
+ internal OtherActions(GlobalDataList globalDataList, Action parent)
+ {
+ this.parent = parent;
+ this.globalDataList = globalDataList;
+ }
+
+ private Action parent;
+ private GlobalDataList globalDataList;
+
+ public Action DealChar(char c)
+ {
+ switch (c)
+ {
+ case ' ':
+ case '\n':
+ case '\r':
+ break;
+
+ case 'a':
+ parent?.OnActive();
+ return parent;
+
+ case '(':
+ getValues = new GetValueListAction(')', this);
+ return getValues;
+ }
+
+ return this;
+ }
+
+ public void Init()
+ {
+ }
+
+ public void OnActive()
+ {
+ if (null != getValues)
+ {
+ int index = (int)getValues.ValueList[0];
+
+ switch (index)
+ {
+ case 0:
+ int typeIndex = (int)getValues.ValueList[1];
+ var items = getValues.ValueList[2] as List<object>;
+ var createArrayInstanceOp = new CreateArrayInstance(globalDataList, typeIndex, items);
+ globalDataList.Operations.Add(createArrayInstanceOp);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ getValues = null;
+ }
+
+ private GetValueListAction getValues;
+ }
+}
public void OnActive()
{
var readedAssemblyName = childOp.Value as string;
- globalDataList.Operations.Add(new GatherAssembly(globalDataList, readedAssemblyName));
+ globalDataList.PreLoadOperations.Add(new GatherAssembly(globalDataList, readedAssemblyName));
childOp = null;
}
}
int typeIndex = int.Parse(childOp.ValueList[0] as string);
string propertyName = childOp.ValueList[1] as string;
- globalDataList.Operations.Add(new GatherBindableProperties(globalDataList, typeIndex, propertyName));
+ globalDataList.PreLoadOperations.Add(new GatherBindableProperties(globalDataList, typeIndex, propertyName));
}
}
}
int typeIndex = int.Parse(childOp.ValueList[0] as string);
string eventName = childOp.ValueList[1] as string;
- globalDataList.Operations.Add(new GatherEvent(globalDataList, typeIndex, eventName));
+ globalDataList.PreLoadOperations.Add(new GatherEvent(globalDataList, typeIndex, eventName));
}
}
}
int typeIndex = int.Parse(childOp.ValueList[0] as string);
string name = childOp.ValueList[1] as string;
var paramList = childOp.ValueList[2] as List<object>;
- globalDataList.Operations.Add(new GatherMethod(globalDataList, typeIndex, name, paramList));
+ globalDataList.PreLoadOperations.Add(new GatherMethod(globalDataList, typeIndex, name, paramList));
}
}
}
int typeIndex = int.Parse(childOp.ValueList[0] as string);
string propertyName = childOp.ValueList[1] as string;
- globalDataList.Operations.Add(new GatherProperty(globalDataList, typeIndex, propertyName));
+ globalDataList.PreLoadOperations.Add(new GatherProperty(globalDataList, typeIndex, propertyName));
}
}
}
public void OnActive()
{
- globalDataList.Operations.Add(GatherType(childOp.ValueList));
+ globalDataList.PreLoadOperations.Add(GatherType(childOp.ValueList));
childOp = null;
}
{
internal class GlobalDataList
{
+ internal List<Operation> PreLoadOperations
+ {
+ get;
+ } = new List<Operation>();
+
internal List<Operation> Operations
{
get;
{
internal static class LoadEXaml
{
- internal static void Load(object view, string xaml)
+ internal static GlobalDataList GatherDataList(string xaml)
{
var globalDataList = new GlobalDataList();
- CreateInstanceAction.Root = view;
-
int index = 0;
var createInstance = new CreateInstanceAction(globalDataList, null);
var setDynamicResourceAction = new SetDynamicResourceAction(globalDataList, null);
var addToResourceDictionaryAction = new AddToResourceDictionaryAction(globalDataList, null);
var setBindingAction = new SetBindingAction(globalDataList, null);
+ var otherActions = new OtherActions(globalDataList, null);
foreach (char c in xaml)
{
currentOp = setBindingAction;
currentOp.Init();
break;
+
+ case 'a':
+ currentOp = otherActions;
+ currentOp.Init();
+ break;
}
}
else
}
}
+ foreach (var op in globalDataList.PreLoadOperations)
+ {
+ op.Do();
+ }
+
+ return globalDataList;
+ }
+
+ internal static void Load(object view, string xaml)
+ {
+ var globalDataList = GatherDataList(xaml);
+
+ CreateInstanceAction.Root = view;
+
+ foreach (var op in globalDataList.Operations)
+ {
+ op.Do();
+ }
+ }
+
+ internal static void Load(object view, object preloadData)
+ {
+ var globalDataList = preloadData as GlobalDataList;
+
+ if (null == globalDataList)
+ {
+ return;
+ }
+
+ CreateInstanceAction.Root = view;
+
foreach (var op in globalDataList.Operations)
{
op.Do();
{
internal class CallAddMethod : Operation
{
- public CallAddMethod(GlobalDataList globalDataList, int parentIndex, int childIndex, int methodIndex)
+ public CallAddMethod(GlobalDataList globalDataList, int parentIndex, object child, int methodIndex)
{
this.parentIndex = parentIndex;
- this.childIndex = childIndex;
+ this.child = child;
this.methodIndex = methodIndex;
this.globalDataList = globalDataList;
}
public void Do()
{
object parent = globalDataList.GatheredInstances[parentIndex];
- object child = globalDataList.GatheredInstances[childIndex];
var method = globalDataList.GatheredMethods[methodIndex];
+ if (child is Instance)
+ {
+ child = globalDataList.GatheredInstances[(child as Instance).Index];
+ }
+
method.Invoke(parent, new object[] { child });
}
private int parentIndex;
- private int childIndex;
+ private object child;
private int methodIndex;
}
}
--- /dev/null
+/*
+ * 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;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Binding.Internals;
+using Tizen.NUI.Xaml;
+
+namespace Tizen.NUI.EXaml
+{
+ internal class CreateArrayInstance : Operation
+ {
+ public CreateArrayInstance(GlobalDataList globalDataList, int typeIndex, List<object> items)
+ {
+ this.typeIndex = typeIndex;
+ this.items = items;
+ this.globalDataList = globalDataList;
+ }
+
+ private GlobalDataList globalDataList;
+
+ public void Do()
+ {
+ var type = globalDataList.GatheredTypes[typeIndex];
+ var array = Array.CreateInstance(type, items.Count);
+
+ for (int i = 0; i < items.Count; i++)
+ {
+ if (items[i] is Instance instance)
+ {
+ ((IList)array)[i] = globalDataList.GatheredInstances[instance.Index];
+ }
+ }
+
+ globalDataList.GatheredInstances.Add(array);
+ }
+
+ private int typeIndex;
+ private List<object> items;
+ }
+}
{
var property = globalDataList.GatheredBindableProperties[bindalbePropertyIndex];
- if (value is Instance)
+ if (value is Instance valueInstance)
{
- int valueIndex = (value as Instance).Index;
- instance.SetValue(property, globalDataList.GatheredInstances[valueIndex]);
- }
- else
- {
- instance.SetValue(property, value);
+ int valueIndex = valueInstance.Index;
+ value = globalDataList.GatheredInstances[valueIndex];
}
+
+ instance.SetValue(property, value);
}
}
if (null == property)
{
- throw new Exception(String.Format("Can't find property in type {0}", instance.GetType().FullName));
+ throw new Exception(String.Format("Can't find property {0} in type {1}", property.Name, instance.GetType().FullName));
}
if (null == property.SetMethod)
throw new Exception(String.Format("Property {0} hasn't set method", property.Name));
}
- if (value is Instance)
+ if (value is Instance valueInstance)
{
- int valueIndex = (value as Instance).Index;
- object realValue = globalDataList.GatheredInstances[valueIndex];
+ int valueIndex = valueInstance.Index;
+ value = globalDataList.GatheredInstances[valueIndex];
- if (null == realValue)
+ if (null == value)
{
throw new Exception(String.Format("Can't get instance of value by index {0}", valueIndex));
}
-
- property.SetMethod.Invoke(instance, new object[] { realValue });
- }
- else
- {
- property.SetMethod.Invoke(instance, new object[] { value });
}
+
+ property.SetMethod.Invoke(instance, new object[] { value });
}
private int instanceIndex;
};
var mi = nodeType.GetRuntimeMethods().FirstOrDefault(isMatch);
if (mi == null)
+ {
+ if (node is ElementNode elementNode)
+ {
+ var nodeTypeExtension = XamlParser.GetElementTypeExtension(node.XmlType, elementNode, Context.RootElement?.GetType().GetTypeInfo().Assembly);
+ mi = nodeTypeExtension?.GetRuntimeMethods().FirstOrDefault(isMatch);
+ }
+ }
+
+ if (mi == null)
+ {
throw new MissingMemberException($"No static method found for {nodeType.FullName}::{factoryMethod} ({string.Join(", ", types.Select(t => t.FullName))})");
+ }
+
return mi.Invoke(null, arguments);
}
return type;
}
+
+ public static Type GetElementTypeExtension(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly)
+ {
+ if (s_xmlnsDefinitions == null)
+ GatherXmlnsDefinitionAttributes(currentAssembly);
+
+ var namespaceURI = xmlType.NamespaceUri;
+ var elementName = xmlType.Name;
+ var typeArguments = xmlType.TypeArguments;
+
+ if (elementName.Contains("-"))
+ {
+ elementName = elementName.Replace('-', '+');
+ }
+
+ var lookupAssemblies = new List<XmlnsDefinitionAttribute>();
+ var lookupNames = new List<string>();
+
+ foreach (var xmlnsDef in s_xmlnsDefinitions)
+ {
+ if (xmlnsDef.XmlNamespace != namespaceURI)
+ continue;
+ lookupAssemblies.Add(xmlnsDef);
+ }
+
+ if (lookupAssemblies.Count == 0)
+ {
+ string ns, asmstring, _;
+ XmlnsHelper.ParseXmlns(namespaceURI, out _, out ns, out asmstring);
+ lookupAssemblies.Add(new XmlnsDefinitionAttribute(namespaceURI, ns)
+ {
+ AssemblyName = asmstring ?? currentAssembly.FullName
+ });
+ }
+
+ lookupNames.Add(elementName + "Extension");
+
+ for (var i = 0; i < lookupNames.Count; i++)
+ {
+ var name = lookupNames[i];
+ if (name.Contains(":"))
+ name = name.Substring(name.LastIndexOf(':') + 1);
+ if (typeArguments != null)
+ name += "`" + typeArguments.Count; //this will return an open generic Type
+ lookupNames[i] = name;
+ }
+
+ Type type = null;
+ foreach (var asm in lookupAssemblies)
+ {
+ foreach (var name in lookupNames)
+ {
+ if ((type = Type.GetType($"{asm.ClrNamespace}.{name}, {asm.AssemblyName}")) != null)
+ break;
+
+ if ((type = currentAssembly.GetType($"{asm.ClrNamespace}.{name}")) != null)
+ {
+ break;
+ }
+
+ if ('?' == name.Last())
+ {
+ string nameOfNotNull = name.Substring(0, name.Length - 1);
+ Type typeofNotNull = Type.GetType($"{asm.ClrNamespace}.{nameOfNotNull}, {asm.AssemblyName}");
+
+ if (null != typeofNotNull)
+ {
+ type = typeof(Nullable<>).MakeGenericType(new Type[] { typeofNotNull });
+ break;
+ }
+ }
+ }
+
+ if (type != null)
+ break;
+ }
+
+ if (type != null && typeArguments != null)
+ {
+ XamlParseException innerexception = null;
+ var args = typeArguments.Select(delegate (XmlType xmltype)
+ {
+ XamlParseException xpe;
+ var t = GetElementType(xmltype, xmlInfo, currentAssembly, out xpe);
+ if (xpe != null)
+ {
+ innerexception = xpe;
+ return null;
+ }
+ return t;
+ }).ToArray();
+ if (innerexception != null)
+ {
+ return null;
+ }
+ type = type.MakeGenericType(args);
+ }
+
+ return type;
+ }
}
}
return view;
}
+ /// Internal used, will never be opened.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static T LoadFromEXamlByRelativePath<T>(this T view, string eXamlPath)
+ {
+ if (null == eXamlPath)
+ {
+ return view;
+ }
+
+ MainAssembly = view.GetType().Assembly;
+
+ string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
+
+ Tizen.Log.Fatal("NUI", "the resource path: " + resource);
+ int windowWidth = NUIApplication.GetDefaultWindow().Size.Width;
+ int windowHeight = NUIApplication.GetDefaultWindow().Size.Height;
+
+ string likelyResourcePath = resource + eXamlPath;
+
+ //Find the xaml file in the layout folder
+ if (File.Exists(likelyResourcePath))
+ {
+ StreamReader reader = new StreamReader(likelyResourcePath);
+ var xaml = reader.ReadToEnd();
+ reader.Close();
+ reader.Dispose();
+
+ LoadEXaml.Load(view, xaml);
+ }
+ else
+ {
+ throw new Exception($"Can't find examl file {eXamlPath}");
+ }
+
+ return view;
+ }
+
/// Used for TCT and TC coverage, will never be opened.
[EditorBrowsable(EditorBrowsableState.Never)]
public static T LoadFromEXaml<T>(this T view, string eXamlStr)