{
   "labels" : [
      "path",
      "status",
      "tracking",
      "watching"
   ],
   "code" : "(\r\nvar readCmds = IdentitySet['/b_allocRead', '/b_allocReadChannel', '/b_read', '/b_readChannel'];\r\n\r\nOSCdef(\\bufWatcher, { |msg, time, addr|\r\n\tvar server, buf;\r\n\tcase\r\n\t{ readCmds.includes(msg[1]) } {\r\n\t\tserver = Server.all.detect { |item| item.addr == addr };\r\n\t\tif(server.notNil) {\r\n\t\t\tbuf = Buffer.cachedBufferAt(server, msg[2]);\r\n\t\t\tif(buf.notNil) {\r\n\t\t\t\t// You might need buf.copy here (posting is OK)\r\n\t\t\t\tbuf.debug(\"read completed\");\r\n\t\t\t} { \"Buffer number % not found in server %\".format(msg[2], server).warn };\r\n\t\t} {\r\n\t\t\t\"/done % received but no Server object found for %\".format(msg[1], addr).warn;\r\n\t\t}\r\n\t}\r\n\t{ msg[1] == '/b_free' } {\r\n\t\t// buffer object is not available here, but OK, don't need it\r\n\t\t[msg[2], Buffer.cachedBufferAt(s, msg[2])].debug(\"freed\");\r\n\t};\r\n}, '/done');\r\n)",
   "id" : "1-50S",
   "is_private" : null,
   "name" : "Tracking buffer .read and .free",
   "author" : "jamshark70",
   "description" : "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.\r\n\r\nFor 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!\r\n\r\nFor freeing, you don't have access to the buffer object.\r\n\r\nThe example just posts messages in response. Substitute your own actions where \"debug\" appears.",
   "ancestor_list" : []
}
