Command + Period not stopping code

Ever since I started using SC 4 years ago I have had a recurring problem quitting code (not my own code) with command + period. Sometimes this is the case for very basic examples from the helpfiles, typically a Pbind not assigned to a variable or if I accidentally overwrite the reference to the Pbind. I does not happen every time but has happened many many times (maybe 100 times) over the years - only solution is to recompile the library as just quitting the server means loads of SynthDef not found errors which is unsuprising in itself. I have not done any thorough testing of the issues yet, first I want to hear if other users have had similar experiences.

In my own code I usually have something like

CmdPeriod.doOnce{ f[\shutdown].() };

Where f[\shutdown] is a cleanup code and as the last line of the shutdown func I have

CmdPeriod.removeAll

It is possible that the described behaviour only happens after I have shut down my own code and thus invoked the CmdPeriod.doOnce…CmdPeriod.removeAll method, but I am not sure. Latest example was trying to run @smoge’s code from this thread, where I was again unable to stop the code with command period. I have always assumed that CmdPeriod.removeAll only removes stuff I have assigned myself without messing with the basic workings of Cmd + Period - is that true?

I have used several official SC releases over the 4 years (never develop branches) always from the precompiled packages and also several generations of OSX - same behaviour.

Any thoughts?

1 Like

That should be fine.

I don’t see why this should be necessary, though…? Or rather, this strikes me as unnecessary.

CmdPeriod.doOnce sets up your action so that it will run and be removed. removeAll would be removing what has already been removed.

Could investigate – start up SC and do this before adding your own CmdPeriod objects:

CmdPeriod.objects

-> List[ class MasterSplay, class TempoClock, a Tempo, class ProxyMeter, class SynthTracker, class NodeWatcher, class KrBusWatcher, class ReceiveReply, class PeakMonitor ]

// hm, let's keep only core classes
(
var classlibPath = Object.filenameSymbol.asString.dirname.dirname.dirname;

CmdPeriod.objects.select { |obj|
	obj.isKindOf(Class) and: {
		obj.filenameSymbol.asString.beginsWith(classlibPath)
	}
}
)

-> [ class TempoClock, class NodeWatcher ]

class TempoClock – it turns out that TempoClock.cmdPeriod is the method where anything scheduled on any TempoClock gets removed from the queue.

That is, emptying TempoClocks is not actually a “basic working” of CmdPeriod – it’s a CmdPeriod action that is registered at startup. It’s expected that users will not remove this action. If that action is gone, then items scheduled on permanent clocks will stay in the queue and will still fire after CmdPeriod.

AFAICS, then, the entire problem being reported here is a side effect of the unnecessary removeAll.

A good rule of thumb is – if you added it, you’re responsible for removing it (i.e. doOnce :white_check_mark: ). If you didn’t add it, then it may be risky to step on the toes of whatever component did add it (and, corollary: taking unnecessary operations creates opportunities for bugs).

hjh

1 Like

Thanks for looking into this. I will remove the CmdPeriod.removeAll line of code and see if this fixes the problem which seems likely given your answer. As I recall, the removeAll action was something I added following the advice of an old video tutorial and I just never thought about since then.