@ -344,7 +344,7 @@ class NsmServerControl(object):
" /nsm/gui/client/pid " : self . _reactCallback_clientPid ,
" /nsm/gui/client/dirty " : self . _reactCallback_clientDirty ,
" /nsm/gui/server/message " : self . _reactCallback_serverMessage ,
" /nsm/gui/gui_announce " : self . _reactCallback_guiAnnounce ,
" /nsm/gui/gui_announce " : self . _reactCallback_guiAnnounce , #we rarely receive that, especially not in init.
" /nsm/server/list " : self . _reactCallback_serverList ,
" /nsm/server/broadcast " : self . _reactCallback_broadcast ,
}
@ -395,7 +395,7 @@ class NsmServerControl(object):
logger . info ( " nsmd is ready @ {} " . format ( self . nsmOSCUrl ) )
#Tell nsmd that we are a GUI and want to receive general messages async, not only after we request something
self . sessionRoot = self . _initial_announce ( ) #Triggers "hi" and session root
self . sessionRoot = self . _initial_announce ( ) #Triggers "hi" and session root
self . internalState [ " sessionRoot " ] = self . sessionRoot
atexit . register ( self . quit ) #mostly does stuff when we started nsmd ourself
@ -579,9 +579,10 @@ class NsmServerControl(object):
then we get the session root . We wait for session root and then clean ' hi ' from the queue .
Returns session root as pathlib - path . """
resultArguments = self . _blockingRequest ( path = " /nsm/gui/gui_announce " , arguments = [ ] , answerPath = " /nsm/gui/session/root " , answerArguments = [ ] )
if len ( self . _queue ) == 1 and self . _queue [ 0 ] . oscpath == " /nsm/gui/gui_announce " and self . _queue [ 0 ] . params == [ " hi " ] :
self . _queue . clear ( )
resultArguments = self . _blockingRequest ( path = " /nsm/gui/gui_announce " , arguments = [ ] , answerPath = " /nsm/gui/session/root " , answerArguments = [ ] )
if len ( self . _queue ) == 1 and self . _queue [ 0 ] . oscpath == " /nsm/gui/gui_announce " and self . _queue [ 0 ] . params == [ " hi " ] :
logger . info ( " Got ' hi ' . We are now the registered nsmd GUI as per our initial /nsm/gui/gui_announce " )
self . _queue . clear ( )
else :
logging . error ( f " For ValueError below: { [ ( m . oscpath , m . params ) for m in self . _queue ] } " )
raise ValueError ( " We were expecting a clean _queue with only ' hi ' as leftover, but instead there were unhandled messages. see print above. Better abort than a wrong program state " )
@ -833,9 +834,9 @@ class NsmServerControl(object):
#Callbacks
def _reactCallback_guiAnnounce ( self , parameters : list ) :
""" Acknowledge """
""" This should not happen, but let ' s keep it in in case of edge-case multi GUI scenarios """
assert parameters == [ " hi " ] , parameters
logger . info ( " We got acknowledged as current nsmd GUI . " )
logger . info ( " We got an unexpected ' hi ' , as if requesting gui_announce. Our own initial GUI announce as received and processed silently earlier already . " )
def _reactCallback_error ( self , parameters : list ) :
logger . error ( parameters )
@ -940,27 +941,35 @@ class NsmServerControl(object):
def _reactCallback_activeSessionChanged ( self , parameters : list ) :
""" This is called when the session has already changed.
Shortly before we receive / nsm / gui / session / session which indicates the attempt to create ,
I guess ! : )
""" We receive this trough /nsm/gui/session/name
This is called when the session has already changed .
This also happens when you connect to a headless nsmd with a running session .
We expect two parameters : [ session name , session path ] both of which could be " " .
If we start nsmd ourselves into an empty state we expect session name to be empty
Shortly before we received / nsm / gui / session / session which indicates the attempt to create a
new one , I guess ! : )
If you want to react to the attempt to open a session you need to use / nsm / gui / server / message [ " Opening session FOO " ]
OR creating a new session , after which nsmd will open that session without a message .
If you want to react to the attempt to open a session you need to use
/ nsm / gui / server / message [ " Opening session FOO " ] OR creating a new session , after which nsmd
will open that session without a message .
Empty string is " No session " or " Choose A Session " mode .
"""
l = len ( parameters )
if l == 2 :
shortName , nsmSessionName = parameters
if not shortName and not nsmSessionName : #No session loaded. We are in session-choosing mode.
nsmSessionName , sessionPath = parameters
if not nsmSessionName and not sessionPath : #No session loaded. We are in session-choosing mode.
logger . info ( " Session closed or never started. Choose-A-Session mode. " )
self . internalState [ " currentSession " ] = None
self . sessionClosedHook ( )
else :
nsmSessionName = nsmSessionName . lstrip ( " / " )
logger . info ( f " Current Session changed. We are now { shortName } under { nsmSessionName } " )
sessionPath = sessionPath . lstrip ( " / " )
logger . info ( f " Current Session changed. We are now { nsmSessionName } in { sessionPath } " )
self . internalState [ " currentSession " ] = nsmSessionName
#This is after the session, received after all programs have loaded.
#We have a counterpart as message reaction that signals the attempt to load.
#We have a counterpart- message reaction that signals the attempt to load.
self . sessionOpenReadyHook ( self . sessionAsDict ( nsmSessionName ) ) #notify the api->UI
for autoClientExecutableInPath in self . _addToNextSession :
self . clientAdd ( autoClientExecutableInPath )
@ -1411,8 +1420,10 @@ class NsmServerControl(object):
sessionFile = pathlib . Path ( basePath , " session.nsm " )
if not sessionFile . exists ( ) :
logger . info ( " Got wrong session directory from nsmd. Race condition after delete? Project: " + repr ( sessionFile ) )
return None
#This is a reason to let the program exit.
print ( nsmSessionName )
logger . error ( " Got wrong session directory from nsmd. Race condition after delete? In any case a breaking error (please report). Quitting. Project was: " + repr ( sessionFile ) )
sysexit ( ) #return None switch to return None to let it crash and see the python traceback
timestamp = datetime . fromtimestamp ( sessionFile . stat ( ) . st_mtime ) . isoformat ( sep = " " , timespec = ' minutes ' )
entry [ " lastSavedDate " ] = timestamp