Calculations/MOT-Simulator/+Helper/parforNotifications.m

149 lines
5.1 KiB
Matlab

% Copyright (c) 2019 Andrea Alberti
%
% All rights reserved.
classdef parforNotifications < handle
properties
N; % number of iterations
text = 'Please wait ...'; % text to show
width = 50;
showWarning = true;
end
properties (GetAccess = public, SetAccess = private)
n;
end
properties (Access = private)
inProgress = false;
percent;
DataQueue;
usePercent;
Nstr;
NstrL;
lastComment;
end
methods
function this = parforNotifications()
this.DataQueue = parallel.pool.DataQueue;
afterEach(this.DataQueue, @this.updateStatus);
end
% Start progress bar
function PB_start(this,N,varargin)
assert(isscalar(N) && isnumeric(N) && N == floor(N) && N>0, 'Error: ''N'' must be a scalar positive integer.');
this.N = N;
p = inputParser;
addParameter(p,'message','Please wait: ');
addParameter(p,'usePercentage',true);
parse(p,varargin{:});
this.text = p.Results.message;
assert(ischar(this.text), 'Error: ''Message'' must be a string.');
this.usePercent = p.Results.usePercentage;
assert(isscalar(this.usePercent) && islogical(this.usePercent), 'Error: ''usePercentage'' must be a logical scalar.');
this.percent = 0;
this.n = 0;
this.lastComment = '';
if this.usePercent
fprintf('%s [%s]: %3d%%\n',this.text, char(32*ones(1,this.width)),0);
else
this.Nstr = sprintf('%d',this.N);
this.NstrL = numel(this.Nstr);
fprintf('%s [%s]: %s/%s\n',this.text, char(32*ones(1,this.width)),[char(32*ones(1,this.NstrL-1)),'0'],this.Nstr);
end
this.inProgress = true;
end
% Iterate progress bar
function PB_iterate(this,str)
if nargin == 1
send(this.DataQueue,'');
else
send(this.DataQueue,str);
end
end
function warning(this,warn_id,msg)
if this.showWarning
msg = struct('Action','Warning','Id',warn_id,'Message',msg);
send(this.DataQueue,msg);
end
end
function PB_reprint(this)
p = round(100*this.n/this.N);
this.percent = p;
cursor_pos=1+round((this.width-1)*p/100);
if p < 100
sep_char = '|';
else
sep_char = '.';
end
if this.usePercent
fprintf('%s [%s%s%s]: %3d%%\n', this.text, char(46*ones(1,cursor_pos-1)), sep_char, char(32*ones(1,this.width-cursor_pos)),p);
else
nstr=sprintf('%d',this.n);
fprintf('%s [%s%s%s]: %s/%s\n', this.text, char(46*ones(1,cursor_pos-1)), sep_char, char(32*ones(1,this.width-cursor_pos)),[char(32*ones(1,this.NstrL-numel(nstr))),nstr],this.Nstr);
end
end
function updateStatus(this,data)
if ischar(data)
this.n = this.n + 1;
p = round(100*this.n/this.N);
if p >= this.percent+1 || this.n == this.N
this.percent = p;
cursor_pos=1+round((this.width-1)*p/100);
if p < 100
sep_char = '|';
else
sep_char = '.';
end
if ~isempty(data)
comment = [' (',data,')'];
else
comment = '';
end
if this.usePercent
fprintf('%s%s%s%s]: %3d%%%s\n',char(8*ones(1,58+numel(this.lastComment))), char(46*ones(1,cursor_pos-1)), sep_char, char(32*ones(1,this.width-cursor_pos)),p,comment);
else
nstr=sprintf('%d',this.n);
fprintf('%s%s%s%s]: %s/%s%s\n',char(8*ones(1,55+2*numel(this.Nstr)+numel(this.lastComment))), char(46*ones(1,cursor_pos-1)), sep_char, char(32*ones(1,this.width-cursor_pos)),[char(32*ones(1,this.NstrL-numel(nstr))),nstr],this.Nstr,comment)
end
this.lastComment = comment;
if p == 100
this.inProgress = false;
end
end
else
switch data.Action
case 'Warning'
warning(data.Id,[data.Message,newline]);
if this.inProgress
this.PB_reprint();
end
end
end
end
end
end