diff general/algo/iterate_timed2.m @ 4:e44f49929e56

Adding reorganised general toolbox, now in several subdirectories.
author samer
date Sat, 12 Jan 2013 19:21:22 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/general/algo/iterate_timed2.m	Sat Jan 12 19:21:22 2013 +0000
@@ -0,0 +1,65 @@
+function Sched=iterate_timed(nextfn,X0,T,varargin)
+% iterate_timed - Iterate function under control of timer
+%
+% iterate_timed :: 
+%    (A=>A)          ~'state transformer action',
+%    A               ~'initial state',
+%    real            ~'timer between updates in seconds'
+%    options {
+%       drawnow   :: {0,1} /0 ~'call drawnow after each iteration';
+%       busy_mode :: {'queue','drop'} /'queue'  ~'See TIMER';
+%       exec_mode :: {'fixedRate','fixedDelay','fixedSpacing'} /'fixedRate' ~'See TIMER';
+%       its       :: natural / inf ~'iteration limit';
+%       onstart   :: (A=>void)/ @nop ~'do this when timer starts';
+%       onstop    :: (A=>void)/ @nop ~'do this when timer stops';
+%       onfinish  :: (A=>void)/ @nop ~'do this when iterator terminates';
+%       pre       :: (A=>void)/ @nop ~'do before each iteration';
+%       post      :: (A=>void)/ @nop ~'do after each iteration';
+%       defer     :: bool / 0      ~'if true then don't start the timer';
+% -> timer, (A=>void) ~'function to seek to given state'.
+%
+% NB: Unlike ITERATE, this does NOT respect the id, save, and recover properties.
+% Neither does it respect the OPTPAUSE property 'pause'.
+
+	opts=prefs('its',inf,'drawnow',0, 'quiet', 0, 'defer', 0, ...
+		'busy_mode','queue','exec_mode','fixedRate', ...
+		'onfinish',@nop,'onstart',@nop,'onstop',@nop,varargin{:});
+
+	if ~isfield(opts,'pre') && ~isfield(opts,'post') && ~opts.drawnow
+		stfn=nextfn; % streamlined version with no checks
+	else % version with calls to pre,post, and drawnow
+		prefn=getparam(opts,'pre',@nop);
+		postfn=getparam(opts,'post',@nop);
+		stfn=@bracket;
+	end
+	
+	Sched=rsched(@schedfn,X0,T,0,opts,'defer',1, ...
+			'onstart',@onstart,'onstop',@onstop,'onfinish',@onfinish);
+
+	if ~opts.defer, Sched.start(); end
+
+	function [s,t_sched]=schedfn(s,dt,t_sched,t_actual), s=stfn(s); end
+
+	function X=bracket(X), 
+		prefn(X); X=nextfn(X); postfn(X); 
+		if opts.drawnow, drawnow; end
+	end
+
+	function onfinish(X,t_actual), opts.onfinish(X); end
+
+	function onstart(X,t_sched,t_actual)
+		if ~opts.quiet, status('starting',X,t_actual); end
+		opts.onstart(X); 
+	end
+
+	function onstop(X,t_actual)
+		if ~opts.quiet, status('stopping',X,t_actual); end
+		opts.onstop(X); 
+	end
+end
+
+function status(msg,x,t),
+	fprintf('| %s at %s with %s\n',msg,mat2str(t),tostring(x)); 
+end
+
+