-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFindInstance.m
More file actions
131 lines (124 loc) · 4.85 KB
/
FindInstance.m
File metadata and controls
131 lines (124 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
function [t, matches, parents, locations] = FindInstance(obj, type, varargin)
% FindInstance: Locate instances of certain classes within a class or a struct.
%
% Parameters:
% obj: The object in which to search. Can be a handle or struct. @type handle
% type: The type of the instances to find. @type char
% varargin: Any more arguments are assumed to be character arrays and denote existing
% properties of the instances to find.
%
% Return values:
% t: A PrintTable instance containing information about the matches and their location within
% the passed object. @type PrintTable
% matches: A cell array of all instances that have been found in obj. @type
% cell
% parents: A cell array of all the parent objects/structs whose immediate property is of the
% specified type.
% locations: A cell array of the according locations/paths within the object hierarchy. @type
% cell
%
% Examples:
% s.someclass1 = RandStream('mt19937ar','Seed',1);
% s.foo = 'bar';
% s.nested.one = RandStream('mt19937ar','Seed',56);
% s.nested.two = RandStream('mrg32k3a');
% s.nested.matrix = rand(4,5);
% FindInstance(s,'RandStream');
%
% % You can also automatically select specific properties of the instances as extra parameters:
% FindInstance(s,'RandStream','Seed')
% FindInstance(s,'RandStream','Seed','NormalTransform')
%
% % If you want to obtain references to the found objects:
% [t, m] = FindInstance(s,'RandStream','Seed','NormalTransform');
% disp(m);
%
% @new{0,6,dw,2012-09-25} Added a cell array of the according locations/paths within the object
% hierarchy as optional return value
%
% @change{0,6,dw,2012-07-20} No longer running into an error if an extra specified property
% could not be found
%
% @author Daniel Wirtz @date 2012-06-11
% This class has originally been developed as part of the framework
% KerMor - Model Order Reduction using Kernels:
% - \c Homepage http://www.morepas.org/software/index.html
% - \c Documentation http://www.morepas.org/software/kermor/index.html
%
% Copyright (c) 2011, Daniel Wirtz
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without modification, are
% permitted only in compliance with the BSD license, see
% http://www.opensource.org/licenses/bsd-license.php
if ~isa(obj, 'handle') && ~isstruct(obj)
error('The argument must either be a handle class or a struct.');
end
matches = {};
visited = {};
parents = {};
locations = {};
t = PrintTable('Instances of "%s" in %s (%s)',...
type,inputname(1),class(obj));
t.HasHeader = true;
t.addRow('Location','Class','ID','Parent',varargin{:});
warning('off','MATLAB:structOnObject');
findinst_recur(obj, inputname(1), true);
warning('on','MATLAB:structOnObject');
function findinst_recur(obj, lvl, checkloop)
if checkloop && any(cellfun(@(o)isequal(o,obj),visited))
return;
end
if numel(obj) > 1
if iscell(obj)
for l = 1:length(obj)
findinst_recur(obj{l}, sprintf('%s{%d}',lvl,l), false);
end
else
for l = 1:length(obj)
findinst_recur(obj(l), sprintf('%s(%d)',lvl,l), false);
end
end
else
if isa(obj,'handle')
try
os = struct(obj);
catch ME
% t.addRow(lvl,class(obj),'error',class(obj),{});
% return;
end
elseif isstruct(obj)
os = obj;
end
fn = fieldnames(os);
for idx = 1:length(fn)
if ~isempty(os.(fn{idx}))
prop = os.(fn{idx});
thislvl = [lvl '.' fn{idx}];
if isa(prop,type)
matches{end+1} = prop;%#ok
parents{end+1} = obj;%#ok
locations{end+1} = thislvl;%#ok
st = 'none';
if any(cellfun(@(o)isequal(o,'ID'),fieldnames(prop)))
st = prop.ID;
end
props = cell(1,length(varargin));
for k = 1:length(varargin)
if isprop(prop,varargin{k}) || isfield(prop,varargin{k})
props{k} = prop.(varargin{k});
else
props{k} = 'doesn''t exist';
end
end
t.addRow(thislvl,class(prop),st,class(obj),props{:});
end
if isa(prop, 'handle') || isstruct(prop)
visited{end+1} = obj;%#ok
findinst_recur(prop, thislvl, true);
end
end
end
end
end
end