KerMor  0.9
Model order reduction for nonlinear dynamical systems and nonlinear approximation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DPCMObject.m
Go to the documentation of this file.
1 
2 
3 /* (Autoinserted by mtoc++)
4  * This source code has been filtered by the mtoc++ executable,
5  * which generates code that can be processed by the doxygen documentation tool.
6  *
7  * On the other hand, it can neither be interpreted by MATLAB, nor can it be compiled with a C++ compiler.
8  * Except for the comments, the function bodies of your M-file functions are untouched.
9  * Consequently, the FILTER_SOURCE_FILES doxygen switch (default in our Doxyfile.template) will produce
10  * attached source files that are highly readable by humans.
11  *
12  * Additionally, links in the doxygen generated documentation to the source code of functions and class members refer to
13  * the correct locations in the source code browser.
14  * However, the line numbers most likely do not correspond to the line numbers in the original MATLAB source files.
15  */
16 
18  :public handle {
46  public: /* ( setObservable ) */
47 
68  public:
69 
70  ID = "[]";
99  public:
100 
102 
103  /* Check if this constructor has already been called; if yes, dont assign a new ID
104  * as this might lead to errors in subclasses or with properties (see above) */
105  if isempty(this.ID)
107  this.ID= DPCMObject.generateID;
108  end
109  }
123  protected:
124 
126 
127  if ~KerMor.App.UseDPCM
128  return;
129  end
130 
131  mc = metaclass(this);
132  if isempty(varargin)
133  for idx = 1:length(mc.Properties)
134  end
135  end
136 
137  /* Iterate over all properties that are to be registered */
138  for pidx = 1:length(varargin)
139  if ~ischar(varargin[pidx])
140  error(" All input arguments must be strings. ");
141  end
142  found = false;
143  for idx = 1:length(mc.Properties)
144  if strcmp(mc.Properties[idx].Name,varargin[pidx])
145  p = mc.Properties[idx];
146  found = true;
147  break;
148  end
149  end
150  /* Validity checks */
151  if ~found
152  error(" Property %s does not exists in class %s. ",varargin[pidx],mc.Name);
153  elseif ~strcmp(p.GetAccess," public ")
154  error(" Property %s has GetAccess=%s, "" public "" is required for registering. ",p.Name,p.GetAccess);
155  elseif p.Constant
156  error(" Property %s is marked Constant. ",p.Name,p.GetAccess);
157  elseif p.Transient
158  error(" Transient property %s is not admissible. ",p.Name,p.GetAccess);
159  elseif strcmp(p.SetAccess," private ")
160  error(" Property %s has SetAccess=private, at least "" protected "" is required for registering. ",p.Name,p.GetAccess);
161  end
162 
163  key = [p.DefiningClass.Name " . " p.Name];
164  hlp = strtrim(help(key)); /* key matches the help search path! see doc help */
165 
166  n = regexp(hlp, " @propclass{(?<level>\w*)}\s*(?<text>[^@]*) "," names ");
167  /* Check if property has @propclass tag set */
168  if ~isempty(n)
169  /* Check validity */
170  if ~any(strcmp(n.level,DPCM.PropClasses))
171  error(" Invalid property class: %s ",n.level);
172  end
173  /* Add the listener */
174  if ~any(strcmp(n.level," data "))
175  if ~p.SetObservable
176  error(" Non-passive registered property %s must have the SetObservable flag. ",p.Name);
177  end
178  addlistener(this,p.Name," PostSet ",@(src,evd)this.PropPostSetCallback(src,evd));
179  end
180  /* Only overwrite if not present -> save/load process! */
181  if ~this.PropertiesChanged.containsKey(key)
182  /* Initialize Changed flag to false */
183  ps.Changed= false;
184 
185  /* Get current value and save as default */
186  ps.Default= this.(p.Name);
187  ps.Name= p.Name;
188 
189  /* Add misc help texts and classification */
190  ps.Short= DPCMObject.getHelpShort(hlp);
191  ps.Level= n.level;
192  ps.Text= strtrim(n.text);
193 
194  this.PropertiesChanged(key) = ps;
195  end
196  elseif ~isempty(hlp)
197  error(" When registering a property you must define the @propclass{<level>} tag in the properties help text. ");
198  end
199  end
200  }
210  private:
211 
212  function PropPostSetCallback(unused1,evd) {
213  p = evd.Source;
214  key = [p.DefiningClass.Name " . " p.Name];
215  ps = this.PropertiesChanged(key);
216  if isempty(ps)
217  warning(" DPCMObject:warning "," PostSet called on property %s but dict does not contain key ",key);
218  else
219  if ~ps.Changed
220  this.PropertiesChanged(key).Changed = true;
221  this.PropertiesChanged(key).DefaultConfirmed = isequal(ps.Default,evd.AffectedObject.(p.Name));
222  /* Save some space! */
223  this.PropertiesChanged(key).Default = [];
224  this.PropertiesChanged(key).Text = [];
225  end
226  end
227  }
228 
229 
230  protected: /* ( Static ) */
231 
232  static function obj = loadobj(obj,from) {
233  if nargin > 1
234  obj.ID= from.ID;
235  obj.WorkspaceVariableName= from.WorkspaceVariableName;
236  if isfield(from," PropertiesChanged ") && ~isempty(from.PropertiesChanged)
237  obj.PropertiesChanged= from.PropertiesChanged;
238  keys = obj.PropertiesChanged.Keys;
239  for idx = 1:obj.PropertiesChanged.Count
240  ps = obj.PropertiesChanged(keys[idx]);
241  if ~ps.Changed && ~any(strcmp(ps.Level," data "))
242  if isprop(obj,ps.Name)
243  addlistener(obj,ps.Name," PostSet ",@(src,evd)obj.PropPostSetCallback(src,evd));
244  else
245  warning(" DPCMObject:load "," Property %s of DPCMObject #%s (class %s) does not exist anymore.\nRemoving it from ProperitesChanged dictionary. ",ps.Name,obj.ID,class(obj));
246  obj.PropertiesChanged.clear(keys[idx]);
247  end
248  end
249  end
250  end
251  elseif ~isa(obj," DPCMObject ")
252  warning(" DPCM:loadobj "," Argument 'obj' not a DPCMObject instance but no argument to initialize from given! ");
253  end
254  }
273  private: /* ( Static ) */
274 
275  static function id = generateID() {
276  persistent cnt;
277  if isempty(cnt)
278  cnt = round((sum(clock)+cputime)*1000);
279  end
280  id = sprintf(" %d ",cnt);
281  cnt = cnt+1;
282  }
291  static function charshort = getHelpShort(char txt) {
292  pos = regexp(txt,sprintf(" \n[ ]*\n "));
293  short = ;
294  if ~isempty(pos)
295  short = txt(1:pos(1)-1);
296  else
297  /* Maybe only one line? */
298  pos = strfind(txt,char(10));
299  if ~isempty(pos)
300  short = txt(1:pos(1)-1);
301  end
302  end
303  short = strtrim(short);
304  }
319 };
320 
WorkspaceVariableName
The workspace variable name of this class. Optional.
Definition: DPCMObject.m:48
function registerProps(varargin)
Call this method at any class that defines DPCM observed properties.
Definition: DPCMObject.m:125
static function obj = loadobj(obj, from)
Re-register any registered change listeners!
Definition: DPCMObject.m:232
DPCMObject: Base object for any class participating in the DPCM system.
Definition: DPCMObject.m:17
DPCMObject()
Creates a new DPCM object.
Definition: DPCMObject.m:101
Matlab's base handle class (documentation generation substitute)
DPCM: Default property change monitoring for MatLab class properties.
Definition: DPCM.m:17
A variable number of input arguments.
A basic dictionary of key/value pairs for small to medium amounts of data.
Definition: Dictionary.m:17
ID
An ID that allows to uniquely identify this DPCMObject (at least within the current MatLab session/co...
Definition: DPCMObject.m:70
static const .cell PropClasses
The known property classes.
Definition: DPCM.m:114
PropertiesChanged
The Dictionary containing all the property settings as key/value pairs.
Definition: DPCMObject.m:85
Global configuration class for all KerMor run-time settings.
Definition: KerMor.m:17
static function KerMor theinstance = App()
The singleton KerMor instance.
Definition: KerMor.m:910
addlistener
Creates a listener for the specified event and assigns a callback function to execute when the event ...