OpenNoteBlockStudio
OpenNoteBlockStudio copied to clipboard
Improve note selections and macro operations
This pull request aims to improve the performance of selection-related actions, macro operations and song loading. It also allows users to undo and redo macro changes.
Changes
- Reimplement
array_to_selection()
,selection_code_update()
,selection_load()
,selection_load_ext()
,selection_to_array()
,region_code_get()
andregion_code_load()
to utilize buffers because buffer functions are much faster than string functions. - The program will now try to compress selection code strings and encode them to base64 before saving them to the history in order to reduce memory usage. The strings will be decompressed when needed. ~~The
selection_code
string is kept uncompressed.~~ Theselection_code
variable is also compressed as well. Selection code (de)compression is implemented intry_compress_selection()
andtry_decompress_selection()
. (De)compression overhead is insignificant. A selection code will not be compressed if the compressed string is longer than the original string or if the original string is short (less than 16 characters). - "Set panning", "Set pitch", "Set velocity", "Replace key" and "Reset all properties" macros are now either reimplemented or changed to call existing functions, which makes these macros as fast as "Change instrument..." command can be.
- Other macros also have performance changes, which improve the macro speed for the selection of less than 20k notes.
- Previously, a nonsimple macro had the following steps: selection data -> selection code -> selection code array -> macro -> altered selection code array -> altered selection code -> altered selection data.
- This PR changes the pipeline to the following steps: selection data -> selection code array -> macro -> altered selection code array -> altered selection data. Two steps are skipped.
- Replace
if else
statements inaction_undo()
andaction_redo()
withswitch case
statements. - Use
array_length(arr_data)
instead ofstring_count("|", str)
to calculatetotal_vals
; usemacro_column_count()
to replacestring_count("-1", ...)
in some macros; - Selection codes created by macro operations will now be added to the history, which effectively enables macro undoing/redoing.
- All macros now will deselect selected notes after being applied unless
Alt
is pressed. - Call functions directly instead of using
script_execute()
, and disable surface depth. - Improve the speed when pasting a large selection to an existing area by using the
@
accessor or turning off copy-on-write. Because copy-on-write is a project-wide option that will affect all arrays in the program, I decided to keep it on; - Move the code to check and extend the
selection_exists
array to separate functions. - Improve song opening performance by 6x, by initializing arrays in the reverse orders and reading notes to a temporal array before adding notes in the reverse orders.
- Add a new function
array_grow_then_set()
to set a value at an index to an array and grow the array by the factor of 1.5 when necessary, which should give a better time complexity thanarray_push()
.
Bugfixes
- Fix the solo property of layers not taken into account when displaying and playing back if the layers are loaded from a file.
- Fix a pattern file that can't be drag-dropped two times in a row.
- Fix playback looping doesn't respect the "Times to loop" property.
Thank you for the pull request! These are some great improvements. I'm gonna review it soon, but since it touches some vital parts of the NBS workflow, I'd like to make sure everything works as expected before merging :)
Ready to merge if no problems are found. I updated the first comment, so please re-read it.