samer@4: function Sched=iterate_timed(nextfn,X0,T,varargin) samer@4: % iterate_timed - Iterate function under control of timer samer@4: % samer@4: % iterate_timed :: samer@4: % (A=>A) ~'state transformer action', samer@4: % A ~'initial state', samer@4: % real ~'timer between updates in seconds' samer@4: % options { samer@4: % drawnow :: {0,1} /0 ~'call drawnow after each iteration'; samer@4: % busy_mode :: {'queue','drop'} /'queue' ~'See TIMER'; samer@4: % exec_mode :: {'fixedRate','fixedDelay','fixedSpacing'} /'fixedRate' ~'See TIMER'; samer@4: % its :: natural / inf ~'iteration limit'; samer@4: % onstart :: (A=>void)/ @nop ~'do this when timer starts'; samer@4: % onstop :: (A=>void)/ @nop ~'do this when timer stops'; samer@4: % onfinish :: (A=>void)/ @nop ~'do this when iterator terminates'; samer@4: % pre :: (A=>void)/ @nop ~'do before each iteration'; samer@4: % post :: (A=>void)/ @nop ~'do after each iteration'; samer@4: % defer :: bool / 0 ~'if true then don't start the timer'; samer@4: % -> timer, (A=>void) ~'function to seek to given state'. samer@4: % samer@4: % NB: Unlike ITERATE, this does NOT respect the id, save, and recover properties. samer@4: % Neither does it respect the OPTPAUSE property 'pause'. samer@4: samer@37: opts=options('its',inf,'drawnow',0, 'quiet', 0, 'defer', 0, ... samer@4: 'busy_mode','queue','exec_mode','fixedRate', ... samer@4: 'onfinish',@nop,'onstart',@nop,'onstop',@nop,varargin{:}); samer@4: samer@6: it={nextfn,X0}; samer@6: if isfield(opts,'pre') || isfield(opts,'post') samer@6: it=bracket_it(it, getparam(opts,'pre',@nop), getparam(opts,'post',@nop)); samer@4: end samer@6: if opts.drawnow, it=drawnow_it(it); end samer@6: stfn=it{1}; samer@4: samer@6: Sched=rsched(@action,it{2},T,nows,opts,'defer',1,... samer@4: 'onstart',@onstart,'onstop',@onstop,'onfinish',@onfinish); samer@4: if ~opts.defer, Sched.start(); end samer@4: samer@6: function [err,s]=action(t_sched,dt,s), err=nows-t_sched; s=stfn(s); end samer@6: function onstart(X,t_sched,t_actual), status('starting',X,t_actual); opts.onstart(X); end samer@6: function onstop(X,t_actual), status('stopping',X,t_actual); opts.onstop(X); end samer@6: function onfinish(t_actual), status('finishing',[],t_actual); opts.onfinish(); end samer@6: function status(msg,x,t), samer@6: if ~opts.quiet samer@6: fprintf('| %s at %s with %s\n',msg,mat2str(t),tostring(x)); samer@6: end samer@4: end samer@4: end samer@4: samer@6: function it=drawnow_it(it), samer@6: f=it{1}; it{1}=@fdraw; samer@6: function x=fdraw(x), x=f(x); drawnow; end samer@4: end samer@4: