MatrixBerryCore
StructChangeTracker.m
Go to the documentation of this file.
1 classdef StructChangeTracker<mxberry.core.struct.AStructChangeTracker
2  methods
3  function self=StructChangeTracker()
4  end
5  function [SInput,lastVersion]=applyAllLaterPatches(self,SInput,startRev)
6  lastVersion=self.getLastRevision();
7  if isnan(startRev)
8  startRev=-Inf;
9  end
10  %
11  if lastVersion>startRev
12  SInput=self.applyPatches(SInput,startRev,...
13  lastVersion,[false true]);
14  elseif lastVersion<startRev
15  mxberry.core.throwerror('badRepoState',...
16  ['inconsistent '...
17  'state of structure repository: latest patch version',...
18  ' is %d, version of current structure is %d'],...
19  lastVersion,startRev);
20  end
21  end
22  function lastRevNum=getLastRevision(self)
23  [~,revNumVec]=self.findPatchFuncList(-Inf,+Inf,[true true]);
24  if isempty(revNumVec)
25  lastRevNum=nan;
26  else
27  lastRevNum=max(revNumVec);
28  end
29 
30  end
31  function SInput=applyPatches(self,SInput,startRev,endRev,isInclusiveVec)
32  if nargin<5
33  isInclusiveVec=[true true];
34  end
35  %
36  funcHandleList=self.findPatchFuncList(startRev,endRev,isInclusiveVec);
37  nFunc=length(funcHandleList);
38  for iFunc=1:nFunc
39  SInput=feval(funcHandleList{iFunc},SInput);
40  end
41  end
42  end
43  methods(Access=private)
44  function [funcHandleList,revNumVec]=findPatchFuncList(self,startRev,endRev,isInclusiveVec)
45 
46 
47  if ~islogical(isInclusiveVec)
48  mxberry.core.throwerror('wrongInput',...
49  'isInlcusiveVec is expected to have logical type');
50  end
51  if length(isInclusiveVec)~=2
52  mxberry.core.throwerror('wrongInput',...
53  'isInlcusiveVec is expected to be a vector with 2 elements');
54  end
55  metaClass=metaclass(self);
56  methodList=metaClass.Methods;
57  %isPatchVec=cellfun(@(x,y)(x.Static),methodList);
58  isPatchVec=true(size(methodList));
59  if any(isPatchVec)
60  %
61  methodList=methodList(isPatchVec);
62  funcNameList=cellfun(@(x)x.Name,methodList,'UniformOutput',false);
63  %
64  [SResList]=regexp(funcNameList,...
65  '^patch_(?<patchver>\d*)','names');
66  nMatchesVec=cellfun('length',SResList);
67  if any(nMatchesVec>1)
68  mxberry.core.throwerror('badState',...
69  ['Oops, we shouldn''t be here, regular ',...
70  'expression is incorrect']);
71  end
72  %
73  isNumOkVec=~cellfun('isempty',SResList);
74  okRevNumVec=cellfun(@(x)str2double(x.patchver),SResList(isNumOkVec));
75  %
76  if isInclusiveVec(1)
77  isNumOkSubLeftVec=(okRevNumVec>=startRev);
78  else
79  isNumOkSubLeftVec=(okRevNumVec>startRev);
80  end
81  %
82  if isInclusiveVec(2)
83  isNumOkSubRightVec=(okRevNumVec<=endRev);
84  else
85  isNumOkSubRightVec=(okRevNumVec<endRev);
86  end
87  %
88  isNumOkSubVec=isNumOkSubLeftVec&isNumOkSubRightVec;
89  isNumOkVec(isNumOkVec)=isNumOkSubVec;
90  %
91  okRevNumVec=okRevNumVec(isNumOkSubVec);
92  %
93  nFuncHandles=sum(isNumOkVec);
94  funcHandleList=cell(1,nFuncHandles);
95  indNumOkVec=find(isNumOkVec);
96  for iFuncHandle=1:nFuncHandles
97  funcHandleList{iFuncHandle}=eval(['@(y)self.',...
98  funcNameList{indNumOkVec(iFuncHandle)},'(y)']);
99  end
100  %sort the patch names by the patch number
101  [revNumVec,ind]=sort(okRevNumVec);
102  funcHandleList=funcHandleList(ind);
103  %
104  else
105  funcHandleList={};
106  end
107  end
108  end
109 end
function throwerror(in msgTag, in varargin)
THROWERROR works similarly to built-in ERROR function in case when there is no output arguments but s...