%FutureInputHelper
% Implementation helper for parallel.internal.queue.Future.

% Copyright 2013-2020 The MathWorks, Inc.
classdef FutureInputHelper < handle
properties (GetAccess = private, SetAccess = immutable)
% A duplicate of the wrapper to the underlying task
JavaTask
end
properties (Dependent, Access = ?parallel.internal.queue.Future)
Function
NumOutputArguments
InputArguments
end
properties (Access = private)
PropertyCache = cell(1,3);
CacheValid = false;
end

methods
function val = get.Function(obj)
if ~obj.CacheValid, updateCache(obj); end
val = obj.PropertyCache{1};
end
function val = get.NumOutputArguments(obj)
if ~obj.CacheValid, updateCache(obj); end
val = obj.PropertyCache{2};
end
function val = get.InputArguments(obj)
if ~obj.CacheValid, updateCache(obj); end
val = obj.PropertyCache{3};
end
end

methods (Access = private)
function updateCache(obj)
if ~obj.CacheValid
assert(~isempty(obj.JavaTask));
task = obj.JavaTask.getIfNotDisposed();
assert(~isempty(task));
try
evaluationRequest = task.getEvaluationRequest();
% get fresh duplicates of the evaluation request buffers.
bbh = evaluationRequest.getBuffersForDeserialization();
doFree = true;
newProps = parallel.internal.pool.deserialize(bbh, doFree);
catch E %#ok<NASGU> Swallow and return empty.
newProps = cell(1,3);
end
obj.PropertyCache = newProps;
obj.CacheValid = true;
obj.JavaTask.disposeIfNecessary();
end
end
end

methods
function delete(obj)
if ~isempty(obj.JavaTask)
obj.JavaTask.disposeIfNecessary();
end
end
end

methods (Access = ?parallel.internal.queue.Future)
function obj = FutureInputHelper(varargin)
% FutureInputHelper - build either with the 3 properties
% directly, or with a new duplicate of the java task.
if nargin == 3
obj.PropertyCache = varargin;
obj.CacheValid = true;
obj.JavaTask = [];
elseif nargin == 1
obj.JavaTask = varargin{1};
else
assert(false);
end
end
end
end