public static bool Generate(Type type, TemplateSettings templateSettings) { templateSettings.resourceManager = new ResourceManager(); // Stopwatch stopwatch = new Stopwatch(); // stopwatch.Start(); CompiledTemplateData compiledTemplateData = TemplateCompiler.CompileTemplates(type, templateSettings); // stopwatch.Stop(); // UnityEngine.Debug.Log("Compiled Templates in " + stopwatch.Elapsed.Milliseconds + "ms"); string path = templateSettings.outputPath; string extension = templateSettings.codeFileExtension; if (extension[0] != '.') { extension = "." + extension; } if (Directory.Exists(path)) { Directory.Delete(path, true); } Directory.CreateDirectory(path); string styleFilePaths = GenerateStyleCode(compiledTemplateData); GenerateTemplateCode(path, extension, compiledTemplateData); GenerateInitCode(path, extension, compiledTemplateData, styleFilePaths); return(true); }
public static CompiledTemplateData LoadRuntimeTemplates(Type type, TemplateSettings templateSettings) { CompiledTemplateData compiledTemplateData = TemplateCompiler.CompileTemplates(type, templateSettings); // Stopwatch stopwatch = Stopwatch.StartNew(); Func <UIElement, TemplateScope, UIElement>[] templates = new Func <UIElement, TemplateScope, UIElement> [compiledTemplateData.compiledTemplates.size]; Action <UIElement, UIElement>[] bindings = new Action <UIElement, UIElement> [compiledTemplateData.compiledBindings.size]; Func <UIElement, UIElement, TemplateScope, UIElement>[] slots = new Func <UIElement, UIElement, TemplateScope, UIElement> [compiledTemplateData.compiledSlots.size]; TemplateMetaData[] templateMetaData = new TemplateMetaData[compiledTemplateData.compiledTemplates.size]; OrderablePartitioner <Tuple <int, int> > partition; if (templateMetaData.Length < 10) { for (int i = 0; i < templateMetaData.Length; i++) { templates[i] = (Func <UIElement, TemplateScope, UIElement>)compiledTemplateData.compiledTemplates[i].templateFn.Compile(); } } else { partition = Partitioner.Create(0, templateMetaData.Length); Parallel.ForEach(partition, (range, loopState) => { for (int i = range.Item1; i < range.Item2; i++) { templates[i] = (Func <UIElement, TemplateScope, UIElement>)compiledTemplateData.compiledTemplates[i].templateFn.Compile(); } }); } if (compiledTemplateData.compiledSlots.size < 10) { for (int i = 0; i < compiledTemplateData.compiledSlots.size; i++) { slots[i] = (Func <UIElement, UIElement, TemplateScope, UIElement>)compiledTemplateData.compiledSlots[i].templateFn.Compile(); } } else { partition = Partitioner.Create(0, compiledTemplateData.compiledSlots.size); Parallel.ForEach(partition, (range, loopState) => { for (int i = range.Item1; i < range.Item2; i++) { slots[i] = (Func <UIElement, UIElement, TemplateScope, UIElement>)compiledTemplateData.compiledSlots[i].templateFn.Compile(); } }); } if (bindings.Length < 10) { for (int i = 0; i < bindings.Length; i++) { try { bindings[i] = (Action <UIElement, UIElement>)compiledTemplateData.compiledBindings[i].bindingFn.Compile(); } catch (Exception e) { Debug.Log("binding " + compiledTemplateData.compiledBindings[i].bindingFn.ToCSharpCode()); Debug.Log(e); } } } else { partition = Partitioner.Create(0, bindings.Length); Parallel.ForEach(partition, (range, loopState) => { for (int i = range.Item1; i < range.Item2; i++) { try { bindings[i] = (Action <UIElement, UIElement>)compiledTemplateData.compiledBindings[i].bindingFn.Compile(); } catch (Exception e) { Debug.Log("binding " + compiledTemplateData.compiledBindings[i].bindingFn.ToCSharpCode()); Debug.Log(e); } } }); } LightList <UIStyleGroupContainer> styleList = new LightList <UIStyleGroupContainer>(128); StyleSheet[] sheets = compiledTemplateData.styleImporter.GetImportedStyleSheets(); for (int i = 0; i < sheets.Length; i++) { StyleSheet sheet = sheets[i]; styleList.EnsureAdditionalCapacity(sheet.styleGroupContainers.Length); for (int j = 0; j < sheet.styleGroupContainers.Length; j++) { styleList.array[styleList.size++] = sheet.styleGroupContainers[j]; } } for (int i = 0; i < templateMetaData.Length; i++) { templateMetaData[i] = compiledTemplateData.compiledTemplates[i].templateMetaData; templateMetaData[i].styleMap = styleList.array; templateMetaData[i].BuildSearchMap(); } Dictionary <int, Func <ConstructedElement> > constructorFnMap = new Dictionary <int, Func <ConstructedElement> >(37); ConstructorInfo constructedTypeCtor = typeof(ConstructedElement).GetConstructor(new Type[] { typeof(int), typeof(UIElement) }); System.Diagnostics.Debug.Assert(constructedTypeCtor != null, nameof(constructedTypeCtor) + " != null"); Expression[] parameters = new Expression[2]; // todo -- this can be improved, cannot currently parallelize because the write target (constructorFnMap) is a dictionary which is not threadsafe // can convert the constructorFnMap to an array but would need a unique index for each type that is sequential foreach (KeyValuePair <Type, ProcessedType> kvp in TypeProcessor.typeMap) { if (kvp.Key.IsAbstract || kvp.Value.references == 0 || kvp.Value.id < 0) { continue; } ConstructorInfo ctor = kvp.Key.GetConstructor(Type.EmptyTypes); if (ctor == null) { throw new CompileException(kvp.Key + " must provide a default constructor in order to be used in templates"); } parameters[0] = Expression.Constant(compiledTemplateData.GetTagNameId(kvp.Value.tagName)); parameters[1] = Expression.New(ctor); Func <ConstructedElement> constructorFn = Expression.Lambda <Func <ConstructedElement> >(Expression.New(constructedTypeCtor, parameters)).Compile(); constructorFnMap[kvp.Value.id] = constructorFn; GCHandle.Alloc(constructorFn); } compiledTemplateData.bindings = bindings; compiledTemplateData.slots = slots; compiledTemplateData.templates = templates; compiledTemplateData.templateMetaData = templateMetaData; compiledTemplateData.constructorFnMap = constructorFnMap; compiledTemplateData.constructElement = (typeId) => compiledTemplateData.constructorFnMap[typeId].Invoke(); // stopwatch.Stop(); // Debug.Log("Loaded UIForia templates in " + stopwatch.Elapsed.TotalSeconds.ToString("F2") + " seconds"); return(compiledTemplateData); }
public static CompiledTemplateData LoadRuntimeTemplates(Type type, TemplateSettings templateSettings) { CompiledTemplateData compiledTemplateData = TemplateCompiler.CompileTemplates(type, templateSettings); // Stopwatch stopwatch = Stopwatch.StartNew(); Func <UIElement, TemplateScope, UIElement>[] templates = new Func <UIElement, TemplateScope, UIElement> [compiledTemplateData.compiledTemplates.size]; Action <UIElement, UIElement>[] bindings = new Action <UIElement, UIElement> [compiledTemplateData.compiledBindings.size]; Func <UIElement, UIElement, TemplateScope, UIElement>[] slots = new Func <UIElement, UIElement, TemplateScope, UIElement> [compiledTemplateData.compiledSlots.size]; TemplateMetaData[] templateMetaData = new TemplateMetaData[compiledTemplateData.compiledTemplates.size]; OrderablePartitioner <Tuple <int, int> > partition; if (templateMetaData.Length < 10) { for (int i = 0; i < templateMetaData.Length; i++) { templates[i] = (Func <UIElement, TemplateScope, UIElement>)compiledTemplateData.compiledTemplates[i].templateFn.Compile(); } } else { partition = Partitioner.Create(0, templateMetaData.Length); Parallel.ForEach(partition, (range, loopState) => { for (int i = range.Item1; i < range.Item2; i++) { templates[i] = (Func <UIElement, TemplateScope, UIElement>)compiledTemplateData.compiledTemplates[i].templateFn.Compile(); } }); } if (compiledTemplateData.compiledSlots.size < 10) { for (int i = 0; i < compiledTemplateData.compiledSlots.size; i++) { slots[i] = (Func <UIElement, UIElement, TemplateScope, UIElement>)compiledTemplateData.compiledSlots[i].templateFn.Compile(); } } else { partition = Partitioner.Create(0, compiledTemplateData.compiledSlots.size); Parallel.ForEach(partition, (range, loopState) => { for (int i = range.Item1; i < range.Item2; i++) { slots[i] = (Func <UIElement, UIElement, TemplateScope, UIElement>)compiledTemplateData.compiledSlots[i].templateFn.Compile(); } }); } if (bindings.Length < 10) { for (int i = 0; i < bindings.Length; i++) { try { bindings[i] = (Action <UIElement, UIElement>)compiledTemplateData.compiledBindings[i].bindingFn.Compile(); } catch (Exception e) { Debug.Log("binding " + compiledTemplateData.compiledBindings[i].bindingFn.ToCSharpCode()); Debug.Log(e); } } } else { partition = Partitioner.Create(0, bindings.Length); Parallel.ForEach(partition, (range, loopState) => { for (int i = range.Item1; i < range.Item2; i++) { try { bindings[i] = (Action <UIElement, UIElement>)compiledTemplateData.compiledBindings[i].bindingFn.Compile(); } catch (Exception e) { Debug.Log("binding " + compiledTemplateData.compiledBindings[i].bindingFn.ToCSharpCode()); Debug.Log(e); } } }); } LightList <UIStyleGroupContainer> styleList = new LightList <UIStyleGroupContainer>(128); StyleSheet[] sheets = compiledTemplateData.styleImporter.GetImportedStyleSheets(); for (int i = 0; i < sheets.Length; i++) { StyleSheet sheet = sheets[i]; styleList.EnsureAdditionalCapacity(sheet.styleGroupContainers.Length); for (int j = 0; j < sheet.styleGroupContainers.Length; j++) { styleList.array[styleList.size++] = sheet.styleGroupContainers[j]; } } for (int i = 0; i < templateMetaData.Length; i++) { templateMetaData[i] = compiledTemplateData.compiledTemplates[i].templateMetaData; templateMetaData[i].styleMap = styleList.array; templateMetaData[i].BuildSearchMap(); } Dictionary <int, Func <ConstructedElement> > constructorFnMap = new Dictionary <int, Func <ConstructedElement> >(37); ConstructorInfo constructedTypeCtor = typeof(ConstructedElement).GetConstructor(new Type[] { typeof(int), typeof(UIElement) }); System.Diagnostics.Debug.Assert(constructedTypeCtor != null, nameof(constructedTypeCtor) + " != null"); compiledTemplateData.bindings = bindings; compiledTemplateData.slots = slots; compiledTemplateData.templates = templates; compiledTemplateData.templateMetaData = templateMetaData; compiledTemplateData.constructorFnMap = constructorFnMap; compiledTemplateData.constructElement = (typeId) => compiledTemplateData.constructorFnMap[typeId].Invoke(); // stopwatch.Stop(); // Debug.Log("Loaded UIForia templates in " + stopwatch.Elapsed.TotalSeconds.ToString("F2") + " seconds"); return(compiledTemplateData); }