diff --git a/source/funkin/backend/system/framerate/AssetTreeInfo.hx b/source/funkin/backend/system/framerate/AssetTreeInfo.hx index 1414904f5f..f81218879e 100644 --- a/source/funkin/backend/system/framerate/AssetTreeInfo.hx +++ b/source/funkin/backend/system/framerate/AssetTreeInfo.hx @@ -6,6 +6,7 @@ import funkin.backend.assets.TranslatedAssetLibrary; import funkin.backend.assets.AssetsLibraryList; import funkin.backend.assets.IModsAssetLibrary; import funkin.backend.assets.ScriptedAssetLibrary; +import funkin.backend.system.macros.StringMacro; class AssetTreeInfo extends FramerateCategory { private var lastUpdateTime:Float = 1; @@ -22,32 +23,35 @@ class AssetTreeInfo extends FramerateCategory { lastUpdateTime = 0; - var text = 'Not initialized yet\n'; + var text = "Not initialized yet\n"; if (Paths.assetsTree != null){ text = ""; + var buf = new StringBuf(); for(l in Paths.assetsTree.libraries) { var l = AssetsLibraryList.getCleanLibrary(l); var tag = l.tag.toString().toUpperCase(); - text += '[$tag] '; + StringMacro.addLine(buf, '[${tag}] '); var className = Type.getClassName(Type.getClass(l)); className = className.substr(className.lastIndexOf(".") + 1); #if TRANSLATIONS_SUPPORT - if (l is TranslatedAssetLibrary) - text += '${className} - ${cast(l, TranslatedAssetLibrary).langFolder} for (${cast(l, TranslatedAssetLibrary).forLibrary.modName})\n'; - else #end if (l is ScriptedAssetLibrary) - text += '${className} - ${cast(l, ScriptedAssetLibrary).scriptName} (${cast(l, ScriptedAssetLibrary).modName} | ${cast(l, ScriptedAssetLibrary).libName} | ${cast(l, ScriptedAssetLibrary).prefix})\n'; - else if (l is IModsAssetLibrary) - text += '${className} - ${cast(l, IModsAssetLibrary).modName} - ${cast(l, IModsAssetLibrary).libName} (${cast(l, IModsAssetLibrary).prefix})\n'; - else - text += Std.string(l) + '\n'; + if (l is TranslatedAssetLibrary) { + StringMacro.addLine(buf, '${className} - ${cast(l, TranslatedAssetLibrary).langFolder} for (${cast(l, TranslatedAssetLibrary).forLibrary.modName})\n'); + } else #end if (l is ScriptedAssetLibrary) { + StringMacro.addLine(buf, '${className} - ${cast(l, ScriptedAssetLibrary).scriptName} (${cast(l, ScriptedAssetLibrary).modName} | ${cast(l, ScriptedAssetLibrary).libName} | ${cast(l, ScriptedAssetLibrary).prefix})\n'); + } else if (l is IModsAssetLibrary) { + StringMacro.addLine(buf, '${className} - ${cast(l, IModsAssetLibrary).modName} - ${cast(l, IModsAssetLibrary).libName} (${cast(l, IModsAssetLibrary).prefix})\n'); + } else { + StringMacro.addLine(buf, '${Std.string(l)}\n'); + } } + text = buf.toString(); + if (text != "") + text = text.substr(0, text.length-1); } - if (text != "") - text = text.substr(0, text.length-1); this.text.text = text; super.__enterFrame(t); diff --git a/source/funkin/backend/system/framerate/ConductorInfo.hx b/source/funkin/backend/system/framerate/ConductorInfo.hx index e615bbbaf9..d5fc9a1737 100644 --- a/source/funkin/backend/system/framerate/ConductorInfo.hx +++ b/source/funkin/backend/system/framerate/ConductorInfo.hx @@ -1,5 +1,7 @@ package funkin.backend.system.framerate; +import funkin.backend.system.macros.StringMacro; + class ConductorInfo extends FramerateCategory { public function new() { super("Conductor Info"); @@ -7,12 +9,15 @@ class ConductorInfo extends FramerateCategory { public override function __enterFrame(t:Int) { if (alpha <= 0.05) return; - _text = 'Current Song Position: ${Math.floor(Conductor.songPosition * 1000) / 1000}'; - _text += '\n - ${Conductor.curBeat} beats'; - _text += '\n - ${Conductor.curStep} steps'; - _text += '\n - ${Conductor.curMeasure} measures'; - _text += '\nCurrent BPM: ${Conductor.bpm}'; - _text += '\nTime Signature: ${Conductor.beatsPerMeasure}/${Conductor.denominator}'; + + var buf = new StringBuf(); + StringMacro.addLine(buf, 'Current Song Position: ${Math.floor(Conductor.songPosition * 1000) / 1000}'); + StringMacro.addLine(buf, '\n - ${Conductor.curBeat} beats'); + StringMacro.addLine(buf, '\n - ${Conductor.curStep} steps'); + StringMacro.addLine(buf, '\n - ${Conductor.curMeasure} measures'); + StringMacro.addLine(buf, '\nCurrent BPM: ${Conductor.bpm}'); + StringMacro.addLine(buf, '\nTime Signature: ${Conductor.beatsPerMeasure}/${Conductor.denominator}'); + _text = buf.toString(); this.text.text = _text; super.__enterFrame(t); diff --git a/source/funkin/backend/system/framerate/FlixelInfo.hx b/source/funkin/backend/system/framerate/FlixelInfo.hx index c485468c97..0ce42c299a 100644 --- a/source/funkin/backend/system/framerate/FlixelInfo.hx +++ b/source/funkin/backend/system/framerate/FlixelInfo.hx @@ -1,6 +1,7 @@ package funkin.backend.system.framerate; import funkin.backend.scripting.ModState; +import funkin.backend.system.macros.StringMacro; class FlixelInfo extends FramerateCategory { public function new() { @@ -10,28 +11,30 @@ class FlixelInfo extends FramerateCategory { public override function __enterFrame(t:Int) { if (alpha <= 0.05) return; - @:privateAccess { var c:Int = Lambda.count(FlxG.bitmap._cache); + var buf = new StringBuf(); if((FlxG.state is ModState)) { var state:ModState = cast FlxG.state; - _text = "Mod State: " + state.scriptName; + StringMacro.addLine(buf, 'Mod State: ${state.scriptName}'); } else { - _text = 'State: ${Type.getClassName(Type.getClass(FlxG.state))}'; + StringMacro.addLine(buf, 'State: ${Type.getClassName(Type.getClass(FlxG.state))}'); + } + StringMacro.addLine(buf, '\nObject Count: ${FlxG.state.members.length}'); + StringMacro.addLine(buf, '\nCamera Count: ${FlxG.cameras.list.length}'); + StringMacro.addLine(buf, '\nBitmaps Count: ${c}'); + StringMacro.addLine(buf, '\nSounds Count: ${FlxG.sound.list.length}'); + StringMacro.addLine(buf, '\nFlxG.game Childs Count: ${FlxG.game.numChildren}'); + if(FlxG.renderBlit) { + StringMacro.addLine(buf, '\nBlitting Render: true'); } - _text += '\nObject Count: ${FlxG.state.members.length}'; - _text += '\nCamera Count: ${FlxG.cameras.list.length}'; - _text += '\nBitmaps Count: ${c}'; - _text += '\nSounds Count: ${FlxG.sound.list.length}'; - _text += '\nFlxG.game Childs Count: ${FlxG.game.numChildren}'; - if(FlxG.renderBlit) _text += '\nBlitting Render: true'; - // _text += '\nCached objects count: ${cachedObjects}'; #if FLX_POINT_POOL //var points = flixel.math.FlxPoint.FlxBasePoint.pool; - //_text += '\nPoint Count: ${points._count} | +${points.made} | -${points.gotten} | ${points.balance} | >${points.putted}'; - //_text += '\nPoint Count: ${points._count}'; + //StringMacro.addLine(buf, '\nPoint Count: ', points._count, ' | +', points.made, ' | -', points.gotten, ' | ', points.balance, ' | >', points.putted); + //StringMacro.addLine(buf, '\nPoint Count: ', points._count); #end + _text = buf.toString(); } this.text.text = _text; diff --git a/source/funkin/backend/system/framerate/FramerateCategory.hx b/source/funkin/backend/system/framerate/FramerateCategory.hx index db89137f37..0bae85b2db 100644 --- a/source/funkin/backend/system/framerate/FramerateCategory.hx +++ b/source/funkin/backend/system/framerate/FramerateCategory.hx @@ -52,4 +52,8 @@ class FramerateCategory extends Sprite { bgSprite.scaleX = width; bgSprite.scaleY = height; } + + public static inline function addLine(buf:StringBuf, ...values:Array):Void { + for (v in values) buf.add(v); + } } diff --git a/source/funkin/backend/system/framerate/StatsInfo.hx b/source/funkin/backend/system/framerate/StatsInfo.hx index 937bdb1062..bc98c39223 100644 --- a/source/funkin/backend/system/framerate/StatsInfo.hx +++ b/source/funkin/backend/system/framerate/StatsInfo.hx @@ -3,6 +3,7 @@ package funkin.backend.system.framerate; #if (gl_stats && !disable_cffi && (!html5 || !canvas)) import openfl.display._internal.stats.Context3DStats; import openfl.display._internal.stats.DrawCallContext; +import funkin.backend.system.macros.StringMacro; class StatsInfo extends FramerateCategory { public function new() { @@ -11,9 +12,12 @@ class StatsInfo extends FramerateCategory { public override function __enterFrame(t:Int) { if (alpha <= 0.05) return; - _text = "totalDC: " + Context3DStats.totalDrawCalls(); - _text += "\nstageDC: " + Context3DStats.contextDrawCalls(DrawCallContext.STAGE); - _text += "\nstage3DDC: " + Context3DStats.contextDrawCalls(DrawCallContext.STAGE3D); + + var buf = new StringBuf(); + StringMacro.addLine(buf, 'totalDC: ${Context3DStats.totalDrawCalls()}'); + StringMacro.addLine(buf, '\nstageDC: ${Context3DStats.contextDrawCalls(DrawCallContext.STAGE)}'); + StringMacro.addLine(buf, '\nstage3DDC: ${Context3DStats.contextDrawCalls(DrawCallContext.STAGE3D)}'); + _text = buf.toString(); this.text.text = _text; super.__enterFrame(t); diff --git a/source/funkin/backend/system/framerate/SystemInfo.hx b/source/funkin/backend/system/framerate/SystemInfo.hx index 4de57190f2..4562b338a1 100644 --- a/source/funkin/backend/system/framerate/SystemInfo.hx +++ b/source/funkin/backend/system/framerate/SystemInfo.hx @@ -9,6 +9,7 @@ import cpp.UInt64; #end using StringTools; +import funkin.backend.system.macros.StringMacro; class SystemInfo extends FramerateCategory { public static var osInfo:String = "Unknown"; @@ -137,21 +138,32 @@ class SystemInfo extends FramerateCategory { } static function formatSysInfo() { - __formattedSysText = ""; - if (osInfo != "Unknown") __formattedSysText += 'System: $osInfo'; - if (cpuName != "Unknown") __formattedSysText += '\nCPU: $cpuName ${openfl.system.Capabilities.cpuArchitecture} ${(openfl.system.Capabilities.supports64BitProcesses ? '64-Bit' : '32-Bit')}'; + var buf = new StringBuf(); + if (osInfo != "Unknown") { + StringMacro.addLine(buf, 'System: ${osInfo}'); + } + if (cpuName != "Unknown") { + StringMacro.addLine(buf, '\nCPU: ${cpuName} ${openfl.system.Capabilities.cpuArchitecture} ${openfl.system.Capabilities.supports64BitProcesses ? "64-Bit" : "32-Bit"}'); + } if (gpuName != cpuName || vRAM != "Unknown") { var gpuNameKnown = gpuName != "Unknown" && gpuName != cpuName; var vramKnown = vRAM != "Unknown"; - if(gpuNameKnown || vramKnown) __formattedSysText += "\n"; + if(gpuNameKnown || vramKnown) buf.add("\n"); - if(gpuNameKnown) __formattedSysText += 'GPU: $gpuName'; - if(gpuNameKnown && vramKnown) __formattedSysText += " | "; - if(vramKnown) __formattedSysText += 'VRAM: $vRAM'; // 1000 bytes of vram (apus) + if(gpuNameKnown) { + StringMacro.addLine(buf, 'GPU: ${gpuName}'); + } + if(gpuNameKnown && vramKnown) buf.add(" | "); + if(vramKnown) { + StringMacro.addLine(buf, 'VRAM: ${vRAM}'); + } + } + //if (gpuMaxSize != "Unknown") StringMacro.addLine(buf, '\nMax Bitmap Size: ',gpuMaxSize); + if (totalMem != "Unknown" && memType != "Unknown") { + StringMacro.addLine(buf, '\nTotal MEM: ${totalMem} ${memType}'); } - //if (gpuMaxSize != "Unknown") __formattedSysText += '\nMax Bitmap Size: $gpuMaxSize'; - if (totalMem != "Unknown" && memType != "Unknown") __formattedSysText += '\nTotal MEM: $totalMem $memType'; + __formattedSysText = buf.toString(); } static function getSizeString(size:Float):String { @@ -172,8 +184,11 @@ class SystemInfo extends FramerateCategory { public override function __enterFrame(t:Int) { if (alpha <= 0.05) return; - _text = __formattedSysText; - _text += '${__formattedSysText == "" ? "" : "\n"}Garbage Collector: ${MemoryUtil.disableCount > 0 ? "OFF" : "ON"} (${MemoryUtil.disableCount})'; + var buf = new StringBuf(); + buf.add(__formattedSysText); + if (__formattedSysText != '') buf.add('\n'); + StringMacro.addLine(buf, 'Garbage Collector: ${MemoryUtil.disableCount > 0 ? "OFF" : "ON"} (${MemoryUtil.disableCount})'); + _text = buf.toString(); this.text.text = _text; super.__enterFrame(t); diff --git a/source/funkin/backend/system/macros/StringMacro.hx b/source/funkin/backend/system/macros/StringMacro.hx new file mode 100644 index 0000000000..47efcfe3c9 --- /dev/null +++ b/source/funkin/backend/system/macros/StringMacro.hx @@ -0,0 +1,105 @@ +package funkin.backend.system.macros; + +#if macro +import haxe.macro.Context; +import haxe.macro.Expr; +import haxe.io.Path; +import sys.io.File; +#end + +class StringMacro { + @:dox(hide) public static macro function addLine(buf:Expr, args:Array):Expr { + var exprs = []; + for (arg in args) { + var expanded = expandInterpolatedString(buf, arg); + if (expanded != null) { + exprs = exprs.concat(expanded); + } else { + exprs.push(macro $buf.add($arg)); + } + } + return macro $b{exprs}; + } + + #if macro + static function expandInterpolatedString(buf:Expr, arg:Expr):Array { + var posInfos = Context.getPosInfos(arg.pos); + if (posInfos == null || posInfos.file == null) return null; + + var fileContent = File.getContent(posInfos.file); + var lineStart = posInfos.min; + var lineEnd = posInfos.max; + + if (lineEnd <= lineStart || lineEnd > fileContent.length) return null; + + var original = fileContent.substring(lineStart, lineEnd); + + var dollarBrace = "$" + "{"; + if (original.indexOf(dollarBrace) == -1) return null; + + var result = []; + var regex = ~/\$\{([^}]+)\}/g; + var lastIndex = 0; + var isFirst = true; + + while (regex.matchSub(original, lastIndex)) { + var matchPos = regex.matchedPos(); + var prefix = original.substring(lastIndex, matchPos.pos); + if (prefix.length > 0) { + if (isFirst && (prefix.charAt(0) == '"' || prefix.charAt(0) == "'".charAt(0))) { + prefix = prefix.substr(1); + } + if (prefix.length > 0) { + prefix = escapeString(prefix); + result.push(macro $buf.add($v{prefix})); + } + } + + var exprStr = regex.matched(1); + if (exprStr != null && exprStr.length > 0) { + var expr = Context.parse(exprStr, arg.pos); + result.push(macro $buf.add($expr)); + } + + lastIndex = matchPos.pos + matchPos.len; + isFirst = false; + } + + var remaining = original.substring(lastIndex); + if (remaining.length > 0) { + if (remaining.charAt(remaining.length - 1) == '"' || remaining.charAt(remaining.length - 1) == "'".charAt(0)) { + remaining = remaining.substr(0, remaining.length - 1); + } + if (remaining.length > 0) { + remaining = escapeString(remaining); + result.push(macro $buf.add($v{remaining})); + } + } + + return result.length > 0 ? result : null; + } + + static function escapeString(s:String):String { + var r = new StringBuf(); + var i = 0; + while (i < s.length) { + var c = s.charAt(i); + if (c == "\\" && i + 1 < s.length) { + var next = s.charAt(i + 1); + switch (next) { + case "n": r.add("\n"); i += 2; continue; + case "t": r.add("\t"); i += 2; continue; + case "r": r.add("\r"); i += 2; continue; + case "\\": r.add("\\"); i += 2; continue; + case '"': r.add('"'); i += 2; continue; + default: r.add(c); i++; + } + } else { + r.add(c); + i++; + } + } + return r.toString(); + } + #end +} \ No newline at end of file