% umgather - Run a processing unit and collect multiple outputs
%
% ugather :: 
%    unit({}, A@typelist(K), _) ~'live processing unit with K outputs',
%    T:natural              ~'number of iterations to run (can be inf)',
%    options {
%       draw  :: boolean/false ~'whether or not to call drawnow after each iteration';
%       quiet :: boolean/false ~'whether or not to suppress progress messages';
%       chunk :: natural/1     ~'print progress every chunk interations';
%    } 
% -> B@typelist(K) ~'collected outputs'.
%
% This function accepts the live processing unit associated
% with an arrow (as created by with_arrow). The arrow must
% have zero inputs and one output. The requested number of outputs
% are collected into an array and returned. If inf outputs are
% requested, the system is run until an EOF exception is caught.

function varargout=umgather(u,its,varargin)
	opts=prefs('draw',0,varargin{:});
	nout=length(u.sizes_out);
	gatherers=map(@(sz)gatherer(sz,opts),u.sizes_out);
	if opts.draw, dfn=@drawnow; else dfn=@nop; end
	uiter(u,its,@gatherxx,[],'label','umgather',opts);
	varargout=map(@(g)g.collect(),gatherers);

	function s=gatherxx(i,s), 
		[outs{1:nout}]=u.process();
		for i=1:nout, gatherers{i}.append(outs{i}); end
		dfn();
	end
end


