Skip to content

Commit

Permalink
Add disgusting workaround for an FL bug
Browse files Browse the repository at this point in the history
When switching to an effect plugin, there's now a 3 tick
delay before it is activated, since sometimes closing a
generator plugin causes FL to think that an effect plugin is
open which causes a crash if the script tries to do anything
with that plugin
  • Loading branch information
MaddyGuthridge committed May 1, 2022
1 parent 3a0bd47 commit 0003a37
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 23 deletions.
7 changes: 6 additions & 1 deletion src/common/activitystate.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Miguel Guthridge [[email protected], HDSQ#2154]
"""

from common.profiler import profilerDecoration
from common.logger import log, verbosity
from common.util.apifixes import (
PluginIndex,
Expand All @@ -16,7 +17,8 @@
EffectIndex,
WindowIndex,
)
from common.util.apifixes import getFocusedPluginIndex, getFocusedWindowIndex
from common.util.apifixes import getFocusedPluginIndex, getFocusedWindowIndex,\
reset_generator_active


class ActivityState:
Expand Down Expand Up @@ -71,10 +73,13 @@ def _forcePlugUpdate(self) -> None:
else:
self._effect = plugin # type: ignore

@profilerDecoration("activity.tick")
def tick(self) -> None:
"""
Called frequently when we need to update the current window
"""
# HACK: Fix FL Studio bugs
reset_generator_active()
self._changed = False
if self._doUpdate:
# Manually update plugin using selection
Expand Down
6 changes: 3 additions & 3 deletions src/common/defaultconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@
# Settings used for debugging
"debug": {
# Whether performance profiling should be enabled
"profiling": True,
"profiling": False,
# Whether profiling should print the tracing of profiler contexts
# within the script. Useful for troubleshooting crashes in FL Studio's
# MIDI API. Requires profiling to be enabled
"exec_tracing": True
# MIDI API. Requires profiling to be enabled.
"exec_tracing": False
},
# Settings used during script initialisation
"bootstrap": {
Expand Down
65 changes: 46 additions & 19 deletions src/common/util/apifixes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import playlist

from typing import Union, Optional
from common.profiler import profilerDecoration, ProfilerContext
from common.consts import PARAM_CC_START

GeneratorIndex = tuple[int]
Expand All @@ -29,11 +30,25 @@
UnsafeIndex = Union[UnsafePluginIndex, UnsafeWindowIndex]


# HACK: A terrible horrible no good really bad global variable to make sure
# that we hopefully avoid crashes in getFocusedPluginIndex
generator_previously_active = 0


def reset_generator_active():
"""Horrible hacky function to hopefully work around a bug in FL Studio"""
global generator_previously_active
if generator_previously_active != 0:
generator_previously_active -= 1


@profilerDecoration("getFocusedPluginIndex")
def getFocusedPluginIndex(force: bool = False) -> UnsafePluginIndex:
"""
Fixes the horrible ui.getFocusedFormIndex() function
Values are returned as tuples so that they can be unwrapped when
Values are returned as tuples so that they can be unwrapped when being
passed to other API functions
Args:
* `force` (`bool`, optional): whether to return the selected plugin on the
Expand All @@ -44,49 +59,61 @@ def getFocusedPluginIndex(force: bool = False) -> UnsafePluginIndex:
* `int`: grouped index of a channel rack plugin if one is focused
* `int, int`: index of a mixer plugin if one is focused
"""
# Check if a channel rack plugin is focused
# if ui.getFocused(7):
form_id = ui.getFocusedFormID()

# HACK: Move this elsewhere
global generator_previously_active
with ProfilerContext("getFocused"):
# for i in range(8):
# print(f" {ui.getFocused(i)=}, {i=}")
ui_6 = ui.getFocused(6)
ui_7 = ui.getFocused(7)
# If a mixer plugin is focused
if ui.getFocused(6):
if ui_6:
# HACK: Error checking to hopefully avoid a crash due to bugs in FL
# Studio
if generator_previously_active:
print("getFocusedPluginIndex() crash prevention")
return None
with ProfilerContext("getFocusedFormID @ mixer"):
form_id = ui.getFocusedFormID()
track = form_id // 4194304
slot = (form_id - 4194304 * track) // 65536
return track, slot
# Otherwise, assume that a channel is selected
# Use the channel rack index so that we always have one
elif ui.getFocused(7):
elif ui_7:
generator_previously_active = 3
with ProfilerContext("getFocusedFormID @ cr"):
form_id = ui.getFocusedFormID()
# NOTE: When using groups, ui.getFocusedFormID() returns the index
# respecting groups, instead of the global index, yuck
if form_id == -1:
# Plugin outside current group or invalid
return None
return (form_id,)
else:
generator_previously_active = 3
if force:
return (channels.selectedChannel(),)
with ProfilerContext("selectedChannel"):
ret = (channels.selectedChannel(),)
return ret
else:
return None


@profilerDecoration("getFocusedWindowIndex")
def getFocusedWindowIndex() -> Optional[int]:
"""
Fixes the horrible ui.getFocusedFormIndex() function
Values are returned as tuples so that they can be unwrapped when
Fixes the horrible ui.getFocused() function
Returns:
* `None`: if no window is focused
* `int`: index of window
"""
# Check if a channel rack plugin is focused
if getFocusedPluginIndex() is not None:
return None
else:
ret = ui.getFocusedFormID()
if ret == -1:
return None
return ret
for i in range(5):
if ui.getFocused(i):
return i
return None


# def getPluginName(index: UnsafeIndex) -> str:
# """
Expand Down

0 comments on commit 0003a37

Please sign in to comment.