Update
This commit is contained in:
162
2023/scripts/rigging_tools/ngskintools2/api/session.py
Normal file
162
2023/scripts/rigging_tools/ngskintools2/api/session.py
Normal file
@@ -0,0 +1,162 @@
|
||||
"""
|
||||
UI session is running as long as any of the ngSkinTools UI windows are open.
|
||||
|
||||
"""
|
||||
import functools
|
||||
|
||||
from ngSkinTools2 import cleanup, signal
|
||||
from ngSkinTools2.api import Layers, PaintTool, events, mirror, plugin
|
||||
from ngSkinTools2.api.log import getLogger
|
||||
from ngSkinTools2.api.python_compatibility import Object
|
||||
from ngSkinTools2.observableValue import ObservableValue
|
||||
from ngSkinTools2.signal import SignalHub
|
||||
|
||||
log = getLogger("events")
|
||||
|
||||
|
||||
class CurrentLayerState(Object):
|
||||
def __init__(self):
|
||||
self.selectedSkinCluster = None
|
||||
|
||||
# will be None, when no current layer is available
|
||||
self.layer = None # type: ngSkinTools2.api.Layer
|
||||
|
||||
|
||||
class CurrentPaintTargetState(Object):
|
||||
def __init__(self):
|
||||
self.skinCluster = None
|
||||
self.layerId = None
|
||||
self.targets = None
|
||||
|
||||
|
||||
class State(Object):
|
||||
def __init__(self):
|
||||
self.layersAvailable = False
|
||||
self.selection = []
|
||||
self.selectedSkinCluster = None
|
||||
self.skin_cluster_dq_channel_used = False
|
||||
|
||||
self.all_layers = [] # type: List[ngSkinTools2.api.Layer]
|
||||
self.currentLayer = CurrentLayerState()
|
||||
self.currentInfluence = CurrentPaintTargetState()
|
||||
|
||||
def set_skin_cluster(self, cluster):
|
||||
self.selectedSkinCluster = cluster
|
||||
self.layers = None if cluster is None else Layers(cluster)
|
||||
|
||||
def mirror(self):
|
||||
# type: () -> mirror.Mirror
|
||||
return mirror.Mirror(self.selectedSkinCluster)
|
||||
|
||||
|
||||
class Context(Object):
|
||||
def __init__(self):
|
||||
self.selected_layers = ObservableValue() # [] layerId
|
||||
|
||||
|
||||
class Session(Object):
|
||||
def __init__(self):
|
||||
# reference objects that are keeping the session
|
||||
self.references = set()
|
||||
self.state = None # type: State
|
||||
self.events = None # type: events.Events
|
||||
self.signal_hub = None # type: SignalHub
|
||||
self.context = None # type: Context
|
||||
|
||||
self.referenceId = 0
|
||||
|
||||
def active(self):
|
||||
return len(self.references) > 0
|
||||
|
||||
def start(self):
|
||||
log.info("STARTING SESSION")
|
||||
plugin.load_plugin()
|
||||
|
||||
self.paint_tool = PaintTool()
|
||||
|
||||
self.state = State()
|
||||
self.events = events.Events(self.state)
|
||||
self.signal_hub = SignalHub()
|
||||
self.signal_hub.activate()
|
||||
cleanup.registerCleanupHandler(self.signal_hub.deactivate)
|
||||
self.context = Context()
|
||||
|
||||
@signal.on(self.events.targetChanged)
|
||||
def on_target_change():
|
||||
log.info("target changed: clearing target context")
|
||||
self.context.selected_layers.set([])
|
||||
|
||||
self.events.nodeSelectionChanged.emit()
|
||||
|
||||
def end(self):
|
||||
log.info("ENDING SESSION")
|
||||
cleanup.cleanup()
|
||||
self.state = None
|
||||
self.events = None
|
||||
self.context = None
|
||||
self.signal_hub = None
|
||||
pass
|
||||
|
||||
def addReference(self):
|
||||
"""
|
||||
returns unique ID for this added reference; this value needs to be passed into removeReference();
|
||||
this ensures that reference holder does not remove other references rather than his own.
|
||||
:return:
|
||||
"""
|
||||
self.referenceId += 1
|
||||
if not self.active():
|
||||
self.start()
|
||||
|
||||
self.references.add(self.referenceId)
|
||||
return self.referenceId
|
||||
|
||||
def removeReference(self, referenceId):
|
||||
try:
|
||||
self.references.remove(referenceId)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if not self.active():
|
||||
self.end()
|
||||
|
||||
def addQtWidgetReference(self, widget):
|
||||
ref = self.addReference()
|
||||
|
||||
widget.destroyed.connect(lambda: self.removeReference(ref))
|
||||
|
||||
def reference(self):
|
||||
class Context(Object):
|
||||
def __init__(self, session):
|
||||
"""
|
||||
:type session: Session
|
||||
:type refObj: object
|
||||
"""
|
||||
|
||||
self.session = session
|
||||
|
||||
def __enter__(self):
|
||||
self.ref = self.session.addReference()
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.session.removeReference(self.ref)
|
||||
|
||||
return Context(self)
|
||||
|
||||
|
||||
session = Session()
|
||||
|
||||
|
||||
def withSession(func):
|
||||
"""
|
||||
decorator makes sure that single session is running throughout function's lifetime
|
||||
"""
|
||||
|
||||
@functools.wraps(func)
|
||||
def result(*args, **kwargs):
|
||||
ref = session.addReference()
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
finally:
|
||||
session.removeReference(ref)
|
||||
|
||||
return result
|
||||
Reference in New Issue
Block a user