From 37cd5ef677510b7522ba8f841f32d800c398a4ec Mon Sep 17 00:00:00 2001
From: Yoshman29 <81191621+YoshiCrafter29@users.noreply.github.com>
Date: Wed, 25 Jan 2023 03:24:47 +0100
Subject: [PATCH] new framerate counter
---
Project.xml | 6 +-
buildnumber.txt | 2 +-
hmm.json | 5 +
source/funkin/mods/ModsFolderLibrary.hx | 14 ++-
source/funkin/options/OptionsMenu.hx | 2 +-
source/funkin/system/AssetsLibraryList.hx | 21 +---
source/funkin/system/FramerateField.hx | 115 ------------------
source/funkin/system/Main.hx | 5 +-
.../funkin/system/framerate/AssetTreeInfo.hx | 36 ++++++
.../system/framerate/CodenameBuildField.hx | 15 +++
.../funkin/system/framerate/ConductorInfo.hx | 20 +++
source/funkin/system/framerate/Framerate.hx | 101 +++++++++++++++
.../system/framerate/FramerateCategory.hx | 52 ++++++++
.../system/framerate/FramerateCounter.hx | 38 ++++++
.../funkin/system/framerate/MemoryCounter.hx | 43 +++++++
source/funkin/system/framerate/StatsInfo.hx | 21 ++++
source/funkin/system/framerate/SystemInfo.hx | 20 +++
source/funkin/utils/MemoryUtil.hx | 17 +++
18 files changed, 395 insertions(+), 138 deletions(-)
delete mode 100644 source/funkin/system/FramerateField.hx
create mode 100644 source/funkin/system/framerate/AssetTreeInfo.hx
create mode 100644 source/funkin/system/framerate/CodenameBuildField.hx
create mode 100644 source/funkin/system/framerate/ConductorInfo.hx
create mode 100644 source/funkin/system/framerate/Framerate.hx
create mode 100644 source/funkin/system/framerate/FramerateCategory.hx
create mode 100644 source/funkin/system/framerate/FramerateCounter.hx
create mode 100644 source/funkin/system/framerate/MemoryCounter.hx
create mode 100644 source/funkin/system/framerate/StatsInfo.hx
create mode 100644 source/funkin/system/framerate/SystemInfo.hx
diff --git a/Project.xml b/Project.xml
index 03373c78..dca9035c 100644
--- a/Project.xml
+++ b/Project.xml
@@ -128,10 +128,14 @@
+
+
+
+
@@ -149,7 +153,7 @@
-
+
diff --git a/buildnumber.txt b/buildnumber.txt
index efed77e1..0fb5907f 100644
--- a/buildnumber.txt
+++ b/buildnumber.txt
@@ -1 +1 @@
-2152
\ No newline at end of file
+2190
\ No newline at end of file
diff --git a/hmm.json b/hmm.json
index a20ce299..52aea2a2 100644
--- a/hmm.json
+++ b/hmm.json
@@ -41,6 +41,11 @@
"type": "haxelib",
"version": "2.5.1"
},
+ {
+ "name": "hxcpp-debug-server",
+ "type": "haxelib",
+ "version": null
+ },
{
"name": "lime",
"type": "haxelib",
diff --git a/source/funkin/mods/ModsFolderLibrary.hx b/source/funkin/mods/ModsFolderLibrary.hx
index a7f809ef..26fe3d6d 100644
--- a/source/funkin/mods/ModsFolderLibrary.hx
+++ b/source/funkin/mods/ModsFolderLibrary.hx
@@ -132,8 +132,18 @@ class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
private function __isCacheValid(cache:Map, asset:String, isLocalCache:Bool = false) {
if (!editedTimes.exists(asset))
return false;
- if (editedTimes[asset] == null) return false;
- if (editedTimes[asset] < FileSystem.stat(getPath(asset)).mtime.getTime()) return false;
+ if (editedTimes[asset] == null || editedTimes[asset] < FileSystem.stat(getPath(asset)).mtime.getTime()) {
+ // destroy already existing to prevent memory leak!!!
+ var asset = cache[asset];
+ if (asset != null) {
+ switch(Type.getClass(asset)) {
+ case lime.graphics.Image:
+ trace("getting rid of image cause replaced");
+ cast(asset, lime.graphics.Image);
+ }
+ }
+ return false;
+ }
if (!isLocalCache) asset = '$libName:$asset';
diff --git a/source/funkin/options/OptionsMenu.hx b/source/funkin/options/OptionsMenu.hx
index ff040c06..13bc89e0 100644
--- a/source/funkin/options/OptionsMenu.hx
+++ b/source/funkin/options/OptionsMenu.hx
@@ -103,7 +103,7 @@ class OptionsMenu extends MusicBeatState {
public function changeSelection(change:Int) {
if (change == 0) return;
- CoolUtil.playMenuSFX(CANCEL, 0.7);
+ CoolUtil.playMenuSFX(SCROLL, 0.7);
curSelected = FlxMath.wrap(curSelected + change, 0, options.length-1);
alphabets.forEach(function(e) {
e.alpha = 0.6;
diff --git a/source/funkin/system/AssetsLibraryList.hx b/source/funkin/system/AssetsLibraryList.hx
index e9b370cc..e9d7bde0 100644
--- a/source/funkin/system/AssetsLibraryList.hx
+++ b/source/funkin/system/AssetsLibraryList.hx
@@ -95,12 +95,12 @@ class AssetsLibraryList extends AssetLibrary {
public function getSpecificAsset(id:String, type:String, source:AssetSource = BOTH):Dynamic {
try {
- MemoryUtil.disable();
+ MemoryUtil.askDisable();
if (!id.startsWith("assets/")) {
var ass = getSpecificAsset('assets/$id', type, source);
if (ass != null) {
- MemoryUtil.enable();
+ MemoryUtil.askEnable();
return ass;
}
}
@@ -109,15 +109,15 @@ class AssetsLibraryList extends AssetLibrary {
var asset = e.getAsset(id, type);
if (asset != null) {
- MemoryUtil.enable();
+ MemoryUtil.askEnable();
return asset;
}
}
- MemoryUtil.enable();
+ MemoryUtil.askEnable();
return null;
} catch(e) {
- MemoryUtil.enable();
+ MemoryUtil.askEnable();
throw e;
}
return null;
@@ -162,17 +162,6 @@ class AssetsLibraryList extends AssetLibrary {
public override function isLocal(id:String, type:String) {
return true;
- // for(l in libraries) {
- // var lib:AssetLibrary = l;
- // if (lib is openfl.utils.AssetLibrary) {
- // var openflLib = cast(lib, openfl.utils.AssetLibrary);
- // @:privateAccess
- // if (openflLib.__proxy != null) lib = openflLib.__proxy;
- // }
- // if (lib.exists(id, type) && lib.isLocal(id, type))
- // return true;
- // }
- // return false;
}
public function new(?base:AssetLibrary) {
diff --git a/source/funkin/system/FramerateField.hx b/source/funkin/system/FramerateField.hx
deleted file mode 100644
index db5f1621..00000000
--- a/source/funkin/system/FramerateField.hx
+++ /dev/null
@@ -1,115 +0,0 @@
-package funkin.system;
-
-import funkin.mods.ModsAssetLibrary;
-import lime.ui.KeyCode;
-import openfl.ui.Keyboard;
-import openfl.events.KeyboardEvent;
-import openfl.text.TextField;
-import openfl.text.TextFormat;
-import openfl.system.System;
-import openfl.display.Application;
-import flixel.math.FlxMath;
-import flixel.FlxG;
-import openfl.display._internal.stats.Context3DStats;
-import openfl.display._internal.stats.DrawCallContext;
-
-class FramerateField extends TextField {
- public var showFPS:Bool = true;
- public var showMemory:Bool = true;
- public var showMemoryPeak:Bool = true;
-
- /**
- * Press F3 to enable
- */
- public var debugMode:Bool = false;
-
- public var peak:Float = 0;
- public var lastFPS:Float = 0;
-
- public function new(x:Float = 10, y:Float = 10, color:Int = 0x000000)
- {
- super();
-
- this.x = x;
- this.y = y;
-
- selectable = false;
- mouseEnabled = false;
- defaultTextFormat = new TextFormat("_sans", 12, color);
- autoSize = LEFT;
-
- #if flash
- addEventListener(Event.ENTER_FRAME, function(e)
- {
- var time = Lib.getTimer();
- __enterFrame(time - currentTime);
- });
- #end
-
- FlxG.stage.addEventListener(KeyboardEvent.KEY_UP, function(e:KeyboardEvent) {
- switch(e.keyCode) {
- case #if web Keyboard.NUMBER_3 #else Keyboard.F3 #end: // 3 on web or F3 on windows, linux and other things that runs code
- debugMode = !debugMode;
- }
- });
- }
-
- public override function __enterFrame(t:Float) {
- var text = [];
- if (showFPS || debugMode) {
- lastFPS = CoolUtil.fpsLerp(lastFPS, FlxG.elapsed == 0 ? 0 : (1 / FlxG.elapsed), 0.25);
- text.push('FPS: ${Std.int(lastFPS)}');
- }
- #if !web
- var totalMemory = MemoryUtil.currentMemUsage();
- if (showMemory || debugMode) {
- text.push('RAM: ${CoolUtil.getSizeString(totalMemory)}');
- }
- if (showMemoryPeak || debugMode) {
- if (peak < totalMemory)
- peak = totalMemory;
- text.push('RAM PEAK: (${CoolUtil.getSizeString(peak)})');
- }
- #end
- #if !release
- text.push('CODENAME ENGINE BETA - BUILD ${funkin.macros.BuildCounterMacro.getBuildNumber()}');
- #end
- if (debugMode) {
- text.push('=== CONDUCTOR INFO ===');
- text.push('Current Song Position: ${Conductor.songPosition} (${Conductor.curBeat} beats - ${Conductor.curStep} steps)');
- text.push('Current BPM: ${Conductor.bpm}');
- text.push('Current speed: ${FlxMath.roundDecimal(Conductor.speed, 2)}x');
- text.push('=== SYSTEM INFO ===');
- text.push('System: ${lime.system.System.platformLabel} ${lime.system.System.platformVersion}');
- text.push('Objs in state: ${FlxG.state.members.length}');
- text.push('Nb cameras: ${FlxG.cameras.list.length}');
- text.push('Current state: ${Type.getClassName(Type.getClass(FlxG.state))}');
- text.push('=== ASSET LIBRARIES TREE ===');
- if (Paths.assetsTree == null)
- text.push('Not initialized yet');
- else {
- for(e in Paths.assetsTree.libraries) {
- var l = e;
- if (l is openfl.utils.AssetLibrary) {
- var al = cast(l, openfl.utils.AssetLibrary);
- @:privateAccess
- if (al.__proxy != null) l = al.__proxy;
- }
-
- if (l is ModsAssetLibrary)
- text.push('${Type.getClassName(Type.getClass(l))} - ${cast(l, ModsAssetLibrary).libName} (${cast(l, ModsAssetLibrary).prefix})');
- else
- text.push(Std.string(e));
- }
- }
- #if (gl_stats && !disable_cffi && (!html5 || !canvas))
- text.push('=== STATS ===');
- text.push("totalDC: " + Context3DStats.totalDrawCalls());
- text.push("stageDC: " + Context3DStats.contextDrawCalls(DrawCallContext.STAGE));
- text.push("stage3DDC: " + Context3DStats.contextDrawCalls(DrawCallContext.STAGE3D));
- #end
-
- }
- this.text = text.join("\n");
- }
-}
\ No newline at end of file
diff --git a/source/funkin/system/Main.hx b/source/funkin/system/Main.hx
index 6812677f..6ba869fd 100644
--- a/source/funkin/system/Main.hx
+++ b/source/funkin/system/Main.hx
@@ -104,7 +104,8 @@ class Main extends Sprite
FlxG.switchState(new funkin.menus.BetaWarningState());
#if !mobile
- addChild(new FramerateField(10, 3, 0xFFFFFF));
+ // addChild(new FramerateField(10, 3, 0xFFFFFF));
+ addChild(new funkin.system.framerate.Framerate());
#end
}
@@ -245,7 +246,7 @@ class Main extends Sprite
Paths.assetsTree.clearCache();
- // MemoryUtil.destroyFlixelZombies();
+ MemoryUtil.clearMinor();
MemoryUtil.clearMajor();
}
}
diff --git a/source/funkin/system/framerate/AssetTreeInfo.hx b/source/funkin/system/framerate/AssetTreeInfo.hx
new file mode 100644
index 00000000..eb57f7b2
--- /dev/null
+++ b/source/funkin/system/framerate/AssetTreeInfo.hx
@@ -0,0 +1,36 @@
+package funkin.system.framerate;
+
+import funkin.mods.ModsAssetLibrary;
+import flixel.FlxG;
+import flixel.math.FlxMath;
+
+class AssetTreeInfo extends FramerateCategory {
+ public function new() {
+ super("Asset Libraries Tree Info");
+ }
+
+ public override function __enterFrame(t:Int) {
+ var text = 'Not initialized yet\n';
+ if (Paths.assetsTree != null){
+ text = "";
+ for(e in Paths.assetsTree.libraries) {
+ var l = e;
+ if (l is openfl.utils.AssetLibrary) {
+ var al = cast(l, openfl.utils.AssetLibrary);
+ @:privateAccess
+ if (al.__proxy != null) l = al.__proxy;
+ }
+
+ if (l is ModsAssetLibrary)
+ text += '${Type.getClassName(Type.getClass(l))} - ${cast(l, ModsAssetLibrary).libName} (${cast(l, ModsAssetLibrary).prefix})\n';
+ else
+ text += Std.string(e) + "\n";
+ }
+ }
+ if (text != "")
+ text = text.substr(0, text.length-1);
+
+ this.text.text = text;
+ super.__enterFrame(t);
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/system/framerate/CodenameBuildField.hx b/source/funkin/system/framerate/CodenameBuildField.hx
new file mode 100644
index 00000000..05c411a0
--- /dev/null
+++ b/source/funkin/system/framerate/CodenameBuildField.hx
@@ -0,0 +1,15 @@
+package funkin.system.framerate;
+
+import openfl.text.TextFormat;
+import openfl.display.Sprite;
+import openfl.text.TextField;
+
+class CodenameBuildField extends TextField {
+ public function new() {
+ super();
+ defaultTextFormat = Framerate.textFormat;
+ autoSize = LEFT;
+ multiline = wordWrap = false;
+ text = 'Codename Engine Beta\nBuild ${funkin.macros.BuildCounterMacro.getBuildNumber()}';
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/system/framerate/ConductorInfo.hx b/source/funkin/system/framerate/ConductorInfo.hx
new file mode 100644
index 00000000..ddbb796e
--- /dev/null
+++ b/source/funkin/system/framerate/ConductorInfo.hx
@@ -0,0 +1,20 @@
+package funkin.system.framerate;
+
+import flixel.math.FlxMath;
+
+class ConductorInfo extends FramerateCategory {
+ public function new() {
+ super("Conductor Info");
+ }
+
+ public override function __enterFrame(t:Int) {
+ var text = 'Current Song Position: ${Conductor.songPosition}';
+ text += '\n - ${Conductor.curBeat} beats';
+ text += '\n - ${Conductor.curStep} steps';
+ text += '\nCurrent BPM: ${Conductor.bpm}';
+ text += '\nCurrent speed: ${FlxMath.roundDecimal(Conductor.speed, 2)}x';
+
+ this.text.text = text;
+ super.__enterFrame(t);
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/system/framerate/Framerate.hx b/source/funkin/system/framerate/Framerate.hx
new file mode 100644
index 00000000..21f29d67
--- /dev/null
+++ b/source/funkin/system/framerate/Framerate.hx
@@ -0,0 +1,101 @@
+package funkin.system.framerate;
+
+import flixel.math.FlxMath;
+import openfl.events.KeyboardEvent;
+import openfl.display.DisplayObject;
+import openfl.display.Sprite;
+import openfl.text.TextField;
+import openfl.text.TextFormat;
+import openfl.ui.Keyboard;
+import flixel.FlxG;
+
+class Framerate extends Sprite {
+ public static var instance:Framerate;
+
+ public static var textFormat:TextFormat;
+ public static var fpsCounter:FramerateCounter;
+ public static var memoryCounter:MemoryCounter;
+ #if SHOW_BUILD_ON_FPS
+ public static var codenameBuildField:CodenameBuildField;
+ #end
+
+ public static var fontName:String = #if windows '${Sys.getEnv("windir")}\\Fonts\\consola.ttf' #else "_sans" #end;
+
+ public static var debugMode:Bool = false;
+
+ public var bgSprite:Sprite;
+
+ public var categories:Array = [];
+
+ public function new() {
+ super();
+ if (instance != null) throw "Cannot create another instance";
+ instance = this;
+ textFormat = new TextFormat("Consolas", 12, -1);
+
+ x = 10;
+ y = 2;
+
+ FlxG.stage.addEventListener(KeyboardEvent.KEY_UP, function(e:KeyboardEvent) {
+ switch(e.keyCode) {
+ case #if web Keyboard.NUMBER_3 #else Keyboard.F3 #end: // 3 on web or F3 on windows, linux and other things that runs code
+ debugMode = !debugMode;
+ }
+ });
+
+ bgSprite = new Sprite();
+ bgSprite.graphics.beginFill(0xFF000000);
+ bgSprite.graphics.drawRect(0, 0, 1, 1);
+ bgSprite.graphics.endFill();
+ bgSprite.alpha = 0;
+ addChild(bgSprite);
+
+ __addToList(fpsCounter = new FramerateCounter());
+ __addToList(memoryCounter = new MemoryCounter());
+ #if SHOW_BUILD_ON_FPS
+ __addToList(codenameBuildField = new CodenameBuildField());
+ #end
+ __addCategory(new ConductorInfo());
+ __addCategory(new SystemInfo());
+ __addCategory(new AssetTreeInfo());
+
+ #if (gl_stats && !disable_cffi && (!html5 || !canvas))
+ __addCategory(new StatsInfo());
+ #end
+ }
+
+ private function __addCategory(category:FramerateCategory) {
+ categories.push(category);
+ __addToList(category);
+ }
+ private var __lastAddedSprite:DisplayObject = null;
+ private function __addToList(spr:DisplayObject) {
+ spr.x = 0;
+ spr.y = __lastAddedSprite != null ? (__lastAddedSprite.y + __lastAddedSprite.height) : 4;
+ __lastAddedSprite = spr;
+ addChild(spr);
+ }
+
+
+ var debugAlpha:Float = 0;
+ public override function __enterFrame(t:Int) {
+ super.__enterFrame(t);
+ debugAlpha = CoolUtil.fpsLerp(debugAlpha, debugMode ? 1 : 0, 1);
+ bgSprite.alpha = debugAlpha * 0.5;
+
+ var width = Math.max(fpsCounter.width, #if SHOW_BUILD_ON_FPS Math.max(memoryCounter.width, codenameBuildField.width) #else memoryCounter.width #end) + (x*2);
+ var height = #if SHOW_BUILD_ON_FPS codenameBuildField.y + codenameBuildField.height #else memoryCounter.y + memoryCounter.height #end;
+ bgSprite.x = -x;
+ bgSprite.scaleX = width;
+ bgSprite.scaleY = height;
+
+ var y:Float = height + 4;
+
+ for(c in categories) {
+ c.alpha = debugAlpha;
+ c.x = FlxMath.lerp(-c.width, 0, debugAlpha);
+ c.y = y;
+ y = c.y + c.height + 4;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/system/framerate/FramerateCategory.hx b/source/funkin/system/framerate/FramerateCategory.hx
new file mode 100644
index 00000000..dc88d46e
--- /dev/null
+++ b/source/funkin/system/framerate/FramerateCategory.hx
@@ -0,0 +1,52 @@
+package funkin.system.framerate;
+
+import flixel.FlxG;
+import openfl.text.TextFormat;
+import openfl.display.Sprite;
+import openfl.text.TextField;
+
+class FramerateCategory extends Sprite {
+ public var title:TextField;
+ public var text:TextField;
+
+ public var bgSprite:Sprite;
+
+ public function new(title:String, text:String = "") {
+ super();
+
+ x = 10;
+ this.title = new TextField();
+ this.text = new TextField();
+
+ bgSprite = new Sprite();
+ bgSprite.graphics.beginFill(0xFF000000);
+ bgSprite.graphics.drawRect(0, 0, 1, 1);
+ bgSprite.graphics.endFill();
+ bgSprite.alpha = 0.5;
+ addChild(bgSprite);
+
+ for(label in [this.title, this.text]) {
+ label.autoSize = LEFT;
+ label.x = 0;
+ label.y = 0;
+ label.defaultTextFormat = new TextFormat(Framerate.fontName, label == this.title ? 18 : 12, -1);
+ addChild(label);
+ }
+ this.title.text = title;
+ this.title.multiline = this.title.wordWrap = false;
+ this.text.multiline = true;
+
+
+ this.text.y = this.title.y + this.title.height + 2;
+ }
+
+ public override function __enterFrame(t:Int) {
+ super.__enterFrame(t);
+
+ var width = Math.max(this.title.width, this.text.width) + (Framerate.instance.x * 2);
+ var height = this.text.height + this.text.y;
+ bgSprite.x = -Framerate.instance.x;
+ bgSprite.scaleX = width;
+ bgSprite.scaleY = height;
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/system/framerate/FramerateCounter.hx b/source/funkin/system/framerate/FramerateCounter.hx
new file mode 100644
index 00000000..c1d0007c
--- /dev/null
+++ b/source/funkin/system/framerate/FramerateCounter.hx
@@ -0,0 +1,38 @@
+package funkin.system.framerate;
+
+import flixel.FlxG;
+import openfl.text.TextFormat;
+import openfl.display.Sprite;
+import openfl.text.TextField;
+
+class FramerateCounter extends Sprite {
+ public var fpsNum:TextField;
+ public var fpsLabel:TextField;
+ public var lastFPS:Float = 0;
+
+ public function new() {
+ super();
+
+ fpsNum = new TextField();
+ fpsLabel = new TextField();
+
+ for(label in [fpsNum, fpsLabel]) {
+ label.autoSize = LEFT;
+ label.x = 0;
+ label.y = 0;
+ label.text = "FPS";
+ label.multiline = label.wordWrap = false;
+ label.defaultTextFormat = new TextFormat(Framerate.fontName, label == fpsNum ? 18 : 12, -1);
+ addChild(label);
+ }
+ }
+
+ public override function __enterFrame(t:Int) {
+ super.__enterFrame(t);
+
+ lastFPS = CoolUtil.fpsLerp(lastFPS, FlxG.elapsed == 0 ? 0 : (1 / FlxG.elapsed), 0.25);
+ fpsNum.text = Std.string(Math.floor(lastFPS));
+ fpsLabel.x = fpsNum.x + fpsNum.width;
+ fpsLabel.y = (fpsNum.y + fpsNum.height) - fpsLabel.height;
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/system/framerate/MemoryCounter.hx b/source/funkin/system/framerate/MemoryCounter.hx
new file mode 100644
index 00000000..43ba5dca
--- /dev/null
+++ b/source/funkin/system/framerate/MemoryCounter.hx
@@ -0,0 +1,43 @@
+package funkin.system.framerate;
+
+import flixel.FlxG;
+import openfl.text.TextFormat;
+import openfl.display.Sprite;
+import openfl.text.TextField;
+
+class MemoryCounter extends Sprite {
+ public var memoryText:TextField;
+ public var memoryPeakText:TextField;
+
+ public var memory:Float = 0;
+ public var memoryPeak:Float = 0;
+
+ public function new() {
+ super();
+
+ memoryText = new TextField();
+ memoryPeakText = new TextField();
+
+ for(label in [memoryText, memoryPeakText]) {
+ label.autoSize = LEFT;
+ label.x = 0;
+ label.y = 0;
+ label.text = "FPS";
+ label.multiline = label.wordWrap = false;
+ label.defaultTextFormat = new TextFormat(Framerate.fontName, 12, -1);
+ addChild(label);
+ }
+ memoryPeakText.alpha = 0.5;
+ }
+
+ public override function __enterFrame(t:Int) {
+ super.__enterFrame(t);
+
+ memory = MemoryUtil.currentMemUsage();
+ if (memoryPeak < memory) memoryPeak = memory;
+ memoryText.text = CoolUtil.getSizeString(memory);
+ memoryPeakText.text = ' / ${CoolUtil.getSizeString(memoryPeak)}';
+
+ memoryPeakText.x = memoryText.x + memoryText.width;
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/system/framerate/StatsInfo.hx b/source/funkin/system/framerate/StatsInfo.hx
new file mode 100644
index 00000000..9bd84a7f
--- /dev/null
+++ b/source/funkin/system/framerate/StatsInfo.hx
@@ -0,0 +1,21 @@
+package funkin.system.framerate;
+
+#if (gl_stats && !disable_cffi && (!html5 || !canvas))
+import openfl.display._internal.stats.Context3DStats;
+import openfl.display._internal.stats.DrawCallContext;
+
+class StatsInfo extends FramerateCategory {
+ public function new() {
+ super("Asset Libraries Tree Info");
+ }
+
+ public override function __enterFrame(t:Int) {
+ var text = "totalDC: " + Context3DStats.totalDrawCalls();
+ text += "\nstageDC: " + Context3DStats.contextDrawCalls(DrawCallContext.STAGE);
+ text += "\nstage3DDC: " + Context3DStats.contextDrawCalls(DrawCallContext.STAGE3D);
+
+ this.text.text = text;
+ super.__enterFrame(t);
+ }
+}
+#end
\ No newline at end of file
diff --git a/source/funkin/system/framerate/SystemInfo.hx b/source/funkin/system/framerate/SystemInfo.hx
new file mode 100644
index 00000000..ef7dc668
--- /dev/null
+++ b/source/funkin/system/framerate/SystemInfo.hx
@@ -0,0 +1,20 @@
+package funkin.system.framerate;
+
+import flixel.FlxG;
+import flixel.math.FlxMath;
+
+class SystemInfo extends FramerateCategory {
+ public function new() {
+ super("System Info");
+ }
+
+ public override function __enterFrame(t:Int) {
+ var text = 'System: ${lime.system.System.platformLabel} ${lime.system.System.platformVersion}';
+ text += '\nObjs in state: ${FlxG.state.members.length}';
+ text += '\nNb cameras: ${FlxG.cameras.list.length}';
+ text += '\nCurrent state: ${Type.getClassName(Type.getClass(FlxG.state))}';
+
+ this.text.text = text;
+ super.__enterFrame(t);
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/utils/MemoryUtil.hx b/source/funkin/utils/MemoryUtil.hx
index e056d050..e1a05425 100644
--- a/source/funkin/utils/MemoryUtil.hx
+++ b/source/funkin/utils/MemoryUtil.hx
@@ -12,6 +12,23 @@ import neko.vm.Gc;
import openfl.system.System;
class MemoryUtil {
+ public static var disableCount:Int = 0;
+
+ public static function askDisable() {
+ disableCount++;
+ if (disableCount > 0)
+ disable();
+ else
+ enable();
+ }
+ public static function askEnable() {
+ disableCount--;
+ if (disableCount > 0)
+ disable();
+ else
+ enable();
+ }
+
public static function init() {
#if cpp
#end