1 // Created on: 1992-02-03
2 // Created by: Christian CAILLET
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16 
17 #ifndef _Transfer_ProcessForTransient_HeaderFile
18 #define _Transfer_ProcessForTransient_HeaderFile
19 
20 #include <TColStd_IndexedMapOfInteger.hxx>
21 #include <Transfer_TransferMapOfProcessForTransient.hxx>
22 #include <TColStd_MapTransientHasher.hxx>
23 #include <TColStd_HSequenceOfTransient.hxx>
24 
25 class Message_Messenger;
26 class Standard_Transient;
27 class Transfer_Binder;
28 class Transfer_ActorOfProcessForTransient;
29 class Message_ProgressIndicator;
30 class Interface_InterfaceError;
31 class Transfer_TransferFailure;
32 class Transfer_IteratorOfProcessForTransient;
33 class Message_Msg;
34 class Interface_Check;
35 class Interface_CheckIterator;
36 
37 
38 class Transfer_ProcessForTransient;
39 DEFINE_STANDARD_HANDLE(Transfer_ProcessForTransient, Standard_Transient)
40 
41 //! Manages Transfer of Transient Objects. Produces also
42 //! ActorOfTransientProcess       (deferred class),
43 //! IteratorOfTransientProcess    (for Results),
44 //! TransferMapOfTransientProcess (internally used)
45 //! Normally uses as TransientProcess, which adds some specifics
46 
47 class Transfer_ProcessForTransient : public Standard_Transient
48 {
49 
50 public:
51 
52 
53   //! Sets TransferProcess at initial state. Gives an Initial size
54   //! (indicative) for the Map when known (default is 10000).
55   //! Sets default trace file as a printer and default trace level
56   //! (see Message_TraceFile).
57   Standard_EXPORT Transfer_ProcessForTransient(const Standard_Integer nb = 10000);
58 
59   //! Sets TransferProcess at initial state. Gives an Initial size
60   //! (indicative) for the Map when known (default is 10000).
61   //! Sets a specified printer.
62   Standard_EXPORT Transfer_ProcessForTransient(const Handle(Message_Messenger)& printer, const Standard_Integer nb = 10000);
63 
64   //! Resets a TransferProcess as ready for a completely new work.
65   //! Clears general data (roots) and the Map
66   Standard_EXPORT void Clear();
67 
68   //! Rebuilds the Map and the roots to really remove Unbound items
69   //! Because Unbind keeps the entity in place, even if not bound
70   //! Hence, working by checking new items is meaningless if a
71   //! formerly unbound item is rebound
72   Standard_EXPORT void Clean();
73 
74   //! Resizes the Map as required (if a new reliable value has been
75   //! determined). Acts only if <nb> is greater than actual NbMapped
76   Standard_EXPORT void Resize (const Standard_Integer nb);
77 
78   //! Defines an Actor, which is used for automatic Transfer
79   //! If already defined, the new Actor is cumulated
80   //! (see SetNext from Actor)
81   Standard_EXPORT void SetActor (const Handle(Transfer_ActorOfProcessForTransient)& actor);
82 
83   //! Returns the defined Actor. Returns a Null Handle if
84   //! not set.
85   Standard_EXPORT Handle(Transfer_ActorOfProcessForTransient) Actor() const;
86 
87   //! Returns the Binder which is linked with a starting Object
88   //! It can either bring a Result (Transfer done) or none (for a
89   //! pre-binding).
90   //! If no Binder is linked with <start>, returns a Null Handle
91   //! Considers a category number, by default 0
92   Standard_EXPORT Handle(Transfer_Binder) Find (const Handle(Standard_Transient)& start) const;
93 
94   //! Returns True if a Result (whatever its form) is Bound with
95   //! a starting Object. I.e., if a Binder with a Result set,
96   //! is linked with it
97   //! Considers a category number, by default 0
98   Standard_EXPORT Standard_Boolean IsBound (const Handle(Standard_Transient)& start) const;
99 
100   //! Returns True if the result of the transfer of an object is
101   //! already used in other ones. If it is, Rebind cannot change it.
102   //! Considers a category number, by default 0
103   Standard_EXPORT Standard_Boolean IsAlreadyUsed (const Handle(Standard_Transient)& start) const;
104 
105   //! Creates a Link a starting Object with a Binder. This Binder
106   //! can either bring a Result (effective Binding) or none (it can
107   //! be set later : pre-binding).
108   //! Considers a category number, by default 0
109   Standard_EXPORT void Bind (const Handle(Standard_Transient)& start, const Handle(Transfer_Binder)& binder);
110 
111   //! Changes the Binder linked with a starting Object for its
112   //! unitary transfer. This it can be useful when the exact form
113   //! of the result is known once the transfer is widely engaged.
114   //! This can be done only on first transfer.
115   //! Considers a category number, by default 0
116   Standard_EXPORT void Rebind (const Handle(Standard_Transient)& start, const Handle(Transfer_Binder)& binder);
117 
118   //! Removes the Binder linked with a starting object
119   //! If this Binder brings a non-empty Check, it is replaced by
120   //! a VoidBinder. Also removes from the list of Roots as required.
121   //! Returns True if done, False if <start> was not bound
122   //! Considers a category number, by default 0
123   Standard_EXPORT Standard_Boolean Unbind (const Handle(Standard_Transient)& start);
124 
125   //! Returns a Binder for a starting entity, as follows :
126   //! Tries to Find the already bound one
127   //! If none found, creates a VoidBinder and Binds it
128   Standard_EXPORT Handle(Transfer_Binder) FindElseBind (const Handle(Standard_Transient)& start);
129 
130   //! Sets Messenger used for outputting messages.
131   Standard_EXPORT void SetMessenger (const Handle(Message_Messenger)& messenger);
132 
133   //! Returns Messenger used for outputting messages.
134   //! The returned object is guaranteed to be non-null;
135   //! default is Message::Messenger().
136   Standard_EXPORT Handle(Message_Messenger) Messenger() const;
137 
138   //! Sets trace level used for outputting messages:
139   //! <trace> = 0 : no trace at all
140   //! <trace> = 1 : handled exceptions and calls to AddError
141   //! <trace> = 2 : also calls to AddWarning
142   //! <trace> = 3 : also traces new Roots
143   //! (uses method ErrorTrace).
144   //! Default is 1 : Errors traced
145   Standard_EXPORT void SetTraceLevel (const Standard_Integer tracelev);
146 
147   //! Returns trace level used for outputting messages.
148   Standard_EXPORT Standard_Integer TraceLevel() const;
149 
150   //! New name for AddFail (Msg)
151   Standard_EXPORT void SendFail (const Handle(Standard_Transient)& start, const Message_Msg& amsg);
152 
153   //! New name for AddWarning (Msg)
154   Standard_EXPORT void SendWarning (const Handle(Standard_Transient)& start, const Message_Msg& amsg);
155 
156   //! Adds an information message
157   //! Trace is filled if trace level is at least 3
158   Standard_EXPORT void SendMsg (const Handle(Standard_Transient)& start, const Message_Msg& amsg);
159 
160   //! Adds an Error message to a starting entity (to the check of
161   //! its Binder of category 0, as a Fail)
162   Standard_EXPORT void AddFail (const Handle(Standard_Transient)& start, const Standard_CString mess, const Standard_CString orig = "");
163 
164   //! (other name of AddFail, maintained for compatibility)
165   Standard_EXPORT void AddError (const Handle(Standard_Transient)& start, const Standard_CString mess, const Standard_CString orig = "");
166 
167   //! Adds an Error Message to a starting entity from the definition
168   //! of a Msg (Original+Value)
169   Standard_EXPORT void AddFail (const Handle(Standard_Transient)& start, const Message_Msg& amsg);
170 
171   //! Adds a Warning message to a starting entity (to the check of
172   //! its Binder of category 0)
173   Standard_EXPORT void AddWarning (const Handle(Standard_Transient)& start, const Standard_CString mess, const Standard_CString orig = "");
174 
175   //! Adds a Warning Message to a starting entity from the definition
176   //! of a Msg (Original+Value)
177   Standard_EXPORT void AddWarning (const Handle(Standard_Transient)& start, const Message_Msg& amsg);
178 
179   Standard_EXPORT void Mend (const Handle(Standard_Transient)& start, const Standard_CString pref = "");
180 
181   //! Returns the Check attached to a starting entity. If <start>
182   //! is unknown, returns an empty Check
183   //! Adds a case name to a starting entity
184   //! Adds a case value to a starting entity
185   //! Returns the complete case list for an entity. Null Handle if empty
186   //! In the list of mapped items (between 1 and NbMapped),
187   //! searches for the first item which follows <num0>(not included)
188   //! and which has an attribute named <name>
189   //! Attributes are brought by Binders
190   //! Hence, allows such an iteration
191   //!
192   //! for (num = TP->NextItemWithAttribute(name,0);
193   //! num > 0;
194   //! num = TP->NextItemWithAttribute(name,num) {
195   //! .. process mapped item <num>
196   //! }
197   //! Returns the type of an Attribute attached to binders
198   //! If this name gives no Attribute, returns ParamVoid
199   //! If this name gives several different types, returns ParamMisc
200   //! Else, returns the effective type (ParamInteger, ParamReal,
201   //! ParamIdent, or ParamText)
202   //! Returns the list of recorded Attribute Names, as a Dictionary
203   //! of Integer : each value gives the count of items which bring
204   //! this attribute name
205   //! By default, considers all the attribute names
206   //! If <rootname> is given, considers only the attribute names
207   //! which begin by <rootname>
208   Standard_EXPORT Handle(Interface_Check) Check (const Handle(Standard_Transient)& start) const;
209 
210   //! Binds a starting object with a Transient Result.
211   //! Uses a SimpleBinderOfTransient to work. If there is already
212   //! one but with no Result set, sets its Result.
213   //! Considers a category number, by default 0
214   Standard_EXPORT void BindTransient (const Handle(Standard_Transient)& start, const Handle(Standard_Transient)& res);
215 
216   //! Returns the Result of the Transfer of an object <start> as a
217   //! Transient Result.
218   //! Returns a Null Handle if there is no Transient Result
219   //! Considers a category number, by default 0
220   //! Warning : Supposes that Binding is done with a SimpleBinderOfTransient
221   Standard_EXPORT const Handle(Standard_Transient)& FindTransient (const Handle(Standard_Transient)& start) const;
222 
223   //! Prepares an object <start> to be bound with several results.
224   //! If no Binder is yet attached to <obj>, a MultipleBinder
225   //! is created, empty. If a Binder is already set, it must
226   //! accept Multiple Binding.
227   //! Considers a category number, by default 0
228   Standard_EXPORT void BindMultiple (const Handle(Standard_Transient)& start);
229 
230   //! Adds an item to a list of results bound to a starting object.
231   //! Considers a category number, by default 0, for all results
232   Standard_EXPORT void AddMultiple (const Handle(Standard_Transient)& start, const Handle(Standard_Transient)& res);
233 
234   //! Searches for a transient result attached to a starting object,
235   //! according to its type, by criterium IsKind(atype)
236   //!
237   //! In case of multiple result, explores the list and gives in
238   //! <val> the first transient result IsKind(atype)
239   //! Returns True and fills <val> if found
240   //! Else, returns False (<val> is not touched, not even nullified)
241   //!
242   //! This syntactic form avoids to do DownCast : if a result is
243   //! found with the good type, it is loaded in <val> and can be
244   //! immediately used, well initialised
245   Standard_EXPORT Standard_Boolean FindTypedTransient (const Handle(Standard_Transient)& start, const Handle(Standard_Type)& atype, Handle(Standard_Transient)& val) const;
246 
247   //! Searches for a transient result recorded in a Binder, whatever
248   //! this Binder is recorded or not in <me>
249   //!
250   //! This is strictly equivalent to the class method GetTypedResult
251   //! from class SimpleBinderOfTransient, but is just lighter to call
252   //!
253   //! Apart from this, works as FindTypedTransient
254   Standard_EXPORT Standard_Boolean GetTypedTransient (const Handle(Transfer_Binder)& binder, const Handle(Standard_Type)& atype, Handle(Standard_Transient)& val) const;
255 
256   //! Returns the maximum possible value for Map Index
257   //! (no result can be bound with a value greater than it)
258   Standard_EXPORT Standard_Integer NbMapped() const;
259 
260   //! Returns the Starting Object bound to an Index,
261   Standard_EXPORT const Handle(Standard_Transient)& Mapped (const Standard_Integer num) const;
262 
263   //! Returns the Index value bound to a Starting Object, 0 if none
264   Standard_EXPORT Standard_Integer MapIndex (const Handle(Standard_Transient)& start) const;
265 
266   //! Returns the Binder bound to an Index
267   //! Considers a category number, by default 0
268   Standard_EXPORT Handle(Transfer_Binder) MapItem (const Standard_Integer num) const;
269 
270   //! Declares <obj> (and its Result) as Root. This status will be
271   //! later exploited by RootResult, see below (Result can be
272   //! produced at any time)
273   Standard_EXPORT void SetRoot (const Handle(Standard_Transient)& start);
274 
275   //! Enable (if <stat> True) or Disables (if <stat> False) Root
276   //! Management. If it is set, Transfers are considered as stacked
277   //! (a first Transfer commands other Transfers, and so on) and
278   //! the Transfers commanded by an external caller are "Root".
279   //! Remark : SetRoot can be called whatever this status, on every
280   //! object.
281   //! Default is set to True.
282   Standard_EXPORT void SetRootManagement (const Standard_Boolean stat);
283 
284   //! Returns the count of recorded Roots
285   Standard_EXPORT Standard_Integer NbRoots() const;
286 
287   //! Returns a Root Entity given its number in the list (1-NbRoots)
288   Standard_EXPORT const Handle(Standard_Transient)& Root (const Standard_Integer num) const;
289 
290   //! Returns the Binder bound with a Root Entity given its number
291   //! Considers a category number, by default 0
292   Standard_EXPORT Handle(Transfer_Binder) RootItem (const Standard_Integer num) const;
293 
294   //! Returns the index in the list of roots for a starting item,
295   //! or 0 if it is not recorded as a root
296   Standard_EXPORT Standard_Integer RootIndex (const Handle(Standard_Transient)& start) const;
297 
298   //! Returns Nesting Level of Transfers (managed by methods
299   //! TranscriptWith & Co). Starts to zero. If no automatic Transfer
300   //! is used, it remains to zero. Zero means Root Level.
301   Standard_EXPORT Standard_Integer NestingLevel() const;
302 
303   //! Resets Nesting Level of Transfers to Zero (Root Level),
304   //! whatever its current value.
305   Standard_EXPORT void ResetNestingLevel();
306 
307   //! Tells if <start> has been recognized as good candidate for
308   //! Transfer. i.e. queries the Actor and its Nexts
309   Standard_EXPORT Standard_Boolean Recognize (const Handle(Standard_Transient)& start) const;
310 
311   //! Performs the Transfer of a Starting Object, by calling
312   //! the method TransferProduct (see below).
313   //! Mapping and Roots are managed : nothing is done if a Result is
314   //! already Bound, an exception is raised in case of error.
315   Standard_EXPORT Handle(Transfer_Binder) Transferring (const Handle(Standard_Transient)& start);
316 
317   //! Same as Transferring but does not return the Binder.
318   //! Simply returns True in case of success (for user call)
319   Standard_EXPORT Standard_Boolean Transfer (const Handle(Standard_Transient)& start);
320 
321   //! Allows controls if exceptions will be handled
322   //! Transfer Operations
323   //! <err> False : they are not handled with try {} catch {}
324   //! <err> True  : they are
325   //! Default is False: no handling performed
326   Standard_EXPORT void SetErrorHandle (const Standard_Boolean err);
327 
328   //! Returns error handling flag
329   Standard_EXPORT Standard_Boolean ErrorHandle() const;
330 
331   //! Method called when trace is asked
332   //! Calls PrintTrace to display information relevant for starting
333   //! objects (which can be redefined)
334   //! <level> is Nesting Level of Transfer (0 = root)
335   //! <mode> controls the way the trace is done :
336   //! 0 neutral, 1 for Error, 2 for Warning message, 3 for new Root
337   Standard_EXPORT void StartTrace (const Handle(Transfer_Binder)& binder, const Handle(Standard_Transient)& start, const Standard_Integer level, const Standard_Integer mode) const;
338 
339   //! Prints a short information on a starting object. By default
340   //! prints its Dynamic Type. Can be redefined
341   Standard_EXPORT virtual void PrintTrace (const Handle(Standard_Transient)& start, const Handle(Message_Messenger)& S) const;
342 
343   //! Returns True if we are surely in a DeadLoop. Evaluation is not
344   //! exact, it is a "majorant" which must be computed fast.
345   //! This "majorant" is : <alevel> greater than NbMapped.
346   Standard_EXPORT Standard_Boolean IsLooping (const Standard_Integer alevel) const;
347 
348   //! Returns, as an iterator, the log of root transfer, i.e. the
349   //! created objects and Binders bound to starting roots
350   //! If withstart is given True, Starting Objets are also returned
351   Standard_EXPORT Transfer_IteratorOfProcessForTransient RootResult (const Standard_Boolean withstart = Standard_False) const;
352 
353   //! Returns, as an Iterator, the entire log of transfer (list of
354   //! created objects and Binders which can bring errors)
355   //! If withstart is given True, Starting Objets are also returned
356   Standard_EXPORT Transfer_IteratorOfProcessForTransient CompleteResult (const Standard_Boolean withstart = Standard_False) const;
357 
358   //! Returns Binders which are neither "Done" nor "Initial",
359   //! that is Error,Loop or Run (abnormal states at end of Transfer)
360   //! Starting Objects are given in correspondance in the iterator
361   Standard_EXPORT Transfer_IteratorOfProcessForTransient AbnormalResult() const;
362 
363   //! Returns a CheckList as a list of Check : each one is for a
364   //! starting entity which have either check (warning or fail)
365   //! messages are attached, or are in abnormal state : that case
366   //! gives a specific message
367   //! If <erronly> is True, checks with Warnings only are ignored
368   Standard_EXPORT Interface_CheckIterator CheckList (const Standard_Boolean erronly) const;
369 
370   //! Returns, as an Iterator, the log of transfer for one object
371   //! <level> = 0 : this object only
372   //! and if <start> is a scope owner (else, <level> is ignored) :
373   //! <level> = 1 : object plus its immediate scoped ones
374   //! <level> = 2 : object plus all its scoped ones
375   Standard_EXPORT Transfer_IteratorOfProcessForTransient ResultOne (const Handle(Standard_Transient)& start, const Standard_Integer level, const Standard_Boolean withstart = Standard_False) const;
376 
377   //! Returns a CheckList for one starting object
378   //! <level> interpreted as by ResultOne
379   //! If <erronly> is True, checks with Warnings only are ignored
380   Standard_EXPORT Interface_CheckIterator CheckListOne (const Handle(Standard_Transient)& start, const Standard_Integer level, const Standard_Boolean erronly) const;
381 
382   //! Returns True if no check message is attached to a starting
383   //! object. <level> interpreted as by ResultOne
384   //! If <erronly> is True, checks with Warnings only are ignored
385   Standard_EXPORT Standard_Boolean IsCheckListEmpty (const Handle(Standard_Transient)& start, const Standard_Integer level, const Standard_Boolean erronly) const;
386 
387   //! Removes Results attached to (== Unbinds) a given object and,
388   //! according <level> :
389   //! <level> = 0 : only it
390   //! <level> = 1 : it plus its immediately owned sub-results(scope)
391   //! <level> = 2 : it plus all its owned sub-results(scope)
392   Standard_EXPORT void RemoveResult (const Handle(Standard_Transient)& start, const Standard_Integer level, const Standard_Boolean compute = Standard_True);
393 
394   //! Computes a number to be associated to a starting object in
395   //! a check or a check-list
396   //! By default, returns 0; can be redefined
397   Standard_EXPORT virtual Standard_Integer CheckNum (const Handle(Standard_Transient)& start) const;
398 
399   //! Sets Progress indicator
400   Standard_EXPORT void SetProgress (const Handle(Message_ProgressIndicator)& theProgress);
401 
402   //! Gets Progress indicator
403   Standard_EXPORT Handle(Message_ProgressIndicator) GetProgress() const;
404 
405 
406 
407 
408   DEFINE_STANDARD_RTTI_INLINE(Transfer_ProcessForTransient,Standard_Transient)
409 
410 protected:
411 
412 
413 
414 
415 private:
416 
417 
418   //! Same as Find but stores the last access to the map, for a
419   //! faster access on next calls (as Bind does too)
420   //! Considers a category number, by default 0
421   //! C++ : return const &
422   Standard_EXPORT Handle(Transfer_Binder) FindAndMask (const Handle(Standard_Transient)& start);
423 
424   //! Internal action of Transfer, called by Transferring, with or
425   //! without ErrorHandle. It invokes the Actor to work (set by
426   //! SetActor), and tries its Nexts if no result is produced,
427   //! until a Non Null Binder is produced.
428   //! But keep in mind that a Null Binder can allways be returned
429   //! if a Starting Entity has not been recognized at all.
430   Standard_EXPORT Handle(Transfer_Binder) TransferProduct (const Handle(Standard_Transient)& start);
431 
432   Standard_Boolean theerrh;
433   Standard_Integer thetrace;
434   Handle(Message_Messenger) themessenger;
435   Standard_Integer thelevel;
436   Standard_Integer therootl;
437   Standard_Boolean therootm;
438   TColStd_IndexedMapOfInteger theroots;
439   Handle(Standard_Transient) thelastobj;
440   Handle(Transfer_Binder) thelastbnd;
441   Standard_Integer theindex;
442   Handle(Transfer_ActorOfProcessForTransient) theactor;
443   Transfer_TransferMapOfProcessForTransient themap;
444   Handle(Message_ProgressIndicator) myProgress;
445 
446 
447 };
448 
449 
450 
451 
452 
453 
454 
455 #endif // _Transfer_ProcessForTransient_HeaderFile
456