Improved Macros + Libraries (WIP)
Co-Authored-By: ⍚~Nex <87421482+NexIsDumb@users.noreply.github.com>
This commit is contained in:
committed by
⍚~Nex
co-authored by
⍚~Nex
parent
f9c74c5a2d
commit
e068300cf1
@@ -0,0 +1,7 @@
|
||||
package funkin.backend.assets;
|
||||
|
||||
enum abstract AssetSource(Null<Bool>) from Bool from Null<Bool> to Null<Bool> {
|
||||
var SOURCE = true;
|
||||
var MODS = false;
|
||||
var BOTH = null;
|
||||
}
|
||||
@@ -22,10 +22,10 @@ class AssetsLibraryList extends AssetLibrary {
|
||||
return lib;
|
||||
}
|
||||
public function existsSpecific(id:String, type:String, source:AssetSource = BOTH) {
|
||||
if (!id.startsWith("assets/") && exists('assets/$id', type))
|
||||
if (!id.startsWith("assets/") && existsSpecific('assets/$id', type, source))
|
||||
return true;
|
||||
for(k=>e in libraries) {
|
||||
if (shouldSkipLib(k, source)) continue;
|
||||
if (shouldSkipLib(e, source)) continue;
|
||||
if (e.exists(id, type))
|
||||
return true;
|
||||
}
|
||||
@@ -36,7 +36,7 @@ class AssetsLibraryList extends AssetLibrary {
|
||||
|
||||
public function getSpecificPath(id:String, source:AssetSource = BOTH) {
|
||||
for(k=>e in libraries) {
|
||||
if (shouldSkipLib(k, source)) continue;
|
||||
if (shouldSkipLib(e, source)) continue;
|
||||
|
||||
@:privateAccess
|
||||
if (e.exists(id, e.types.get(id))) {
|
||||
@@ -54,7 +54,7 @@ class AssetsLibraryList extends AssetLibrary {
|
||||
public function getFiles(folder:String, source:AssetSource = BOTH):Array<String> {
|
||||
var content:Array<String> = [];
|
||||
for(k=>e in libraries) {
|
||||
if (shouldSkipLib(k, source)) continue;
|
||||
if (shouldSkipLib(e, source)) continue;
|
||||
|
||||
var l = e;
|
||||
|
||||
@@ -78,7 +78,7 @@ class AssetsLibraryList extends AssetLibrary {
|
||||
public function getFolders(folder:String, source:AssetSource = BOTH):Array<String> {
|
||||
var content:Array<String> = [];
|
||||
for(k=>e in libraries) {
|
||||
if (shouldSkipLib(k, source)) continue;
|
||||
if (shouldSkipLib(e, source)) continue;
|
||||
|
||||
var l = e;
|
||||
|
||||
@@ -108,7 +108,7 @@ class AssetsLibraryList extends AssetLibrary {
|
||||
}
|
||||
}
|
||||
for(k=>e in libraries) {
|
||||
if (shouldSkipLib(k, source)) continue;
|
||||
if (shouldSkipLib(e, source)) continue;
|
||||
|
||||
@:privateAccess
|
||||
if (e.exists(id, e.types.get(id))) {
|
||||
@@ -125,15 +125,9 @@ class AssetsLibraryList extends AssetLibrary {
|
||||
return null;
|
||||
}
|
||||
|
||||
private function shouldSkipLib(k:Int, source:AssetSource) {
|
||||
#if TRANSLATIONS_SUPPORT
|
||||
k -= libraries.indexOf(transLib) + 1;
|
||||
#end
|
||||
return switch(source) {
|
||||
case BOTH: false;
|
||||
case SOURCE: k < libraries.length - __defaultLibraries.length;
|
||||
case MODS: k >= libraries.length - __defaultLibraries.length;
|
||||
};
|
||||
private function shouldSkipLib(lib:AssetLibrary, source:AssetSource) {
|
||||
if (source == BOTH || lib.tag == BOTH) return false;
|
||||
return source != lib.tag;
|
||||
}
|
||||
public override inline function getAsset(id:String, type:String):Dynamic
|
||||
return getSpecificAsset(id, type, BOTH);
|
||||
@@ -171,10 +165,4 @@ class AssetsLibraryList extends AssetLibrary {
|
||||
lib.tag = tag;
|
||||
return lib;
|
||||
}
|
||||
}
|
||||
|
||||
enum abstract AssetSource(Null<Bool>) from Bool from Null<Bool> to Null<Bool> {
|
||||
var SOURCE = true;
|
||||
var MODS = false;
|
||||
var BOTH = null;
|
||||
}
|
||||
@@ -48,8 +48,10 @@ class ModsFolder {
|
||||
* Initialises `mods` folder.
|
||||
*/
|
||||
public static function init() {
|
||||
if(!getModsList().contains(Options.lastLoadedMod))
|
||||
if(!getModsList().contains(Options.lastLoadedMod)) {
|
||||
Options.lastLoadedMod = null;
|
||||
Logs.trace("Mod not found in mods list, switching to base game!", WARNING, YELLOW);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,6 +61,10 @@ class ModsFolder {
|
||||
public static function switchMod(mod:String) {
|
||||
Options.lastLoadedMod = currentModFolder = mod;
|
||||
reloadMods();
|
||||
Logs.traceColored([
|
||||
Logs.logText('Switched to mod ', GRAY),
|
||||
Logs.logText(mod, GREEN)
|
||||
], VERBOSE);
|
||||
}
|
||||
|
||||
public static function reloadMods() {
|
||||
|
||||
@@ -236,7 +236,7 @@ class Paths
|
||||
return graph.imageFrame;
|
||||
}
|
||||
|
||||
public static function getFolderDirectories(key:String, addPath:Bool = false, source:AssetsLibraryList.AssetSource = BOTH):Array<String> {
|
||||
public static function getFolderDirectories(key:String, addPath:Bool = false, source:AssetSource = BOTH):Array<String> {
|
||||
if (!key.endsWith("/")) key += "/";
|
||||
var content = assetsTree.getFolders('assets/$key', source);
|
||||
if (addPath) {
|
||||
@@ -246,7 +246,7 @@ class Paths
|
||||
return content;
|
||||
}
|
||||
|
||||
public static function getFolderContent(key:String, addPath:Bool = false, source:AssetsLibraryList.AssetSource = BOTH):Array<String> {
|
||||
public static function getFolderContent(key:String, addPath:Bool = false, source:AssetSource = BOTH):Array<String> {
|
||||
// designed to work both on windows and web
|
||||
if (!key.endsWith("/")) key += "/";
|
||||
var content = assetsTree.getFiles('assets/$key', source);
|
||||
|
||||
@@ -57,6 +57,16 @@ class TranslatedAssetLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
return null;
|
||||
}
|
||||
|
||||
public override function getText(id:String):String
|
||||
{
|
||||
for(lib in ModsFolder.getLoadedModsLibs(true)) {
|
||||
if(!(lib is AssetLibrary)) continue;
|
||||
var val = cast(lib, AssetLibrary).getText(formatPath(lib.prefix, id));
|
||||
if(val != null) return val;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override function getFont(id:String):Font
|
||||
{
|
||||
for(lib in ModsFolder.getLoadedModsLibs(true)) {
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
package funkin.backend.system.macros;
|
||||
|
||||
#if macro
|
||||
import haxe.macro.Context;
|
||||
import haxe.macro.Expr;
|
||||
import haxe.macro.Compiler;
|
||||
|
||||
using StringTools;
|
||||
|
||||
/**
|
||||
* Macro used to add custom fields to classes without having to override the entire file.
|
||||
*/
|
||||
class CustomFieldMacro {
|
||||
public static function init() {
|
||||
Compiler.addGlobalMetadata("lime.utils", '@:build(funkin.backend.system.macros.UsingHandler.build("lime.utils.AssetLibrary", "tag", "funkin.backend.assets.AssetSource"))');
|
||||
}
|
||||
|
||||
// TODO: Add support for default values
|
||||
public static function build(lib:String, fieldName:String, type:String) {
|
||||
var fields = Context.getBuildFields();
|
||||
var clRef = Context.getLocalClass();
|
||||
if (clRef == null) return fields;
|
||||
var cl = clRef.get();
|
||||
|
||||
var key = cl.module;
|
||||
var fkey = cl.module + "." + cl.name;
|
||||
|
||||
if(fkey != lib) {
|
||||
return fields;
|
||||
}
|
||||
|
||||
var fields = Context.getBuildFields();
|
||||
|
||||
fields.push({
|
||||
name: fieldName,
|
||||
access: [APublic],
|
||||
kind: FVar(getTPath(type)),
|
||||
pos: Context.currentPos()
|
||||
});
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
public static function getTPath(type:String) {
|
||||
var arr = type.split(".");
|
||||
return TPath({
|
||||
pack: arr.slice(0, arr.length - 1),
|
||||
name: arr[arr.length - 1]
|
||||
});
|
||||
}
|
||||
}
|
||||
#end
|
||||
@@ -1,164 +0,0 @@
|
||||
package funkin.backend.system.macros;
|
||||
|
||||
#if macro
|
||||
import haxe.macro.Expr;
|
||||
import haxe.macro.*;
|
||||
|
||||
using StringTools;
|
||||
using haxe.macro.PositionTools;
|
||||
|
||||
class HashLinkFixer {
|
||||
public static var buildMacroString = '@:build(funkin.backend.system.macros.HashLinkFixer.build())';
|
||||
|
||||
public static var applyOn:Array<String> = [
|
||||
"lime",
|
||||
"std",
|
||||
"Math",
|
||||
"",
|
||||
];
|
||||
|
||||
public static var modifiedClasses:Array<String> = [];
|
||||
|
||||
public static function init() {
|
||||
#if !display
|
||||
if(Context.defined("hl")) {
|
||||
for(apply in applyOn) {
|
||||
compile(apply);
|
||||
}
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
public static function compile(name:String) {
|
||||
#if !display
|
||||
Compiler.addGlobalMetadata(name, buildMacroString);
|
||||
#end
|
||||
}
|
||||
|
||||
public static function build():Array<Field> {
|
||||
var fields = Context.getBuildFields();
|
||||
var clRef = Context.getLocalClass();
|
||||
if (clRef == null) return fields;
|
||||
var cl = clRef.get();
|
||||
|
||||
if (cl.isAbstract || cl.isExtern || cl.isInterface) return fields;
|
||||
if (!cl.name.endsWith("_Impl_") && !cl.name.endsWith("_HSX") && !cl.name.endsWith("_HSC") && !cl.name.endsWith("_HLFHelper")) {
|
||||
var metas = cl.meta.get();
|
||||
|
||||
if(cl.params.length > 0)
|
||||
return fields;
|
||||
|
||||
if(cl.module == "EReg") return fields; // private typedef in same class
|
||||
if(cl.module == "hl.Format") return fields; // enum in same class
|
||||
|
||||
var definedFields = [];
|
||||
|
||||
var helperClass = macro class {
|
||||
|
||||
};
|
||||
|
||||
helperClass.pos = cl.pos;
|
||||
|
||||
var module = cl.module + "_HLFHelper";
|
||||
var hcClassName = cl.name + "_HLFHelper";
|
||||
|
||||
for(f in fields.copy()) {
|
||||
if (f == null)
|
||||
continue;
|
||||
if (f.name == "new")
|
||||
continue;
|
||||
|
||||
if(definedFields.contains(f.name)) continue; // no duplicate fields
|
||||
|
||||
var hasHlNative = false;
|
||||
for(m in f.meta)
|
||||
if (m.name == ":hlNative") {
|
||||
hasHlNative = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!hasHlNative) continue;
|
||||
|
||||
switch(f.kind) {
|
||||
case FFun(fun):
|
||||
if (fun == null)
|
||||
continue;
|
||||
if (fun.params != null && fun.params.length > 0) // TODO: Support for this maybe?
|
||||
continue;
|
||||
|
||||
if(fun.params == null)
|
||||
fun.params = [];
|
||||
|
||||
var overrideExpr:Expr;
|
||||
var returns:Bool = !fun.ret.match(TPath({name: "Void"}));
|
||||
|
||||
var name = 'hlf_${f.name}';
|
||||
|
||||
var arguments = fun.args == null ? [] : [for(a in fun.args) macro $i{a.name}];
|
||||
|
||||
var funcExpr:Expr = returns ? {
|
||||
//macro return $i{name}($a{arguments});
|
||||
macro return @:privateAccess $i{hcClassName}.$name($a{arguments});
|
||||
} : {
|
||||
macro @:privateAccess $i{hcClassName}.$name($a{arguments});
|
||||
};
|
||||
|
||||
var fiel:Field = {
|
||||
name: name,
|
||||
pos: Context.currentPos(),
|
||||
kind: FFun({
|
||||
ret: fun.ret,
|
||||
params: fun.params.copy(),
|
||||
expr: fun.expr,
|
||||
args: fun.args.copy()
|
||||
}),
|
||||
access: f.access.copy(),
|
||||
meta: f.meta.copy()
|
||||
};
|
||||
helperClass.fields.push(fiel);
|
||||
definedFields.push(f.name);
|
||||
|
||||
for(m in f.meta.copy())
|
||||
if (m.name == ":hlNative") {
|
||||
f.meta.remove(m);
|
||||
}
|
||||
|
||||
fun.expr = funcExpr;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
helperClass.pack = cl.pack.copy();
|
||||
helperClass.pos = cl.pos;
|
||||
helperClass.name = hcClassName;
|
||||
|
||||
if(definedFields.length > 0) {
|
||||
trace(cl.module);
|
||||
|
||||
/*for(m in metas.copy()) {
|
||||
trace(" " + m.name);
|
||||
if(m.name == ":coreApi") {
|
||||
metas.remove(m);
|
||||
}
|
||||
}*/
|
||||
|
||||
var imports = Context.getLocalImports().copy();
|
||||
Context.defineModule(module, [helperClass], imports);
|
||||
|
||||
Context.getLocalImports().push({
|
||||
path: [for(m in module.split(".")) {
|
||||
name: m,
|
||||
pos: Context.currentPos()
|
||||
}],
|
||||
mode: INormal
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
#else
|
||||
class HashLinkFixer {
|
||||
}
|
||||
#end
|
||||
@@ -43,10 +43,6 @@ class Macros {
|
||||
}
|
||||
|
||||
public static function initMacros() {
|
||||
if(Context.defined("hl"))
|
||||
HashLinkFixer.init();
|
||||
|
||||
CustomFieldsMacro.init();
|
||||
}
|
||||
}
|
||||
#end
|
||||
@@ -125,7 +125,7 @@ class TranslationUtil
|
||||
}
|
||||
if (xml == null) return [];
|
||||
if (!xml.hasNode.translations) {
|
||||
FlxG.log.warn("A translation xml file requires a translations root element.");
|
||||
Logs.trace("A translation xml file requires a translations root element.", WARNING, YELLOW);
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
@@ -430,7 +430,7 @@ class FreeplaySonglist {
|
||||
|
||||
public function new() {}
|
||||
|
||||
public function getSongsFromSource(source:funkin.backend.assets.AssetsLibraryList.AssetSource, useTxt:Bool = true) {
|
||||
public function getSongsFromSource(source:funkin.backend.assets.AssetSource, useTxt:Bool = true) {
|
||||
var path:String = Paths.txt('freeplaySonglist');
|
||||
var songsFound:Array<String> = [];
|
||||
if (useTxt && Paths.assetsTree.existsSpecific(path, "TEXT", source)) {
|
||||
|
||||
@@ -297,7 +297,7 @@ class StoryMenuState extends MusicBeatState {
|
||||
characters[charName] = charObj;
|
||||
}
|
||||
|
||||
public function getWeeksFromSource(weeks:Array<String>, source:funkin.backend.assets.AssetsLibraryList.AssetSource) {
|
||||
public function getWeeksFromSource(weeks:Array<String>, source:funkin.backend.assets.AssetSource) {
|
||||
var path:String = Paths.txt('freeplaySonglist');
|
||||
var weeksFound:Array<String> = [];
|
||||
if (Paths.assetsTree.existsSpecific(path, "TEXT", source)) {
|
||||
|
||||
@@ -20,7 +20,7 @@ class CreditsMain extends TreeMenu {
|
||||
|
||||
var selectables:Array<OptionType> = [];
|
||||
var xmlPath = Paths.xml('config/credits');
|
||||
for(source in [funkin.backend.assets.AssetsLibraryList.AssetSource.SOURCE, funkin.backend.assets.AssetsLibraryList.AssetSource.MODS]) {
|
||||
for(source in [funkin.backend.assets.AssetSource.SOURCE, funkin.backend.assets.AssetSource.MODS]) {
|
||||
if (Paths.assetsTree.existsSpecific(xmlPath, "TEXT", source)) {
|
||||
var access:Access = null;
|
||||
try {
|
||||
|
||||
@@ -69,7 +69,7 @@ class OptionsMenu extends TreeMenu {
|
||||
})]);
|
||||
|
||||
var xmlPath = Paths.xml("config/options");
|
||||
for(source in [funkin.backend.assets.AssetsLibraryList.AssetSource.SOURCE, funkin.backend.assets.AssetsLibraryList.AssetSource.MODS]) {
|
||||
for(source in [funkin.backend.assets.AssetSource.SOURCE, funkin.backend.assets.AssetSource.MODS]) {
|
||||
if (Paths.assetsTree.existsSpecific(xmlPath, "TEXT", source)) {
|
||||
var access:Access = null;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user