diff --git a/.github/actions/setup-haxeshit/action.yml b/.github/actions/setup-haxeshit/action.yml index 9c1fae0b1..236d29944 100644 --- a/.github/actions/setup-haxeshit/action.yml +++ b/.github/actions/setup-haxeshit/action.yml @@ -3,21 +3,46 @@ description: "sets up haxe shit, using HMM!" runs: using: "composite" steps: - - uses: funkincrew/ci-haxe@v3 + - name: Install Haxe lol + uses: funkincrew/ci-haxe@v3.1.0 with: haxe-version: 4.3.3 - name: Config haxelib run: | - haxelib config + haxelib --never install haxelib 4.1.0 --global + haxelib --never deleterepo || true + haxelib --never newrepo + echo "HAXEPATH=$(haxelib config)" >> "$GITHUB_ENV" + haxelib --never git haxelib https://github.com/HaxeFoundation/haxelib.git master shell: bash - - name: Installing Haxe lol + - name: Gather debug info + run: | + cat << EOF >> "$GITHUB_STEP_SUMMARY" + ## haxe + - version: \`$(haxe -version)\` + - exe: \`$(which haxe)\` + ## haxelib + - version: \`$(haxelib version)\` + - exe: \`$(which haxelib)\` + - path: \`$HAXEPATH\` + ### local + - config: \`$(haxelib config)\` + - path: \`$(haxelib path haxelib || true)\` + ### global + - config: \`$(haxelib config --global)\` + - path: \`$(haxelib path haxelib --global || true)\` + ### system + - version: \`$(haxelib --system version)\` + - local: \`$(haxelib --system config)\` + - global: \`$(haxelib --system config --global)\` + EOF + shell: bash + - name: Install hmm + # hmm only supports global installs run: | - haxe -version - haxelib git haxelib https://github.com/HaxeFoundation/haxelib.git master - haxelib version haxelib --global install hmm shell: bash - - name: dependency install cache + - name: Restore cached dependencies id: cache-hmm uses: actions/cache@v4 with: diff --git a/.github/workflows/build-shit.yml b/.github/workflows/build-shit.yml index 388670a01..5a1f5609a 100644 --- a/.github/workflows/build-shit.yml +++ b/.github/workflows/build-shit.yml @@ -8,71 +8,80 @@ jobs: runs-on: [self-hosted, linux] container: ubuntu:23.10 steps: - - name: prepare container + - name: Install tools missing in container run: | apt update - apt install sudo git curl unzip -y - git config --global --add safe.directory $GITHUB_WORKSPACE - - name: get token from gh app + apt install -y sudo git curl unzip + - name: Fix git config on posix runner + run: | + git config --global --add safe.directory ${{ github.workspace }} + - name: Get checkout token uses: actions/create-github-app-token@v1 id: app_token with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PEM }} owner: ${{ github.repository_owner }} - - name: checkout repo + - name: Checkout repo uses: funkincrew/ci-checkout@v6 with: submodules: 'recursive' token: ${{ steps.app_token.outputs.token }} - - uses: ./.github/actions/setup-haxeshit - - name: gather game dependencies + - name: Install Haxe, dependencies + uses: ./.github/actions/setup-haxeshit + - name: Install native dependencies run: | - sudo apt-get install -y libx11-dev xorg-dev libgl-dev libxi-dev libxext-dev libasound2-dev libxinerama-dev libxrandr-dev libgl1-mesa-dev - - name: build game + apt install -y \ + libx11-dev libxi-dev libxext-dev libxinerama-dev libxrandr-dev \ + libgl-dev libgl1-mesa-dev \ + libasound2-dev + - name: Build game run: | haxelib run lime build html5 -release --times -DGITHUB_BUILD - ls - - uses: ./.github/actions/upload-itch + - name: Upload build artifacts + uses: ./.github/actions/upload-itch with: butler-key: ${{ secrets.BUTLER_API_KEY}} build-dir: export/release/html5/bin target: html5 create-nightly-win: runs-on: [self-hosted, windows] + defaults: + run: + shell: bash steps: - - name: get token from gh app + - name: Get checkout token uses: actions/create-github-app-token@v1 id: app_token with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PEM }} owner: ${{ github.repository_owner }} - - name: checkout repo + - name: Checkout repo uses: funkincrew/ci-checkout@v6 with: submodules: 'recursive' token: ${{ steps.app_token.outputs.token }} - - uses: ./.github/actions/setup-haxeshit - - name: Make HXCPP cache dir + - name: Install Haxe, dependencies + uses: ./.github/actions/setup-haxeshit + - name: Setup build cache run: | - mkdir -p ${{ runner.temp }}\hxcpp_cache + mkdir -p ${{ runner.temp }}/hxcpp_cache - name: Restore build cache id: cache-build-win uses: actions/cache@v4 with: path: | - .haxelib export - ${{ runner.temp }}\hxcpp_cache - key: ${{ runner.os }}-build-win-${{ github.ref_name }}-${{ hashFiles('**/hmm.json') }} - - name: build game + ${{ runner.temp }}/hxcpp_cache + key: ${{ runner.os }}-build-win-${{ github.ref_name }} + - name: Build game run: | - haxelib run lime build windows -release -DNO_REDIRECT_ASSETS_FOLDER -DGITHUB_BUILD - dir + haxelib run lime build windows -v -release -DNO_REDIRECT_ASSETS_FOLDER -DGITHUB_BUILD env: HXCPP_COMPILE_CACHE: "${{ runner.temp }}\\hxcpp_cache" - - uses: ./.github/actions/upload-itch + - name: Upload build artifacts + uses: ./.github/actions/upload-itch with: butler-key: ${{ secrets.BUTLER_API_KEY }} build-dir: export/release/windows/bin @@ -80,78 +89,42 @@ jobs: create-nightly-mac: runs-on: [self-hosted, macos] steps: - - name: prepare container + - name: Fix git config on posix runner run: | - git config --global --add safe.directory $GITHUB_WORKSPACE - - name: get token from gh app + git config --global --add safe.directory ${{ github.workspace }} + - name: Get checkout token uses: actions/create-github-app-token@v1 id: app_token with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PEM }} owner: ${{ github.repository_owner }} - - name: checkout repo + - name: Checkout repo uses: funkincrew/ci-checkout@v6 with: submodules: 'recursive' token: ${{ steps.app_token.outputs.token }} - - uses: ./.github/actions/setup-haxeshit - - name: Make HXCPP cache dir + - name: Install Haxe, dependencies + uses: ./.github/actions/setup-haxeshit + - name: Setup build cache run: | mkdir -p ${{ runner.temp }}/hxcpp_cache - - name: restore build cache + - name: Restore build cache id: cache-build-win uses: actions/cache@v4 with: path: | - .haxelib export ${{ runner.temp }}/hxcpp_cache - key: ${{ runner.os }}-build-mac-${{ github.ref_name }}-${{ hashFiles('**/hmm.json') }} + key: ${{ runner.os }}-build-mac-${{ github.ref_name }} - name: Build game run: | haxelib run lime build macos -release --times -DGITHUB_BUILD - ls env: HXCPP_COMPILE_CACHE: "${{ runner.temp }}/hxcpp_cache" - - uses: ./.github/actions/upload-itch + - name: Upload build artifacts + uses: ./.github/actions/upload-itch with: butler-key: ${{ secrets.BUTLER_API_KEY}} build-dir: export/release/macos/bin target: macos - -# test-unit-win: -# needs: create-nightly-win -# runs-on: windows-latest -# steps: -# - name: get token from gh app -# uses: actions/create-github-app-token@v1 -# id: app_token -# with: -# app-id: ${{ vars.APP_ID }} -# private-key: ${{ secrets.APP_PEM }} -# owner: ${{ github.repository_owner }} -# - name: checkout repo -# uses: funkincrew/ci-checkout@v6 -# with: -# submodules: 'recursive' -# token: ${{ steps.app_token.outputs.token }} -# - name: Make HXCPP cache dir -# run: | -# mkdir -p ${{ runner.temp }}\hxcpp_cache -# - name: Restore build cache -# id: cache-build-win -# uses: actions/cache@v4 -# with: -# path: | -# .haxelib -# export -# ${{ runner.temp }}\hxcpp_cache -# key: ${{ runner.os }}-test-win-${{ github.ref_name }}-${{ hashFiles('**/hmm.json') }} -# - uses: ./.github/actions/setup-haxeshit -# - name: Run unit tests -# run: | -# cd ./tests/unit/ -# ./start-win-native.bat -# env: -# HXCPP_COMPILE_CACHE: "${{ runner.temp }}\\hxcpp_cache" diff --git a/.gitignore b/.gitignore index 34a0c5590..87fd97fc5 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ dump/ export/ RECOVER_*.fla shitAudio/ +.build_time diff --git a/assets b/assets index 8b914574f..b152ad838 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 8b914574fc4724c5fe483f4f9d81081bb1518c12 +Subproject commit b152ad83868ff77307abb24893ddd5f74ed324d7 diff --git a/source/Postbuild.hx b/source/Postbuild.hx index d48b670a4..f1827c4ab 100644 --- a/source/Postbuild.hx +++ b/source/Postbuild.hx @@ -1,11 +1,37 @@ package source; // Yeah, I know... +import sys.FileSystem; +import sys.io.File; + class Postbuild { + static inline final buildTimeFile = '.build_time'; + static function main() { - trace('Postbuild'); + printBuildTime(); + } - // TODO: Maybe put a 'Build took X seconds' message here? + static function printBuildTime() + { + // get buildEnd before fs operations since they are blocking + var end:Float = Sys.time(); + if (FileSystem.exists(buildTimeFile)) + { + var fi = File.read(buildTimeFile); + var start:Float = fi.readDouble(); + fi.close(); + + sys.FileSystem.deleteFile(buildTimeFile); + + var buildTime = roundToTwoDecimals(end - start); + + trace('Build took: ${buildTime} seconds'); + } + } + + private static function roundToTwoDecimals(value:Float):Float + { + return Math.round(value * 100) / 100; } } diff --git a/source/Prebuild.hx b/source/Prebuild.hx index 63782fc56..18a5e2076 100644 --- a/source/Prebuild.hx +++ b/source/Prebuild.hx @@ -1,9 +1,22 @@ package source; // Yeah, I know... +import sys.io.File; + class Prebuild { + static inline final buildTimeFile = '.build_time'; + static function main() { - trace('Prebuild'); + saveBuildTime(); + trace('Building...'); + } + + static function saveBuildTime() + { + var fo = File.write(buildTimeFile); + var now = Sys.time(); + fo.writeDouble(now); + fo.close(); } } diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index 7dc20b385..2368d09f2 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -30,6 +30,7 @@ import funkin.modding.module.ModuleHandler; import funkin.ui.title.TitleState; import funkin.util.CLIUtil; import funkin.util.CLIUtil.CLIParams; +import funkin.util.tools.TimerTools; import funkin.ui.transition.LoadingState; #if discord_rpc import Discord.DiscordClient; @@ -219,7 +220,7 @@ class InitState extends FlxState // NOTE: Registries must be imported and not referenced with fully qualified names, // to ensure build macros work properly. trace('Parsing game data...'); - var perfStart = haxe.Timer.stamp(); + var perfStart:Float = TimerTools.start(); SongEventRegistry.loadEventCache(); // SongEventRegistry is structured differently so it's not a BaseRegistry. SongRegistry.instance.loadEntries(); LevelRegistry.instance.loadEntries(); @@ -236,9 +237,7 @@ class InitState extends FlxState ModuleHandler.loadModuleCache(); ModuleHandler.callOnCreate(); - var perfEnd = haxe.Timer.stamp(); - - trace('Parsing game data took ${Math.floor((perfEnd - perfStart) * 1000)}ms.'); + trace('Parsing game data took: ${TimerTools.ms(perfStart)}'); } /** diff --git a/source/funkin/audio/visualize/SpectogramSprite.hx b/source/funkin/audio/visualize/SpectogramSprite.hx index b4e024a4c..470dbf7fe 100644 --- a/source/funkin/audio/visualize/SpectogramSprite.hx +++ b/source/funkin/audio/visualize/SpectogramSprite.hx @@ -10,7 +10,6 @@ import flixel.util.FlxColor; import funkin.audio.visualize.PolygonSpectogram.VISTYPE; import funkin.audio.visualize.VisShit.CurAudioInfo; import funkin.audio.visualize.dsp.FFT; -import haxe.Timer; import lime.system.ThreadPool; import lime.utils.Int16Array; diff --git a/source/funkin/audio/visualize/VisShit.hx b/source/funkin/audio/visualize/VisShit.hx index 5bfb8c7c5..204ced1e1 100644 --- a/source/funkin/audio/visualize/VisShit.hx +++ b/source/funkin/audio/visualize/VisShit.hx @@ -3,7 +3,6 @@ package funkin.audio.visualize; import flixel.math.FlxMath; import flixel.sound.FlxSound; import funkin.audio.visualize.dsp.FFT; -import haxe.Timer; import lime.system.ThreadPool; import lime.utils.Int16Array; import funkin.util.MathUtil; diff --git a/source/funkin/audio/waveform/WaveformDataParser.hx b/source/funkin/audio/waveform/WaveformDataParser.hx index 54a142f6a..c667f2002 100644 --- a/source/funkin/audio/waveform/WaveformDataParser.hx +++ b/source/funkin/audio/waveform/WaveformDataParser.hx @@ -1,5 +1,7 @@ package funkin.audio.waveform; +import funkin.util.tools.TimerTools; + class WaveformDataParser { static final INT16_MAX:Int = 32767; @@ -71,7 +73,7 @@ class WaveformDataParser var outputData:Array = []; - var perfStart = haxe.Timer.stamp(); + var perfStart:Float = TimerTools.start(); for (pointIndex in 0...outputPointCount) { @@ -108,8 +110,7 @@ class WaveformDataParser var outputDataLength:Int = Std.int(outputData.length / channels / 2); var result = new WaveformData(null, channels, sampleRate, samplesPerPoint, bitsPerSample, outputPointCount, outputData); - var perfEnd = haxe.Timer.stamp(); - trace('[WAVEFORM] Interpreted audio buffer in ${perfEnd - perfStart} seconds.'); + trace('[WAVEFORM] Interpreted audio buffer in ${TimerTools.seconds(perfStart)}.'); return result; } diff --git a/source/funkin/play/GameOverSubState.hx b/source/funkin/play/GameOverSubState.hx index b7e92d10f..857cda524 100644 --- a/source/funkin/play/GameOverSubState.hx +++ b/source/funkin/play/GameOverSubState.hx @@ -338,8 +338,8 @@ class GameOverSubState extends MusicBeatSubState } else { - isStarting = false; onComplete = function() { + isStarting = false; // We need to force to ensure that the non-starting music plays. startDeathMusic(1.0, true); }; diff --git a/source/funkin/play/components/PopUpStuff.hx b/source/funkin/play/components/PopUpStuff.hx index faab5e4dc..0fe50f513 100644 --- a/source/funkin/play/components/PopUpStuff.hx +++ b/source/funkin/play/components/PopUpStuff.hx @@ -3,9 +3,10 @@ package funkin.play.components; import flixel.FlxSprite; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.tweens.FlxTween; +import flixel.util.FlxDirection; import funkin.graphics.FunkinSprite; import funkin.play.PlayState; -import flixel.util.FlxDirection; +import funkin.util.tools.TimerTools; class PopUpStuff extends FlxTypedGroup { @@ -16,9 +17,7 @@ class PopUpStuff extends FlxTypedGroup public function displayRating(daRating:String) { - #if sys - var perfStart:Float = Sys.time(); - #end + var perfStart:Float = TimerTools.start(); if (daRating == null) daRating = "good"; @@ -60,17 +59,12 @@ class PopUpStuff extends FlxTypedGroup startDelay: Conductor.instance.beatLengthMs * 0.001 }); - #if sys - var perfEnd:Float = Sys.time(); - trace("displayRating took: " + (perfEnd - perfStart)); - #end + trace('displayRating took: ${TimerTools.seconds(perfStart)}'); } public function displayCombo(?combo:Int = 0):Int { - #if sys - var perfStart:Float = Sys.time(); - #end + var perfStart:Float = TimerTools.start(); if (combo == null) combo = 0; @@ -163,10 +157,7 @@ class PopUpStuff extends FlxTypedGroup daLoop++; } - #if sys - var perfEnd:Float = Sys.time(); - trace("displayCombo took: " + (perfEnd - perfStart)); - #end + trace('displayCombo took: ${TimerTools.seconds(perfStart)}'); return combo; } diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx index 5e3ffeb42..889f5764f 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx @@ -7,6 +7,7 @@ import funkin.audio.FunkinSound; import funkin.play.character.BaseCharacter.CharacterType; import funkin.util.FileUtil; import funkin.util.assets.SoundUtil; +import funkin.util.tools.TimerTools; import funkin.audio.waveform.WaveformData; import funkin.audio.waveform.WaveformDataParser; import funkin.audio.waveform.WaveformSprite; @@ -128,41 +129,41 @@ class ChartEditorAudioHandler public static function switchToInstrumental(state:ChartEditorState, instId:String = '', playerId:String, opponentId:String):Bool { - var perfA = haxe.Timer.stamp(); + var perfA:Float = TimerTools.start(); var result:Bool = playInstrumental(state, instId); if (!result) return false; - var perfB = haxe.Timer.stamp(); + var perfB:Float = TimerTools.start(); stopExistingVocals(state); - var perfC = haxe.Timer.stamp(); + var perfC:Float = TimerTools.start(); result = playVocals(state, BF, playerId, instId); - var perfD = haxe.Timer.stamp(); + var perfD:Float = TimerTools.start(); // if (!result) return false; result = playVocals(state, DAD, opponentId, instId); // if (!result) return false; - var perfE = haxe.Timer.stamp(); + var perfE:Float = TimerTools.start(); state.hardRefreshOffsetsToolbox(); - var perfF = haxe.Timer.stamp(); + var perfF:Float = TimerTools.start(); state.hardRefreshFreeplayToolbox(); - var perfG = haxe.Timer.stamp(); + var perfG:Float = TimerTools.start(); - trace('Switched to instrumental in ${perfB - perfA} seconds.'); - trace('Stopped existing vocals in ${perfC - perfB} seconds.'); - trace('Played BF vocals in ${perfD - perfC} seconds.'); - trace('Played DAD vocals in ${perfE - perfD} seconds.'); - trace('Hard refreshed offsets toolbox in ${perfF - perfE} seconds.'); - trace('Hard refreshed freeplay toolbox in ${perfG - perfF} seconds.'); + trace('Switched to instrumental in ${TimerTools.seconds(perfA, perfB)}.'); + trace('Stopped existing vocals in ${TimerTools.seconds(perfB, perfC)}.'); + trace('Played BF vocals in ${TimerTools.seconds(perfC, perfD)}.'); + trace('Played DAD vocals in ${TimerTools.seconds(perfD, perfE)}.'); + trace('Hard refreshed offsets toolbox in ${TimerTools.seconds(perfE, perfF)}.'); + trace('Hard refreshed freeplay toolbox in ${TimerTools.seconds(perfF, perfG)}.'); return true; } @@ -174,10 +175,9 @@ class ChartEditorAudioHandler { if (instId == '') instId = 'default'; var instTrackData:Null = state.audioInstTrackData.get(instId); - var perfA = haxe.Timer.stamp(); + var perfStart:Float = TimerTools.start(); var instTrack:Null = SoundUtil.buildSoundFromBytes(instTrackData); - var perfB = haxe.Timer.stamp(); - trace('Built instrumental track in ${perfB - perfA} seconds.'); + trace('Built instrumental track in ${TimerTools.seconds(perfStart)} seconds.'); if (instTrack == null) return false; stopExistingInstrumental(state); @@ -205,10 +205,9 @@ class ChartEditorAudioHandler { var trackId:String = '${charId}${instId == '' ? '' : '-${instId}'}'; var vocalTrackData:Null = state.audioVocalTrackData.get(trackId); - var perfStart = haxe.Timer.stamp(); + var perfStart:Float = TimerTools.start(); var vocalTrack:Null = SoundUtil.buildSoundFromBytes(vocalTrackData); - var perfEnd = haxe.Timer.stamp(); - trace('Built vocal track in ${perfEnd - perfStart} seconds.'); + trace('Built vocal track in ${TimerTools.seconds(perfStart)}.'); if (state.audioVocalTrackGroup == null) state.audioVocalTrackGroup = new VoicesGroup(); @@ -219,10 +218,9 @@ class ChartEditorAudioHandler case BF: state.audioVocalTrackGroup.addPlayerVoice(vocalTrack); - var perfStart = haxe.Timer.stamp(); + var perfStart:Float = TimerTools.start(); var waveformData:Null = vocalTrack.waveformData; - var perfEnd = haxe.Timer.stamp(); - trace('Interpreted waveform data in ${perfEnd - perfStart} seconds.'); + trace('Interpreted waveform data in ${TimerTools.seconds(perfStart)}.'); if (waveformData != null) { @@ -246,10 +244,9 @@ class ChartEditorAudioHandler case DAD: state.audioVocalTrackGroup.addOpponentVoice(vocalTrack); - var perfStart = haxe.Timer.stamp(); + var perfStart:Float = TimerTools.start(); var waveformData:Null = vocalTrack.waveformData; - var perfEnd = haxe.Timer.stamp(); - trace('Interpreted waveform data in ${perfEnd - perfStart} seconds.'); + trace('Interpreted waveform data in ${TimerTools.seconds(perfStart)}.'); if (waveformData != null) { diff --git a/source/funkin/ui/debug/charting/toolboxes/ChartEditorFreeplayToolbox.hx b/source/funkin/ui/debug/charting/toolboxes/ChartEditorFreeplayToolbox.hx index 1432c9205..28d435c54 100644 --- a/source/funkin/ui/debug/charting/toolboxes/ChartEditorFreeplayToolbox.hx +++ b/source/funkin/ui/debug/charting/toolboxes/ChartEditorFreeplayToolbox.hx @@ -1,21 +1,22 @@ package funkin.ui.debug.charting.toolboxes; +import flixel.addons.display.FlxTiledSprite; +import flixel.math.FlxMath; import funkin.audio.SoundGroup; +import funkin.audio.waveform.WaveformDataParser; +import funkin.ui.debug.charting.commands.SetFreeplayPreviewCommand; +import funkin.ui.haxeui.components.WaveformPlayer; +import funkin.ui.freeplay.FreeplayState; +import funkin.util.tools.TimerTools; +import haxe.ui.backend.flixel.components.SpriteWrapper; import haxe.ui.components.Button; import haxe.ui.components.HorizontalSlider; import haxe.ui.components.Label; -import flixel.addons.display.FlxTiledSprite; -import flixel.math.FlxMath; import haxe.ui.components.NumberStepper; import haxe.ui.components.Slider; -import haxe.ui.backend.flixel.components.SpriteWrapper; -import funkin.ui.debug.charting.commands.SetFreeplayPreviewCommand; -import funkin.ui.haxeui.components.WaveformPlayer; -import funkin.audio.waveform.WaveformDataParser; import haxe.ui.containers.VBox; import haxe.ui.containers.Absolute; import haxe.ui.containers.ScrollView; -import funkin.ui.freeplay.FreeplayState; import haxe.ui.containers.Frame; import haxe.ui.core.Screen; import haxe.ui.events.DragEvent; @@ -288,12 +289,12 @@ class ChartEditorFreeplayToolbox extends ChartEditorBaseToolbox // Build player waveform. // waveformMusic.waveform.forceUpdate = true; - var perfStart = haxe.Timer.stamp(); + var perfStart:Float = TimerTools.start(); var waveformData1 = playerVoice?.waveformData; var waveformData2 = opponentVoice?.waveformData ?? playerVoice?.waveformData; // this null check is for songs that only have 1 vocals file! var waveformData3 = chartEditorState.audioInstTrack.waveformData; var waveformData = waveformData3.merge(waveformData1).merge(waveformData2); - trace('Waveform data merging took: ${haxe.Timer.stamp() - perfStart} seconds'); + trace('Waveform data merging took: ${TimerTools.seconds(perfStart)}'); waveformMusic.waveform.waveformData = waveformData; // Set the width and duration to render the full waveform, with the clipRect applied we only render a segment of it. diff --git a/source/funkin/util/plugins/MemoryGCPlugin.hx b/source/funkin/util/plugins/MemoryGCPlugin.hx index 3df861eb5..67a4fe18e 100644 --- a/source/funkin/util/plugins/MemoryGCPlugin.hx +++ b/source/funkin/util/plugins/MemoryGCPlugin.hx @@ -1,6 +1,7 @@ package funkin.util.plugins; import flixel.FlxBasic; +import funkin.util.tools.TimerTools; /** * A plugin which adds functionality to press `Ins` to immediately perform memory garbage collection. @@ -23,10 +24,9 @@ class MemoryGCPlugin extends FlxBasic if (FlxG.keys.justPressed.INSERT) { - var perfStart:Float = Sys.time(); + var perfStart:Float = TimerTools.start(); funkin.util.MemoryUtil.collect(true); - var perfEnd:Float = Sys.time(); - trace("Memory GC took " + (perfEnd - perfStart) + " seconds"); + trace('Memory GC took: ${TimerTools.seconds(perfStart)}'); } } diff --git a/source/funkin/util/tools/FloatTools.hx b/source/funkin/util/tools/FloatTools.hx index e07ae5cb9..e34110490 100644 --- a/source/funkin/util/tools/FloatTools.hx +++ b/source/funkin/util/tools/FloatTools.hx @@ -12,4 +12,13 @@ class FloatTools { return Math.max(min, Math.min(max, value)); } + + /** + Round a float to a certain number of decimal places. + **/ + public static function round(number:Float, ?precision = 2):Float + { + number *= Math.pow(10, precision); + return Math.round(number) / Math.pow(10, precision); + } } diff --git a/source/funkin/util/tools/TimerTools.hx b/source/funkin/util/tools/TimerTools.hx new file mode 100644 index 000000000..5322ada92 --- /dev/null +++ b/source/funkin/util/tools/TimerTools.hx @@ -0,0 +1,30 @@ +package funkin.util.tools; + +import funkin.util.tools.FloatTools; +import haxe.Timer; + +class TimerTools +{ + public static function start():Float + { + return Timer.stamp(); + } + + private static function took(start:Float, ?end:Float):Float + { + var endOrNow:Float = end != null ? end : Timer.stamp(); + return endOrNow - start; + } + + public static function seconds(start:Float, ?end:Float, ?precision = 2):String + { + var seconds:Float = FloatTools.round(took(start, end), precision); + return '${seconds} seconds'; + } + + public static function ms(start:Float, ?end:Float):String + { + var seconds:Float = took(start, end); + return '${seconds * 1000} ms'; + } +}