% with_arrow - Instatiate processing network and run a command against it
%
% with_arrow ::
%    arrow(T1@typelist(N),T2@typelist(M),S),
%    Cmd:(unit(T1,T2,S) -> action R)  ~'function to apply to live unit',
%    {[N]->size}                      ~'sizes of inputs',
%    options {
%       pause    :: boolean/false ~'pause after creation and before destruction of unit';
%       keyboard :: boolean/false ~'drop to debug command line instead of pausing';
%       gui      :: boolean/false ~'create Java GUI for viewables'
%    }
% -> action R ~'eventually returns any return values from Cmd.
%
% This command brings to life the processing network defined by the
% supplied arrow. The function Cmd is called passing in a structure representing
% the live system. After Cmd, the system is closed in a controlled fashion,
% releasing any system resources that were claimed during construction.
% This occures even if an exception is thrown. HOWEVER - if you press Ctrl-C,
% this generates an uncatchable exception and so resources will not be
% correctly released.
%
% If the gui option is supplied, a Java GUI is created for any viewable
% objects created by the system (Java class samer.core.Viewable). This
% requires that the Java AWT be available, ie usejava('awt')==1.


function varargout=with_arrow(sys,cmd,sizes_in,varargin)
	opts=options('pause',0,'gui',0,'keyboard',0,varargin{:});
	ud.figs=[];
	ud.arrows={};
	set(0,'UserData',ud);
	u=construct(sys,sizes_in);
	if opts.gui, 
		if usejava('awt'), 
			if exist('expose_viewables','file')
				frame=expose_viewables(u.viewables,'system'); 
			else
				fprintf('WARNING: could not find expose_viewables function.\n'); 
				opts.gui=false;
			end
		else 
			fprintf('WARNING: cannot create GUI Java AWT is unavailable.\n'); 
			opts.gui=false;
		end
	end
	if opts.keyboard
		whos
		fprintf('type "return" to when you have finished snooping around.\n');
		keyboard
	elseif opts.pause>0, 
		msg_pause('press any key to start');  
		fprintf('running...'); 
	end
	try, [varargout{1:nargout}]=cmd(u);
	catch ex
		fprintf('\nwith_arrow: CAUGHT EXCEPTION\n\n');
		% fprintf(getReport(ex));
		if opts.keyboard, keyboard
		elseif opts.pause>0, msg_pause('\npress any key to close'); end
		if opts.gui, frame.dispose; end
		u.dispose();
		rethrow(ex);
	end
	if opts.keyboard
		fprintf('type "return" to when you have finished snooping around.\n');
		keyboard
	elseif opts.pause>0, 
		msg_pause('\npress any key to close'); 
	end
	if opts.gui, frame.close; end
	u.dispose();
	set(0,'UserData',[]);
end

function msg_pause(msg)
	fprintf(msg); pause; 
	fprintf('\n');
end
