Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Refactor literally everything #161

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
"playhead",
"plugins",
"pmeflags",
"postprocess",
"postprocessed",
"rect",
"Roadmap",
"RRGGBB",
Expand Down
2 changes: 2 additions & 0 deletions docs/contributing/devices/event_forward.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

# Event Forwarding

FIXME: Update this for the v2.0 release

For devices that use multiple ports, the Universal Controller Script uses a
many-to-one one-to-many model for processing events. The main script should be
assigned to the MIDI port for your controller, and the forwarder script should
Expand Down
14 changes: 3 additions & 11 deletions resources/docstring_template.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{{extendedSummaryPlaceholder}}

{{#parametersExist}}
### Args:
### Args
{{#args}}
* `{{var}}` (`{{typePlaceholder}}`): {{descriptionPlaceholder}}

Expand All @@ -18,24 +18,16 @@
{{/kwargs}}
{{/parametersExist}}

{{#exceptionsExist}}
### Raises:
{{#exceptions}}
* `{{type}}`: {{descriptionPlaceholder}}

{{/exceptions}}
{{/exceptionsExist}}

{{#returnsExist}}
### Returns:
### Returns
{{#returns}}
* `{{typePlaceholder}}`: {{descriptionPlaceholder}}

{{/returns}}
{{/returnsExist}}

{{#yieldsExist}}
### Yields:
### Yields
{{#yields}}
* `{{typePlaceholder}}`: {{descriptionPlaceholder}}

Expand Down
9 changes: 0 additions & 9 deletions src/common/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,6 @@
from .logger import log, verbosity
from .profiler import ProfilerContext, profilerDecoration

from .context_manager import (
getContext,
resetContext,
unsafeResetContext,
catchContextResetException
)

from .extension_manager import ExtensionManager

# Import devices and plugins
import devices
import integrations
Expand Down
4 changes: 1 addition & 3 deletions src/common/activity_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,10 @@ def _forcePlugUpdate(self) -> None:
Used so that split windows and plugins behaves correctly.
"""
plugin = getFocusedPluginIndex(force=True)
if plugin is None:
raise TypeError("Wait this shouldn't be possible")
if self._plugin != plugin:
self._plugin = plugin
try:
self._plugin_name = plugins.getPluginName(*plugin)
self._plugin_name = plugin.getName()
except TypeError:
self._plugin_name = ""
if isinstance(plugin, GeneratorIndex):
Expand Down
14 changes: 14 additions & 0 deletions src/common/config/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""
common > config

Code for managing the configuration of the script.

Authors:
* Miguel Guthridge [hdsq@outlook.com.au, HDSQ#2154]

This code is licensed under the GPL v3 license. Refer to the LICENSE file for
more details.
"""
__all__ = ['load_configuration']

from .loader import load_configuration
39 changes: 39 additions & 0 deletions src/common/config/default_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""
common > default_config

Stores the default configuration for the script. The user configuration will
override any existing settings here.

Authors:
* Miguel Guthridge [hdsq@outlook.com.au, HDSQ#2154]

This code is licensed under the GPL v3 license. Refer to the LICENSE file for
more details.
"""
from .types import Config

DEFAULT_CONFIG: Config = {
"controls": {
"double_press_time": 0.3,
"long_press_time": 0.5,
"short_press_time": 0.1,
"navigation_speed": 5,
"use_snap": True,
"use_undo_toggle": True,
"score_log_dump_length": 120
},
"integrations": {
"mixer": {
"allow_extended_volume": False
},
},
"advanced": {
"debug": {
"profiling_enabled": False,
"exec_tracing_enabled": False
},
"drop_tick_time": 100,
"slow_tick_time": 50,
"activity_history_length": 25,
},
}
44 changes: 44 additions & 0 deletions src/common/config/loader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
common > config > loader

Code for loading the user configuration.
"""
import sys
from .types import Config
from .default_config import DEFAULT_CONFIG
from common.util import dict_tools


# Add the custom configuration directory to the path so we can load from it
scripts_dir = \
'/'.join(__file__.replace('\\', '/').split('/')[:-4]) + '/ucs_config'
sys.path.insert(0, scripts_dir)


def load_configuration() -> Config:
"""
Load the script configuration
"""
try:
from ucs_config import CONFIG as user_settings
except ImportError as e:
# The file doesn't exist
# FIXME: Log the error properly
print(f"User configuration not found {e}")
return DEFAULT_CONFIG
except SyntaxError as e:
# FIXME: Log the error properly
print(e)
return DEFAULT_CONFIG
except Exception as e:
# FIXME: Log the error properly
print(e)
return DEFAULT_CONFIG

# Now merge the user settings with the defaults
merged_settings = dict_tools.recursive_merge_dictionaries(
DEFAULT_CONFIG,
user_settings,
)

return merged_settings
26 changes: 26 additions & 0 deletions src/common/config/types/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from typing import TypedDict

from .advanced import AdvancedConfig
from .controls import ControlSurfaceConfig
from .integrations import IntegrationConfig


class Config(TypedDict):
"""
Represents the configuration of the script
"""

controls: ControlSurfaceConfig
"""
Options for control surfaces, applied to all devices
"""

integrations: IntegrationConfig
"""
Options for integrations
"""

advanced: AdvancedConfig
"""
Advanced configuration options, including debug options
"""
52 changes: 52 additions & 0 deletions src/common/config/types/advanced.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from typing import TypedDict


class DebugConfig(TypedDict):
"""
Settings used for debugging
"""

profiling_enabled: bool
"""Whether performance profiling should be enabled"""

exec_tracing_enabled: bool
"""
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.

Note that this causes a huge amount of output to be produced on the
console, which can be immensely laggy. Only use it if absolutely necessary.
"""


class AdvancedConfig(TypedDict):
"""
Advanced settings for the script. Don't edit these unless you know what
you're doing, as they could cause the script to break, or behave badly.
"""

debug: DebugConfig
"""
Settings used for debugging the script
"""

drop_tick_time: int
"""
Time in ms during which we expect the script to be ticked. If the
script doesn't tick during this time, then the script will consider
itself to be constrained by performance, and will drop the next tick
to prevent lag in FL Studio.
"""

slow_tick_time: int
"""
Time in ms for which a tick should be expected to complete. If
ticking FL Studio takes longer than this, it will be recorded,
regardless of whether profiling is enabled.
"""

activity_history_length: int
"""
The maximum length of the plugin/window tracking history
"""
57 changes: 57 additions & 0 deletions src/common/config/types/controls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from typing import TypedDict


class ControlSurfaceConfig(TypedDict):
"""
Configuration of options for control surfaces
"""

double_press_time: float
"""The time in seconds for which a double press is valid"""

long_press_time: float
"""
The time in seconds required to register a long press

NOTE: This is currently not implemented, but will be used to implement
things such as long press scrolling.
"""

short_press_time: float
"""
The maximum duration in seconds for which a button press is considered
short.

This is used for buttons that usually repeat over time, but have a
different action is pressed and released quickly.
"""

navigation_speed: int
"""
How fast to navigate when long-pressing a direction button. This roughly
corresponds to the number of times the action will be performed per second.
"""

use_snap: bool
"""
Whether values that have a centred default value (eg panning) should snap
to the centred value when values are close.
"""

use_undo_toggle: bool
"""
Whether the undo/redo button should act as a toggle between undo and redo.

* If `True`, it will redo unless there is nothing to redo, in which case it
will undo
* If `False`, it will always undo

Note that devices with separate undo and redo buttons are not affected by
this option.
"""

score_log_dump_length: int
"""
The length of time to dump to a pattern from the score log when a
capture MIDI button is pressed, in seconds.
"""
26 changes: 26 additions & 0 deletions src/common/config/types/integrations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from typing import TypedDict


class MixerConfig(TypedDict):
"""
Configuration for FL Studio mixer
"""

allow_extended_volume: bool
"""
Whether volumes over 100% should be allowed
* `True`: faders will map from 0-125%
* `False`: faders will map from 0-100%
"""


class IntegrationConfig(TypedDict):
"""
Configuration of script integrations - any integrations that provide
settings are listed as members of this.
"""

mixer: MixerConfig
"""
FL Studio mixer window
"""
Loading
Loading