Property listener with OOP
1 visualizzazione (ultimi 30 giorni)
Mostra commenti meno recenti
Hello all,
I'm not exactly sure what I'm supposed to be asking here, so forgive me if I'm way off base. I have an object created in matlab with three properties. The class is called an nUnit, and the properties are value, unit, and unitVec. Both the unit and unitVec are heavily related to one another. So, if the user modifies the .unit, I wish for the .unitVec to be automatically updated and vice versa.
I have the conversion functions written, but how do I trigger them to run? I've read a lot about listeners and the like, but I can't seem to find a proper example for a function that would get triggered if a property is modified. Below is my class definition file. Thank you for your time!
Trevor
classdef nUnit
%NUNIT Create numerical unit class
%
% A = NUNIT(VALUE, UNITSTRING)
% A = NUNIT(VALUE, UNITVEC)
% Inputs:
% VALUE: Numeric scalar or array
% UNITSTRING: String of accepted unit strings
% UNITVEC: 1x9 numeric array of base unit powers
%
properties
value
unit
unitVec
end
methods
function nU = nUnit(value,unit)
% ==============================================================================
% Constructor - Create an nUnit
% ==============================================================================
if ~isnumeric(value) || isempty(value); error('input VALUE must be a non-empty numeric'); end
% If value is 1-dimensional, force vertical concatenation
if any(1 == size(value))
value = value(:);
end
if ~(ischar(unit) ||...
(isnumeric(unit) &&...
all(size(unit) == [1, 9]))); error('input UNIT must be a string or unitVector'); end %#ok<ALIGN>
if ischar(unit) % Unit string is inputed
[nU.unitVec, valueMult] = unit2vec(unit);
nU.unit = vec2unit(nU.unitVec);
nU.value = value * valueMult;
else % Unit vector is inputed - Base units only
nU.unitVec = unit;
nU.unit = vec2unit(unit);
nU.value = value;
end
end
% ==============================================================================
% Functions that only modify value property
% ==============================================================================
function nUnitA = diff(varargin); nUnitA = genValueFun(@diff, varargin{:}); end
function nUnitA = unique(varargin); nUnitA = genValueFun(@unique, varargin{:}); end
function nUnitX = genValueFun(functionH, nUnitX, varargin)
nUnitX.value = feval(functionH, nUnitX.value, varargin{:});
end
% ==============================================================================
% Overload Numel for O-O compatability
% Source: http://www.mathworks.com/matlabcentral/answers/101955-why-do-i-receive-errors-when-overloading-subsref-for-types-and-for-matlab-classes
% ==============================================================================
function n = numel(varargin)
n = 1;
end
% ==============================================================================
% Functions that query the value property
% ==============================================================================
function [varargout] = size(varargin)
varargout = genValueQueryFun(@size, varargin{:});
varargout = {varargout};
end
function [varargout] = length(varargin)
varargout = genValueQueryFun(@length, varargin{:});
varargout = {varargout};
end
function [varargout] = genValueQueryFun(functionH, nUnitX, varargin)
varargout = feval(functionH, nUnitX.value, varargin{:});
varargout = {varargout};
end
end
end
0 Commenti
Risposta accettata
Adam
il 7 Set 2016
Modificato: Adam
il 7 Set 2016
I use dependent properties for this, e.g.
properties
value
end
properties( Dependent )
unit
unitVec
end
properties( Access = private )
unit_;
unitVec_;
end
methods
function obj = set.unit( obj, unit )
unit_ = unit;
updateUnitVecFromUnit( obj );
end
function unit = get.unit( obj )
unit = obj.unit_;
end
function obj = set.unitVec( obj, unitVec )
unitVec_ = unitVec;
updateUnitFromUnitVec( obj );
end
function unitVec = get.unitVec( obj )
unitVec = obj.unitVec_;
end
end
methods( Access = private )
function updateUnitFromUnitVec( obj )
obj.unit_ = f( obj.unitVec_ );
end
function updateUnitVecFromUnit( obj )
obj.unitVec_ = f2( obj.unit_ );
end
end
There may be some errors in there as I did it off the top of my head, but the general idea is that only a dependent property is allowed to (or rather should do) alter other properties in its set function so you use a double property solution with a private property for each that actually stores the value and a dependent property which is publicly visible and whose set function will then update the other property also.
It is very important though that you update unit_ and unitVec_ in the functions as shown above otherwise you will have a circular set of calls that will lead you to infinite recursion! My code above just uses placeholder functions f and f2 instead of whatever it is you have already written to update one property from the other.
You could use a property listener. I do in many many cases, but not usually if I am doing something like this.
Più risposte (0)
Vedere anche
Categorie
Scopri di più su Interactive Control and Callbacks in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!