File: ReadableNodeIDAllocator.sc

package info (click to toggle)
supercollider 1%3A3.10.0%2Brepack-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 45,496 kB
  • sloc: cpp: 283,513; lisp: 74,040; ansic: 72,252; sh: 23,016; python: 7,175; makefile: 1,087; perl: 766; java: 677; yacc: 314; lex: 175; ruby: 136; objc: 65; xml: 15
file content (86 lines) | stat: -rw-r--r-- 2,174 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/* make nodeIDs more humanly readable:
10 ** 8 ids for 1 user, 10 ** 7 for < 21, 10 ** 6 for < 210

for example, with 20 Clients, clientIDs would be
clientID  defaultGroup  tempIDs
1         10000001      120001000, 10001001, etc
2         10000001      120001000, 10001001, etc
12        120000001      120001000, 10001001, etc

In multi-client settings, this makes s.plotTree display
or s.queryAllNodes posts much easier to understand.
*/

ReadableNodeIDAllocator {

	var <clientID, <lowestTempID, <numClients;
	var <numIDs, <idOffset, <maxPermID;
	var tempCount = -1, permCount = 1, permFreed;

	*new { |clientID = 0, lowestTempID = 1000, numClients = 32|
		^super.newCopyArgs(clientID, lowestTempID, numClients).reset
	}

	reset {
		var maxNumPerUser = (2 ** 31 / numClients).trunc;
		// go to next lower power of 10:
		numIDs = (10 ** maxNumPerUser.log10.trunc).asInteger;

		idOffset = numIDs * clientID;

		permFreed = IdentitySet.new;
		maxPermID = idOffset + lowestTempID - 1;
		tempCount = -1;
		permCount = 1;
	}

	alloc {
		tempCount = tempCount + 1;
		// wraps after handing out (numIDs - lowestTempID) ids
		^(lowestTempID + tempCount).wrap(lowestTempID, numIDs) + idOffset;
	}

	isPerm { |num|
		// test whether num is a valid permanent nodeID for this client/allocator's range,
		// which includes idOffset + 0 (for clientID 0, RootNode)
		// and idOffset + 1, the defaultGroup for this allocator/client
		^num.inclusivelyBetween(idOffset, maxPermID);
	}

	allocPerm {
		var perm;
		if(permFreed.size > 0) {
			perm = permFreed.minItem;
			permFreed.remove(perm);
			^perm
		};

		permCount = (permCount + 1).min(lowestTempID);
		perm = permCount;
		if (perm >= lowestTempID) {
			warn("%: cannot create more than % permanent ids."
				"\nPlease free some permanent ids first,"
				"or set lowestTempID higher."
				.format(thisMethod, perm)
			);
			^nil
		};
		^perm + idOffset
	}

	freePerm { |id|
		var topFreed;
		if (this.isPerm(id).not) { ^this };

		permFreed.add(id);
		while {
			permFreed.notEmpty and: {
				topFreed = permFreed.maxItem;
				topFreed == permCount;
			}
		} {
			permFreed.remove(topFreed);
			permCount = permCount - 1;
		}
	}
}