oscillode/src/blender_maxwell/registration.py

147 lines
3.5 KiB
Python

import typing as typ
from pathlib import Path
import bpy
from .nodeps.utils import simple_logger
log = simple_logger.get(__name__)
# TODO: More types for these things!
DelayedRegKey: typ.TypeAlias = str
BLClass: typ.TypeAlias = typ.Any ## TODO: Better Type
BLKeymapItem: typ.TypeAlias = typ.Any ## TODO: Better Type
KeymapItemDef: typ.TypeAlias = typ.Any ## TODO: Better Type
####################
# - Globals
####################
BL_KEYMAP: bpy.types.KeyMap | None = None
REG__CLASSES: list[BLClass] = []
REG__KEYMAP_ITEMS: list[BLKeymapItem] = []
DELAYED_REGISTRATIONS: dict[DelayedRegKey, typ.Callable[[Path], None]] = {}
####################
# - Constants
####################
EVENT__DEPS_SATISFIED: str = 'on_deps_satisfied'
####################
# - Class Registration
####################
def register_classes(bl_register: list):
log.info('Registering %s Classes', len(bl_register))
for cls in bl_register:
if cls.bl_idname in REG__CLASSES:
msg = f'Skipping register of {cls.bl_idname}'
log.info(msg)
continue
log.debug(
'Registering Class %s',
repr(cls),
)
bpy.utils.register_class(cls)
REG__CLASSES.append(cls)
def unregister_classes():
log.info('Unregistering %s Classes', len(REG__CLASSES))
for cls in reversed(REG__CLASSES):
log.debug(
'Unregistering Class %s',
repr(cls),
)
bpy.utils.unregister_class(cls)
REG__CLASSES.clear()
####################
# - Keymap Registration
####################
def register_keymap_items(keymap_item_defs: list[dict]):
# Lazy-Load BL_NODE_KEYMAP
global BL_KEYMAP # noqa: PLW0603
if BL_KEYMAP is None:
BL_KEYMAP = bpy.context.window_manager.keyconfigs.addon.keymaps.new(
name='Node Editor',
space_type='NODE_EDITOR',
)
log.info(
'Registered Keymap %s',
str(BL_KEYMAP),
)
# Register Keymaps
log.info('Registering %s Keymap Items', len(keymap_item_defs))
for keymap_item_def in keymap_item_defs:
keymap_item = BL_KEYMAP.keymap_items.new(
*keymap_item_def['_'],
ctrl=keymap_item_def['ctrl'],
shift=keymap_item_def['shift'],
alt=keymap_item_def['alt'],
)
log.debug(
'Registered Keymap Item %s with spec %s',
repr(keymap_item),
keymap_item_def,
)
REG__KEYMAP_ITEMS.append(keymap_item)
def unregister_keymap_items():
global BL_KEYMAP # noqa: PLW0603
# Unregister Keymaps
log.info('Unregistering %s Keymap Items', len(REG__KEYMAP_ITEMS))
for keymap_item in reversed(REG__KEYMAP_ITEMS):
log.debug(
'Unregistered Keymap Item %s',
repr(keymap_item),
)
BL_KEYMAP.keymap_items.remove(keymap_item)
# Lazy-Unload BL_NODE_KEYMAP
if BL_KEYMAP is not None:
log.info(
'Unregistered Keymap %s',
repr(BL_KEYMAP),
)
REG__KEYMAP_ITEMS.clear()
BL_KEYMAP = None
####################
# - Delayed Registration Semantics
####################
def delay_registration(
delayed_reg_key: DelayedRegKey,
classes_cb: typ.Callable[[Path], list[BLClass]],
keymap_item_defs_cb: typ.Callable[[Path], list[KeymapItemDef]],
) -> None:
if delayed_reg_key in DELAYED_REGISTRATIONS:
msg = f'Already delayed a registration with key {delayed_reg_key}'
raise ValueError(msg)
def register_cb(path_deps: Path):
log.info(
'Running Delayed Registration (key %s) with PyDeps: %s',
delayed_reg_key,
path_deps,
)
register_classes(classes_cb(path_deps))
register_keymap_items(keymap_item_defs_cb(path_deps))
DELAYED_REGISTRATIONS[delayed_reg_key] = register_cb
def run_delayed_registration(
delayed_reg_key: DelayedRegKey, path_deps: Path
) -> None:
register_cb = DELAYED_REGISTRATIONS.pop(delayed_reg_key)
register_cb(path_deps)