From 257fa2da6aff6e74972f999108c9e241fe34a92f Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 12 Sep 2023 23:31:38 -0400 Subject: [PATCH 1/3] Remove old Notifbar code --- .../funkin/ui/haxeui/components/Notifbar.hx | 109 ------------------ 1 file changed, 109 deletions(-) delete mode 100644 source/funkin/ui/haxeui/components/Notifbar.hx diff --git a/source/funkin/ui/haxeui/components/Notifbar.hx b/source/funkin/ui/haxeui/components/Notifbar.hx deleted file mode 100644 index 91ba16077..000000000 --- a/source/funkin/ui/haxeui/components/Notifbar.hx +++ /dev/null @@ -1,109 +0,0 @@ -package funkin.ui.haxeui.components; - -import flixel.FlxG; -import flixel.util.FlxTimer; -import haxe.ui.RuntimeComponentBuilder; -import haxe.ui.components.Button; -import haxe.ui.components.Label; -import haxe.ui.containers.Box; -import haxe.ui.containers.SideBar; -import haxe.ui.containers.VBox; -import haxe.ui.core.Component; - -class Notifbar extends SideBar -{ - final NOTIFICATION_DISMISS_TIME = 5.0; // seconds - var dismissTimer:FlxTimer = null; - - var outerContainer:Box = null; - var container:VBox = null; - var message:Label = null; - var action:Button = null; - var dismiss:Button = null; - - public function new() - { - super(); - - buildSidebar(); - buildChildren(); - } - - public function showNotification(message:String, ?actionText:String = null, ?actionCallback:Void->Void = null, ?dismissTime:Float = null) - { - if (dismissTimer != null) dismissNotification(); - - if (dismissTime == null) dismissTime = NOTIFICATION_DISMISS_TIME; - - // Message text. - this.message.text = message; - - // Action - if (actionText != null) - { - this.action.text = actionText; - this.action.visible = true; - this.action.disabled = false; - this.action.onClick = (_) -> { - actionCallback(); - }; - } - else - { - this.action.visible = false; - this.action.disabled = false; - this.action.onClick = null; - } - - this.show(); - - // Auto dismiss. - dismissTimer = new FlxTimer().start(dismissTime, (_:FlxTimer) -> dismissNotification()); - } - - public function dismissNotification() - { - if (dismissTimer != null) - { - dismissTimer.cancel(); - dismissTimer = null; - } - - this.hide(); - } - - function buildSidebar():Void - { - this.width = 256; - this.height = 80; - - // border-top: 1px solid #000; border-left: 1px solid #000; - this.styleString = "border: 1px solid #000; background-color: #3d3f41; padding: 8px; border-top-left-radius: 8px;"; - - // float to the right - this.x = FlxG.width - this.width; - - this.position = "bottom"; - this.method = "float"; - } - - function buildChildren():Void - { - outerContainer = cast(buildComponent("assets/data/notifbar.xml"), Box); - addComponent(outerContainer); - - container = outerContainer.findComponent('notifbarContainer', VBox); - message = outerContainer.findComponent('notifbarMessage', Label); - action = outerContainer.findComponent('notifbarAction', Button); - dismiss = outerContainer.findComponent('notifbarDismiss', Button); - - dismiss.onClick = (_) -> { - dismissNotification(); - }; - } - - function buildComponent(path:String):Component - { - return RuntimeComponentBuilder.fromAsset(path); - } -} From b42e4ceb67ce781727d7324daec70ec6334b15f2 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 12 Sep 2023 23:37:07 -0400 Subject: [PATCH 2/3] Fix cursor modes on toolboxes. --- .../charting/ChartEditorToolboxHandler.hx | 1 + .../ui/haxeui/components/FunkinDropdown.hx | 30 +++++++++++++++++++ .../haxeui/components/FunkinNumberStepper.hx | 30 +++++++++++++++++++ .../ui/haxeui/components/FunkinTextField.hx | 30 +++++++++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 source/funkin/ui/haxeui/components/FunkinDropdown.hx create mode 100644 source/funkin/ui/haxeui/components/FunkinNumberStepper.hx create mode 100644 source/funkin/ui/haxeui/components/FunkinTextField.hx diff --git a/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx b/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx index 7833e19fd..db090542d 100644 --- a/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx @@ -1,5 +1,6 @@ package funkin.ui.debug.charting; +import haxe.ui.components.HorizontalSlider; import haxe.ui.containers.TreeView; import haxe.ui.containers.TreeViewNode; import funkin.play.character.BaseCharacter.CharacterType; diff --git a/source/funkin/ui/haxeui/components/FunkinDropdown.hx b/source/funkin/ui/haxeui/components/FunkinDropdown.hx new file mode 100644 index 000000000..ad396856c --- /dev/null +++ b/source/funkin/ui/haxeui/components/FunkinDropdown.hx @@ -0,0 +1,30 @@ +package funkin.ui.haxeui.components; + +import haxe.ui.components.DropDown; +import funkin.input.Cursor; +import haxe.ui.events.MouseEvent; + +/** + * A HaxeUI dropdown which: + * - Changes the current cursor when hovered over. + */ +class FunkinDropDown extends DropDown +{ + public function new() + { + super(); + + this.onMouseOver = handleMouseOver; + this.onMouseOut = handleMouseOut; + } + + private function handleMouseOver(event:MouseEvent) + { + Cursor.cursorMode = Pointer; + } + + private function handleMouseOut(event:MouseEvent) + { + Cursor.cursorMode = Default; + } +} diff --git a/source/funkin/ui/haxeui/components/FunkinNumberStepper.hx b/source/funkin/ui/haxeui/components/FunkinNumberStepper.hx new file mode 100644 index 000000000..db8d4fb7f --- /dev/null +++ b/source/funkin/ui/haxeui/components/FunkinNumberStepper.hx @@ -0,0 +1,30 @@ +package funkin.ui.haxeui.components; + +import haxe.ui.components.NumberStepper; +import funkin.input.Cursor; +import haxe.ui.events.MouseEvent; + +/** + * A HaxeUI number stepper which: + * - Changes the current cursor when hovered over. + */ +class FunkinNumberStepper extends NumberStepper +{ + public function new() + { + super(); + + this.onMouseOver = handleMouseOver; + this.onMouseOut = handleMouseOut; + } + + private function handleMouseOver(event:MouseEvent) + { + Cursor.cursorMode = Pointer; + } + + private function handleMouseOut(event:MouseEvent) + { + Cursor.cursorMode = Default; + } +} diff --git a/source/funkin/ui/haxeui/components/FunkinTextField.hx b/source/funkin/ui/haxeui/components/FunkinTextField.hx new file mode 100644 index 000000000..3ecab0684 --- /dev/null +++ b/source/funkin/ui/haxeui/components/FunkinTextField.hx @@ -0,0 +1,30 @@ +package funkin.ui.haxeui.components; + +import haxe.ui.components.TextField; +import funkin.input.Cursor; +import haxe.ui.events.MouseEvent; + +/** + * A HaxeUI text field which: + * - Changes the current cursor when hovered over. + */ +class FunkinTextField extends TextField +{ + public function new() + { + super(); + + this.onMouseOver = handleMouseOver; + this.onMouseOut = handleMouseOut; + } + + private function handleMouseOver(event:MouseEvent) + { + Cursor.cursorMode = Text; + } + + private function handleMouseOut(event:MouseEvent) + { + Cursor.cursorMode = Default; + } +} From 8dd07d27630b4f7718838fd6ae07b5f84c9f9588 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 13 Sep 2023 14:51:12 -0400 Subject: [PATCH 3/3] I discovered a new profiling tool and stayed up until 5 AM optimizing shit. --- source/funkin/data/song/SongData.hx | 71 ++++++--- source/funkin/import.hx | 4 +- source/funkin/play/notes/NoteSprite.hx | 11 -- source/funkin/play/notes/SustainTrail.hx | 8 +- .../debug/charting/ChartEditorEventSprite.hx | 6 +- .../charting/ChartEditorHoldNoteSprite.hx | 12 +- .../debug/charting/ChartEditorNoteSprite.hx | 12 +- .../ui/debug/charting/ChartEditorState.hx | 141 ++++++++++++------ source/funkin/util/SortUtil.hx | 14 +- .../util/tools/SongEventDataArrayTools.hx | 62 ++++++++ .../util/tools/SongNoteDataArrayTools.hx | 69 +++++++++ 11 files changed, 318 insertions(+), 92 deletions(-) create mode 100644 source/funkin/util/tools/SongEventDataArrayTools.hx create mode 100644 source/funkin/util/tools/SongNoteDataArrayTools.hx diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx index 6dc6f55e7..59f8fcaf1 100644 --- a/source/funkin/data/song/SongData.hx +++ b/source/funkin/data/song/SongData.hx @@ -363,7 +363,13 @@ class SongEventData * The timestamp of the event. The timestamp is in the format of the song's time format. */ @:alias("t") - public var time:Float; + public var time(default, set):Float; + + function set_time(value:Float):Float + { + _stepTime = null; + return time = value; + } /** * The kind of the event. @@ -398,11 +404,13 @@ class SongEventData } @:jignored - public var stepTime(get, never):Float; + var _stepTime:Null = null; - function get_stepTime():Float + public function getStepTime(force:Bool = false):Float { - return Conductor.getTimeInSteps(this.time); + if (_stepTime != null && !force) return _stepTime; + + return _stepTime = Conductor.getTimeInSteps(this.time); } public inline function getDynamic(key:String):Null @@ -488,7 +496,13 @@ class SongNoteData * The timestamp of the note. The timestamp is in the format of the song's time format. */ @:alias("t") - public var time:Float; + public var time(default, set):Float; + + function set_time(value:Float):Float + { + _stepTime = null; + return time = value; + } /** * Data for the note. Represents the index on the strumline. @@ -533,15 +547,18 @@ class SongNoteData this.kind = kind; } - /** - * The timestamp of the note, in steps. - */ @:jignored - public var stepTime(get, never):Float; + var _stepTime:Null = null; - function get_stepTime():Float + /** + * @param force Set to `true` to force recalculation (good after BPM changes) + * @return The position of the note in the song, in steps. + */ + public function getStepTime(force:Bool = false):Float { - return Conductor.getTimeInSteps(this.time); + if (_stepTime != null && !force) return _stepTime; + + return _stepTime = Conductor.getTimeInSteps(this.time); } /** @@ -594,20 +611,34 @@ class SongNoteData return getStrumlineIndex(strumlineSize) == 0; } - /** - * If this is a hold note, this is the length of the hold note in steps. - * @default 0 (not a hold note) - */ - public var stepLength(get, set):Float; + @:jignored + var _stepLength:Null = null; - function get_stepLength():Float + /** + * @param force Set to `true` to force recalculation (good after BPM changes) + * @return The length of the hold note in steps, or `0` if this is not a hold note. + */ + public function getStepLength(force = false):Float { - return Conductor.getTimeInSteps(this.time + this.length) - this.stepTime; + if (this.length <= 0) return 0.0; + + if (_stepLength != null && !force) return _stepLength; + + return _stepLength = Conductor.getTimeInSteps(this.time + this.length) - getStepTime(); } - function set_stepLength(value:Float):Float + public function setStepLength(value:Float):Void { - return this.length = Conductor.getStepTimeInMs(value) - this.time; + if (value <= 0) + { + this.length = 0.0; + } + else + { + var lengthMs:Float = Conductor.getStepTimeInMs(value) - this.time; + this.length = lengthMs; + } + _stepLength = null; } @:jignored diff --git a/source/funkin/import.hx b/source/funkin/import.hx index cd0af4b55..06fe2bfa8 100644 --- a/source/funkin/import.hx +++ b/source/funkin/import.hx @@ -9,10 +9,12 @@ import flixel.FlxG; // This one in particular causes a compile error if you're u // These are great. using Lambda; using StringTools; -using funkin.util.tools.ArrayTools; using funkin.util.tools.ArraySortTools; +using funkin.util.tools.ArrayTools; using funkin.util.tools.Int64Tools; using funkin.util.tools.IteratorTools; using funkin.util.tools.MapTools; +using funkin.util.tools.SongEventDataArrayTools; +using funkin.util.tools.SongNoteDataArrayTools; using funkin.util.tools.StringTools; #end diff --git a/source/funkin/play/notes/NoteSprite.hx b/source/funkin/play/notes/NoteSprite.hx index e6202a3a0..e5c4786d3 100644 --- a/source/funkin/play/notes/NoteSprite.hx +++ b/source/funkin/play/notes/NoteSprite.hx @@ -22,17 +22,6 @@ class NoteSprite extends FlxSprite return this.strumTime; } - /** - * The time at which the note should be hit, in steps. - */ - public var stepTime(get, never):Float; - - function get_stepTime():Float - { - // TODO: Account for changes in BPM. - return this.strumTime / Conductor.stepLengthMs; - } - /** * An extra attribute for the note. * For example, whether the note is an "alt" note, or whether it has custom behavior on hit. diff --git a/source/funkin/play/notes/SustainTrail.hx b/source/funkin/play/notes/SustainTrail.hx index 0b9304a3d..37bc674a5 100644 --- a/source/funkin/play/notes/SustainTrail.hx +++ b/source/funkin/play/notes/SustainTrail.hx @@ -142,12 +142,14 @@ class SustainTrail extends FlxSprite return (susLength * 0.45 * scroll); } - function set_sustainLength(s:Float) + function set_sustainLength(s:Float):Float { - if (s < 0) s = 0; + if (s < 0.0) s = 0.0; + + if (sustainLength == s) return s; height = sustainHeight(s, getScrollSpeed()); - updateColorTransform(); + // updateColorTransform(); updateClipping(); return sustainLength = s; } diff --git a/source/funkin/ui/debug/charting/ChartEditorEventSprite.hx b/source/funkin/ui/debug/charting/ChartEditorEventSprite.hx index af1b605a0..021abde0f 100644 --- a/source/funkin/ui/debug/charting/ChartEditorEventSprite.hx +++ b/source/funkin/ui/debug/charting/ChartEditorEventSprite.hx @@ -145,7 +145,9 @@ class ChartEditorEventSprite extends FlxSprite if (this.eventData == null) return; this.x = (ChartEditorState.STRUMLINE_SIZE * 2 + 1 - 1) * ChartEditorState.GRID_SIZE; - if (this.eventData.stepTime >= 0) this.y = this.eventData.stepTime * ChartEditorState.GRID_SIZE; + + var stepTime:Float = inline eventData.getStepTime(); + this.y = stepTime * ChartEditorState.GRID_SIZE; if (origin != null) { @@ -174,7 +176,7 @@ class ChartEditorEventSprite extends FlxSprite public static function wouldEventBeVisible(viewAreaBottom:Float, viewAreaTop:Float, eventData:SongEventData, ?origin:FlxObject):Bool { var noteHeight:Float = ChartEditorState.GRID_SIZE; - var notePosY:Float = eventData.stepTime * ChartEditorState.GRID_SIZE; + var notePosY:Float = eventData.getStepTime() * ChartEditorState.GRID_SIZE; if (origin != null) notePosY += origin.y; // True if the note is above the view area. diff --git a/source/funkin/ui/debug/charting/ChartEditorHoldNoteSprite.hx b/source/funkin/ui/debug/charting/ChartEditorHoldNoteSprite.hx index d64cc33a1..59d84647a 100644 --- a/source/funkin/ui/debug/charting/ChartEditorHoldNoteSprite.hx +++ b/source/funkin/ui/debug/charting/ChartEditorHoldNoteSprite.hx @@ -98,8 +98,9 @@ class ChartEditorHoldNoteSprite extends SustainTrail */ public static function wouldHoldNoteBeVisible(viewAreaBottom:Float, viewAreaTop:Float, noteData:SongNoteData, ?origin:FlxObject):Bool { - var noteHeight:Float = noteData.stepLength * ChartEditorState.GRID_SIZE; - var notePosY:Float = noteData.stepTime * ChartEditorState.GRID_SIZE; + var noteHeight:Float = noteData.getStepLength() * ChartEditorState.GRID_SIZE; + var stepTime:Float = inline noteData.getStepTime(); + var notePosY:Float = stepTime * ChartEditorState.GRID_SIZE; if (origin != null) notePosY += origin.y; // True if the note is above the view area. @@ -138,10 +139,11 @@ class ChartEditorHoldNoteSprite extends SustainTrail this.x = cursorColumn * ChartEditorState.GRID_SIZE; // Notes far in the song will start far down, but the group they belong to will have a high negative offset. - if (this.noteData.stepTime >= 0) + // noteData.getStepTime() returns a calculated value which accounts for BPM changes + var stepTime:Float = + inline this.noteData.getStepTime(); + if (stepTime >= 0) { - // noteData.stepTime is a calculated value which accounts for BPM changes - var stepTime:Float = this.noteData.stepTime; // Add epsilon to fix rounding issues? // var roundedStepTime:Float = Math.floor((stepTime + 0.01) / noteSnapRatio) * noteSnapRatio; this.y = stepTime * ChartEditorState.GRID_SIZE; diff --git a/source/funkin/ui/debug/charting/ChartEditorNoteSprite.hx b/source/funkin/ui/debug/charting/ChartEditorNoteSprite.hx index c8fe8f598..4e0972621 100644 --- a/source/funkin/ui/debug/charting/ChartEditorNoteSprite.hx +++ b/source/funkin/ui/debug/charting/ChartEditorNoteSprite.hx @@ -170,10 +170,12 @@ class ChartEditorNoteSprite extends FlxSprite this.x = cursorColumn * ChartEditorState.GRID_SIZE; // Notes far in the song will start far down, but the group they belong to will have a high negative offset. - if (this.noteData.stepTime >= 0) + // noteData.getStepTime() returns a calculated value which accounts for BPM changes + var stepTime:Float = + inline this.noteData.getStepTime(); + if (stepTime >= 0) { - // noteData.stepTime is a calculated value which accounts for BPM changes - this.y = this.noteData.stepTime * ChartEditorState.GRID_SIZE; + this.y = stepTime * ChartEditorState.GRID_SIZE; } if (origin != null) @@ -230,11 +232,13 @@ class ChartEditorNoteSprite extends FlxSprite /** * Return whether a note, if placed in the scene, would be visible. + * This function should be made HYPER EFFICIENT because it's called a lot. */ public static function wouldNoteBeVisible(viewAreaBottom:Float, viewAreaTop:Float, noteData:SongNoteData, ?origin:FlxObject):Bool { var noteHeight:Float = ChartEditorState.GRID_SIZE; - var notePosY:Float = noteData.stepTime * ChartEditorState.GRID_SIZE; + var stepTime:Float = inline noteData.getStepTime(); + var notePosY:Float = stepTime * ChartEditorState.GRID_SIZE; if (origin != null) notePosY += origin.y; // True if the note is above the view area. diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 1113743f5..404e9928e 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -590,7 +590,13 @@ class ChartEditorState extends HaxeUIState /** * Whether the note preview graphic needs to be FULLY rebuilt. */ - var notePreviewDirty:Bool = true; + var notePreviewDirty(default, set):Bool = true; + + function set_notePreviewDirty(value:Bool):Bool + { + trace('Note preview dirtied!'); + return notePreviewDirty = value; + } var notePreviewViewportBoundsDirty:Bool = true; @@ -1178,6 +1184,21 @@ class ChartEditorState extends HaxeUIState */ var playbarHead:Null = null; + /** + * The label by the playbar telling the song position. + */ + var playbarSongPos:Null