«Tracking buffer .read and .free» by jamshark70

on 30 Jan'16 06:45 in pathstatustrackingwatching

If you need to maintain a list of buffers (say, for a GUI) and have that list update automatically even if the user issues Buffer.read or b.free commands independently, '/done' notifications from the server can help you.

For reading, you can get the Buffer object from Buffer.cachedBufferAt (and thereby determine the path that was read). If you save the Buffer in your own collection, .copy the buffer (so that you can still get its bufnum after .free). Note that buf.copy is NOT buf.copyData!

For freeing, you don't have access to the buffer object.

The example just posts messages in response. Substitute your own actions where "debug" appears.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(
var readCmds = IdentitySet['/b_allocRead', '/b_allocReadChannel', '/b_read', '/b_readChannel'];

OSCdef(\bufWatcher, { |msg, time, addr|
	var server, buf;
	case
	{ readCmds.includes(msg[1]) } {
		server = Server.all.detect { |item| item.addr == addr };
		if(server.notNil) {
			buf = Buffer.cachedBufferAt(server, msg[2]);
			if(buf.notNil) {
				// You might need buf.copy here (posting is OK)
				buf.debug("read completed");
			} { "Buffer number % not found in server %".format(msg[2], server).warn };
		} {
			"/done % received but no Server object found for %".format(msg[1], addr).warn;
		}
	}
	{ msg[1] == '/b_free' } {
		// buffer object is not available here, but OK, don't need it
		[msg[2], Buffer.cachedBufferAt(s, msg[2])].debug("freed");
	};
}, '/done');
)
raw 796 chars (focus & ctrl+a+c to copy)
reception
comments