%CLASSWAITBARDIST waitbar class communicating via TCP/IP sockets
% This waitbar can be used with the Parallel Computing Toolbox and the MATLAB Distributed Computing Server for the worker to update a waitbar
% on the client machine.
%
% RECEIVER = CLASSWAITBARDIST() opens a TCP/IP connexion via JAVA sockets on a port,
% creates a waitbar figure and waits for incoming data on sockets. It
% automatically initializes the hostname and the port.
%
% SENDER = CLASSWAITBARDIST(RECEIVER) opens a TCP/IP connexion via JAVA
% sockets by retrieving the info from RECEIVER
% and creates an object used to send progress info.
% CLASSWAITBARDIST implement saveobj and loadobj for the object serialization
% when using the Parallel Computing Toolbox with the MATLAB Distributed Computing Server.
% Example:
% % ON THE CLIENT:
% awaitbar = classWaitbardist();
% job = createJob();
% set(job,'FileDependencies',{'worker_waitbardist.m',...
% 'classWaitbardist', ...
% 'distplus/@classTCPIPSender'});
% createTask(job, 'worker_waitbardist', 0, {awaitbar});
% submit(job);
%
% % ON THE WORKER:
% function worker_waitbardist(awaitbar)
% for i=0:0.01:1
% awaitbar.update(i, 'Me, the worker, I work!');
% end
% awaitbar.close();
%
% $Author: cpouillo $
% Copyright 2009 - 2009 The MathWorks, Inc.
% $Rev: 22 $ $Date: 2009-09-03 09:43:07 +0200 (jeu., 03 sept. 2009) $
classdef classWaitbardist
properties
hostname;
port;
internalH;
sender;
receiver;
isSender = false;
end
methods(Static)
function initJAVA()
% adding the JAVA package
path = fileparts(mfilename('fullpath'));
javaaddpath(fullfile(path, 'communication.jar'));
end
% NOTICE: The Parallel Computing Toolbox and the MATLAB Distributed Computing Server will use the saveobj and loadobj methods of
% classWaitbardist. The loadobj method
% will automatically transform the (TCPIP server) awaitbardist from client machine
% to a worker (TCPIP client) awaitbardist.
% loadobj needs to be a static method.
function a = loadobj(b)
a = classWaitbardist(b);
end
end
methods
% NOTICE: The Parallel Computing Toolbox and the MATLAB Distributed Computing Server will use the saveobj and loadobj methods of
% classWaitbardist. The loadobj method
% will automatically transform the (TCPIP server) awaitbardist from client machine
% to a worker (TCPIP client) awaitbardist.
function a = saveobj(b)
a.hostname = b.hostname;
a.port = b.port;
end
function obj = classWaitbardist(varargin)
if nargin == 0
obj.isSender = false;
try
obj.receiver = classTCPIPReceiver();
catch ME
if strcmp(ME.identifier, 'MATLAB:Java:ClassLoad')
error(ME.identifier, 'You should need to run "classWaitbardist.initJAVA()" before using this class.');
else
rethrow(ME);
end
end
obj.port = obj.receiver.port;
obj.hostname = obj.receiver.hostname;
% fprintf('A receiver object is created on "%s" with port %d.\n', obj.hostname, obj.port);
obj.receiver.DataReceivedCallback = @nested_progressCallback;
% starting receiver
obj.receiver.start();
obj.internalH = waitbar(0,'Waiting info from a worker...');
set( obj.internalH, 'CloseRequestFcn', @nested_CloseRequestFcn);
else
try
% works for both class and structure
varargin{1}.hostname;
varargin{1}.port;
catch
error('classWaitbardist:invalidArgument', 'Input argument must have "port" and "hostname" fields.');
end
obj.isSender = true;
classWaitbardist.initJAVA();
try
obj.sender = classTCPIPSender(varargin{1}.hostname, varargin{1}.port);
obj.hostname = varargin{1}.hostname;
obj.port = varargin{1}.port;
% fprintf('A sender object is created to "%s" with port %d.\n', varargin{1}.hostname, varargin{1}.port);
catch ME
if strcmp(ME.identifier, 'MATLAB:Java:ClassLoad')
error(ME.identifier, 'You should need to run "classWaitbardist.initJAVA()" before using this class.');
else
rethrow(ME);
end
end
end
function nested_progressCallback(data)
if isfield(data, 'type') && strcmp(data.type, 'waitbardist')
try % if it fails, it comes from invalid obj.internalH
switch data.command
case 'initializing'
waitbar(data.progress, obj.internalH, data.message);
case 'update'
if isfield(data, 'message')
waitbar(data.progress, obj.internalH, data.message);
else
waitbar(data.progress, obj.internalH);
end
case 'close'
close(obj.internalH);
end
end
end
end
function nested_CloseRequestFcn(handle, varargin)
obj.close();
end
end
function update(this, progress, message)
if nargin == 3
data.message = message;
end
if this.isSender
data.type = 'waitbardist';
data.command = 'update';
data.progress = progress;
this.sender.send(data);
end
end
function close(this)
try
delete(this.internalH);
end
if this.isSender
data.type = 'waitbardist';
data.command = 'close';
this.sender.send(data);
delete(this.sender);
else
this.receiver.stop();
delete(this.receiver);
end
end
function delete(this)
close(this);
end
end
end