Advertisement
Guest User

Untitled

a guest
Apr 12th, 2019
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haxe 11.86 KB | None | 0 0
  1. package haxe.ui.macros;
  2.  
  3. #if macro
  4. import haxe.macro.Context;
  5. import haxe.ui.core.ComponentClassMap;
  6. import haxe.ui.core.LayoutClassMap;
  7. import haxe.ui.macros.helpers.ClassBuilder;
  8. import haxe.ui.macros.helpers.CodeBuilder;
  9. import haxe.ui.parsers.modules.Module;
  10. import haxe.ui.parsers.modules.ModuleParser;
  11. import sys.FileSystem;
  12. import sys.io.File;
  13. #end
  14.  
  15. class ModuleMacros {
  16.    
  17.     #if macro
  18.     private static var _modules:Array<Module> = [];
  19.     private static var _modulesProcessed:Bool;
  20.     private static var _resourceIds:Array<String> = [];
  21.     #end
  22.    
  23.     macro public static function processModules() {
  24.         if (_modulesProcessed == true) {
  25.             return macro null;
  26.         }
  27.  
  28.         loadModules();
  29.        
  30.         var preloadAll:Bool = false;
  31.         var builder = new CodeBuilder();
  32.         for (m in _modules) {
  33.             if (m.preloadList == "all") {
  34.                 preloadAll = true;
  35.             }
  36.            
  37.             // add resources as haxe resources (plus prefix)
  38.             for (r in m.resourceEntries) {
  39.                 if (r.path != null) {
  40.                     var resolvedPath = null;
  41.                     try {
  42.                         resolvedPath = Context.resolvePath(r.path);
  43.                     } catch (e:Dynamic) {
  44.                         resolvedPath = haxe.io.Path.join([Sys.getCwd(), r.path]);
  45.                     }
  46.                     if (FileSystem.isDirectory(resolvedPath) && FileSystem.exists(resolvedPath)) {
  47.                         addResources(resolvedPath, resolvedPath, r.prefix);
  48.                     } else {
  49.                         trace("WARNING: Could not find path " + resolvedPath);
  50.                     }
  51.                 }
  52.             }
  53.  
  54.             for (s in m.scriptletEntries) {
  55.                 var types:Array<haxe.macro.Type> = MacroHelpers.typesFromClassOrPackage(s.className, s.classPackage);
  56.                 if (types != null) {
  57.                     for (t in types) {
  58.                         var scriptType = new ClassBuilder(t);
  59.                         if (scriptType.isPrivate == true) {
  60.                             continue;
  61.                         }
  62.                        
  63.                         var skipRest = false;
  64.                         var resolvedClass:String = scriptType.fullPath;
  65.                         var classAlias:String = s.classAlias;
  66.                         if (classAlias == null) {
  67.                             classAlias = scriptType.name;
  68.                         } else {
  69.                             skipRest = true; // as we have an alias defined lets skip any other types (assumes the first class is the one to alias)
  70.                         }
  71.                         if (StringTools.startsWith(resolvedClass, ".")) {
  72.                             continue;
  73.                         }
  74.                        
  75.                         builder.add(macro
  76.                             haxe.ui.scripting.ScriptInterp.addClassAlias($v{classAlias}, $v{resolvedClass})
  77.                         );
  78.                        
  79.                         if (s.staticClass == true || s.keep == true) {
  80.                             builder.add(macro
  81.                                 haxe.ui.scripting.ScriptInterp.addStaticClass($v{classAlias}, $p{resolvedClass.split(".")})
  82.                             );
  83.                         }
  84.  
  85.                         if (skipRest == true) {
  86.                             break;
  87.                         }
  88.                     }
  89.                 }
  90.             }
  91.  
  92.             // setup themes
  93.             for (t in m.themeEntries) {
  94.                 if (t.parent != null) {
  95.                     builder.add(macro
  96.                         haxe.ui.themes.ThemeManager.instance.getTheme($v{t.name}).parent = $v{t.parent}
  97.                     );
  98.                 }
  99.                 for (r in t.styles) {
  100.                     builder.add(macro
  101.                         haxe.ui.themes.ThemeManager.instance.addStyleResource($v{t.name}, $v{r.resource}, $v{r.priority})
  102.                     );
  103.                 }
  104.             }
  105.  
  106.             // handle plugins
  107.             /* TODO: is this still relevant??? Check haxeui-kha
  108.             for (p in m.plugins) {
  109.                 switch (p.type) {
  110.                     case "asset":
  111.                         code += 'var assetPlugin:${p.className} = new ${p.className}();\n';
  112.                         for (propName in p.config.keys()) {
  113.                             var propValue = p.config.get(propName);
  114.                             code += 'assetPlugin.setProperty("${propName}", "${propValue}");\n';
  115.                         }
  116.                         code += 'ToolkitAssets.instance.addPlugin(assetPlugin);\n';
  117.                     default:
  118.                         trace("WARNING: unknown plugin type: " + p.type);
  119.                 }
  120.             }
  121.             */
  122.  
  123.             // set toolkit properties
  124.             for (p in m.properties) {
  125.                 builder.add(macro
  126.                     haxe.ui.Toolkit.properties.set($v{p.name}, $v{p.value})
  127.                 );
  128.             }
  129.  
  130.             for (p in m.preload) {
  131.                 builder.add(macro
  132.                     haxe.ui.ToolkitAssets.instance.preloadList.push({type: $v{p.type}, resourceId: $v{p.id}})
  133.                 );
  134.             }
  135.         }
  136.        
  137.         if (preloadAll) {
  138.             for (r in _resourceIds) {
  139.                 if (StringTools.endsWith(r, ".png")) {
  140.                     builder.add(macro
  141.                         haxe.ui.ToolkitAssets.instance.preloadList.push({type: "image", resourceId: $v{r}})
  142.                     );
  143.                 }
  144.             }
  145.         }
  146.  
  147.         populateClassMap();
  148.        
  149.         for (alias in ComponentClassMap.list()) {
  150.             builder.add(macro
  151.                 haxe.ui.core.ComponentClassMap.register($v{alias}, $v{ComponentClassMap.get(alias)})
  152.             );
  153.         }
  154.  
  155.         for (alias in LayoutClassMap.list()) {
  156.             builder.add(macro
  157.                 haxe.ui.core.LayoutClassMap.register($v{alias}, $v{LayoutClassMap.get(alias)})
  158.             );
  159.         }
  160.        
  161.         _modulesProcessed = true;
  162.         return builder.expr;
  163.     }
  164.  
  165.     #if macro
  166.     private static var _classMapPopulated:Bool = false;
  167.     public static function populateClassMap() {
  168.         if (_classMapPopulated == true) {
  169.             return;
  170.         }
  171.  
  172.         var modules:Array<Module> = ModuleMacros.loadModules();
  173.         for (m in modules) {
  174.             // load component classes from all modules
  175.             for (c in m.componentEntries) {
  176.                 var types:Array<haxe.macro.Type> = MacroHelpers.typesFromClassOrPackage(c.className, c.classPackage);
  177.                 if (types != null) {
  178.                     for (t in types) {
  179.                         var builder = new ClassBuilder(t);
  180.                         if (builder.isPrivate == true) {
  181.                             continue;
  182.                         }
  183.                        
  184.                         if (builder.hasSuperClass("haxe.ui.core.Component") == true) {
  185.                             var resolvedClass:String = builder.fullPath;
  186.                             if (c.className != null && resolvedClass != c.className) {
  187.                                 continue;
  188.                             }
  189.                            
  190.                             var resolvedClassName = builder.name;
  191.                             var classAlias:String = c.classAlias;
  192.                             if (classAlias == null) {
  193.                                 classAlias = resolvedClassName;
  194.                             }
  195.                             classAlias = classAlias.toLowerCase();
  196.                            
  197.                             if (builder.hasInterface("haxe.ui.core.IDirectionalComponent")) {
  198.                                 var pkg = MacroHelpers.getPackage(resolvedClass);
  199.                                 if (StringTools.startsWith(resolvedClassName, "Horizontal")) { // alias HorizontalComponent with hcomponent
  200.                                     ComponentClassMap.register("h" + StringTools.replace(resolvedClassName, "Horizontal", "").toLowerCase(), resolvedClass);
  201.                                 } else if (StringTools.startsWith(resolvedClassName, "Vertical")) { // alias VerticalComponent with vcomponent
  202.                                     ComponentClassMap.register("v" + StringTools.replace(resolvedClassName, "Vertical", "").toLowerCase(), resolvedClass);
  203.                                 }
  204.                             }
  205.                            
  206.                             ComponentClassMap.register(classAlias, resolvedClass);
  207.                         }
  208.                     }
  209.                 }
  210.             }
  211.  
  212.             // load layout classes from all modules
  213.             for (c in m.layoutEntries) {
  214.                 var types:Array<haxe.macro.Type> = MacroHelpers.typesFromClassOrPackage(c.className, c.classPackage);
  215.                 if (types != null) {
  216.                     for (t in types) {
  217.                         var builder = new ClassBuilder(t);
  218.                         if (builder.isPrivate == true) {
  219.                             continue;
  220.                         }
  221.  
  222.                         if (builder.hasSuperClass("haxe.ui.layouts.Layout") == true) {                            
  223.                             var resolvedClass:String = builder.fullPath;
  224.                             if (c.className != null && resolvedClass != c.className) {
  225.                                 continue;
  226.                             }
  227.  
  228.                             var resolvedClassName = builder.name;
  229.                             var classAlias:String = c.classAlias;
  230.                             if (classAlias == null) {
  231.                                 classAlias = resolvedClassName;
  232.                             }
  233.                             classAlias = classAlias.toLowerCase();
  234.  
  235.                             LayoutClassMap.register(classAlias, resolvedClass);
  236.                         }
  237.                     }
  238.                 }
  239.             }
  240.         }
  241.  
  242.         _classMapPopulated = true;
  243.     }
  244.  
  245.     private static var _modulesLoaded:Bool = false;
  246.     public static function loadModules():Array<Module> {
  247.         if (_modulesLoaded == true) {
  248.             return _modules;
  249.         }
  250.  
  251.         MacroHelpers.scanClassPath(function(filePath:String) {
  252.             var moduleParser = ModuleParser.get(MacroHelpers.extension(filePath));
  253.             if (moduleParser != null) {
  254.                 try {
  255.                     var module:Module = moduleParser.parse(File.getContent(filePath), Context.getDefines(), filePath);
  256.                     module.validate();
  257.                     _modules.push(module);
  258.                     return true;
  259.                 } catch (e:Dynamic) {
  260.                     trace('WARNING: Problem parsing module ${MacroHelpers.extension(filePath)} (${filePath}) - ${e} (skipping file)');
  261.                 }
  262.             }
  263.             return false;
  264.         }, ["module."]);
  265.  
  266.         _modulesLoaded = true;
  267.         return _modules;
  268.     }
  269.  
  270.     private static function addResources(path:String, base:String, prefix:String) {
  271.         if (prefix == null) {
  272.             prefix = "";
  273.         }
  274.         var contents:Array<String> = sys.FileSystem.readDirectory(path);
  275.         for (f in contents) {
  276.             var file = path + "/" + f;
  277.             if (sys.FileSystem.isDirectory(file)) {
  278.                 addResources(file, base, prefix);
  279.             } else {
  280.                 var relativePath = prefix + StringTools.replace(file, base, "");
  281.                 var resourceName:String = relativePath;
  282.                 if (StringTools.startsWith(resourceName, "/")) {
  283.                     resourceName = resourceName.substr(1, resourceName.length);
  284.                 }
  285.                 _resourceIds.push(resourceName);
  286.                 Context.addResource(resourceName, File.getBytes(file));
  287.             }
  288.         }
  289.     }
  290.     #end
  291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement