samer@4
|
1 function Sched=iterate_timed(nextfn,X0,T,varargin)
|
samer@4
|
2 % iterate_timed - Iterate function under control of timer
|
samer@4
|
3 %
|
samer@4
|
4 % iterate_timed ::
|
samer@4
|
5 % (A=>A) ~'state transformer action',
|
samer@4
|
6 % A ~'initial state',
|
samer@4
|
7 % real ~'timer between updates in seconds'
|
samer@4
|
8 % options {
|
samer@4
|
9 % drawnow :: {0,1} /0 ~'call drawnow after each iteration';
|
samer@4
|
10 % busy_mode :: {'queue','drop'} /'queue' ~'See TIMER';
|
samer@4
|
11 % exec_mode :: {'fixedRate','fixedDelay','fixedSpacing'} /'fixedRate' ~'See TIMER';
|
samer@4
|
12 % its :: natural / inf ~'iteration limit';
|
samer@4
|
13 % onstart :: (A=>void)/ @nop ~'do this when timer starts';
|
samer@4
|
14 % onstop :: (A=>void)/ @nop ~'do this when timer stops';
|
samer@4
|
15 % onfinish :: (A=>void)/ @nop ~'do this when iterator terminates';
|
samer@4
|
16 % pre :: (A=>void)/ @nop ~'do before each iteration';
|
samer@4
|
17 % post :: (A=>void)/ @nop ~'do after each iteration';
|
samer@4
|
18 % defer :: bool / 0 ~'if true then don't start the timer';
|
samer@4
|
19 % -> timer, (A=>void) ~'function to seek to given state'.
|
samer@4
|
20 %
|
samer@4
|
21 % NB: Unlike ITERATE, this does NOT respect the id, save, and recover properties.
|
samer@4
|
22 % Neither does it respect the OPTPAUSE property 'pause'.
|
samer@4
|
23
|
samer@37
|
24 opts=options('its',inf,'drawnow',0, 'quiet', 0, 'defer', 0, ...
|
samer@4
|
25 'busy_mode','queue','exec_mode','fixedRate', ...
|
samer@4
|
26 'onfinish',@nop,'onstart',@nop,'onstop',@nop,varargin{:});
|
samer@4
|
27
|
samer@6
|
28 it={nextfn,X0};
|
samer@6
|
29 if isfield(opts,'pre') || isfield(opts,'post')
|
samer@6
|
30 it=bracket_it(it, getparam(opts,'pre',@nop), getparam(opts,'post',@nop));
|
samer@4
|
31 end
|
samer@6
|
32 if opts.drawnow, it=drawnow_it(it); end
|
samer@6
|
33 stfn=it{1};
|
samer@4
|
34
|
samer@6
|
35 Sched=rsched(@action,it{2},T,nows,opts,'defer',1,...
|
samer@4
|
36 'onstart',@onstart,'onstop',@onstop,'onfinish',@onfinish);
|
samer@4
|
37 if ~opts.defer, Sched.start(); end
|
samer@4
|
38
|
samer@6
|
39 function [err,s]=action(t_sched,dt,s), err=nows-t_sched; s=stfn(s); end
|
samer@6
|
40 function onstart(X,t_sched,t_actual), status('starting',X,t_actual); opts.onstart(X); end
|
samer@6
|
41 function onstop(X,t_actual), status('stopping',X,t_actual); opts.onstop(X); end
|
samer@6
|
42 function onfinish(t_actual), status('finishing',[],t_actual); opts.onfinish(); end
|
samer@6
|
43 function status(msg,x,t),
|
samer@6
|
44 if ~opts.quiet
|
samer@6
|
45 fprintf('| %s at %s with %s\n',msg,mat2str(t),tostring(x));
|
samer@6
|
46 end
|
samer@4
|
47 end
|
samer@4
|
48 end
|
samer@4
|
49
|
samer@6
|
50 function it=drawnow_it(it),
|
samer@6
|
51 f=it{1}; it{1}=@fdraw;
|
samer@6
|
52 function x=fdraw(x), x=f(x); drawnow; end
|
samer@4
|
53 end
|
samer@4
|
54
|