objectRegistry.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2017 OpenFOAM Foundation
9 Copyright (C) 2015-2022 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "objectRegistry.H"
30#include "Time.H"
31#include "predicates.H"
32
33// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34
35namespace Foam
36{
38}
39
40
41// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
42
43namespace Foam
44{
45
46// Templated implementation for erase() with iterator range.
47// Prefer not to expose directly.
48template<class InputIter>
49static label eraseImpl(objectRegistry& obr, InputIter first, InputIter last)
50{
51 label changed = 0;
52
53 for
54 (
55 const label nTotal = obr.size();
56 changed < nTotal && first != last; // Terminate early
57 ++first
58 )
59 {
60 if (obr.erase(*first))
61 {
62 ++changed;
63 }
64 }
65
66 return changed;
67}
68
69} // End namespace Foam
70
71
72// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
73
74bool Foam::objectRegistry::parentNotTime() const noexcept
75{
76 return (&parent_ != static_cast<const objectRegistry*>(&time_));
77}
78
79
80// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
81
82Foam::objectRegistry::objectRegistry(const Time& t, const label nObjects)
83:
85 (
87 (
88 word::validate(t.caseName()),
89 t.path(),
90 t,
91 IOobject::NO_READ,
92 IOobject::AUTO_WRITE,
93 false
94 ),
95 true // to flag that this is the top-level regIOobject
96 ),
97 HashTable<regIOobject*>(nObjects),
98 time_(t),
99 parent_(t),
100 dbDir_(name()),
101 event_(1)
102{}
103
104
106:
108 HashTable<regIOobject*>(nObjects),
109 time_(io.time()),
110 parent_(io.db()),
111 dbDir_(parent_.dbDir()/local()/name()),
112 event_(1)
113{
115}
116
117
118// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
119
121{
123}
124
125
126// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
127
129{
130 return (this == &static_cast<const objectRegistry&>(time_));
131}
132
133
135{
136 return classesImpl(*this, predicates::always());
137}
138
139
140Foam::label Foam::objectRegistry::count(const char* clsName) const
141{
142 // No nullptr check - only called with string literals
143 return count(static_cast<word>(clsName));
144}
145
146
149{
150 return objectsTypeImpl<const regIOobject>(*this, predicates::always());
151}
152
153
156{
157 return objectsTypeImpl<const regIOobject>(*this, predicates::always());
158}
159
160
163{
164 return objectsTypeImpl<regIOobject>(*this, predicates::always());
165}
166
167
169{
171}
172
173
175{
177}
178
179
181{
182 // No nullptr check - only called with string literals
183 return names(static_cast<word>(clsName));
184}
185
186
188{
189 // No nullptr check - only called with string literals
190 return sortedNames(static_cast<word>(clsName));
191}
192
193
195(
196 const word& name,
197 const bool forceCreate,
198 const bool recursive
199) const
200{
201 if (forceCreate && !foundObject<objectRegistry>(name, recursive))
202 {
203 objectRegistry* subObr = new objectRegistry
204 (
206 (
207 name,
208 time().constant(),
209 *this,
212 )
213 );
214 subObr->store();
215 }
216
217 return lookupObject<objectRegistry>(name, recursive);
218}
219
220
222{
223 label curEvent = event_++;
224
225 if (event_ == labelMax)
226 {
227 if (objectRegistry::debug)
228 {
230 << "Event counter has overflowed. "
231 << "Resetting counter on all dependent objects." << nl
232 << "This might cause extra evaluations." << endl;
233 }
234
235 // Reset event counter
236 curEvent = 1;
237 event_ = 2;
238
239 // No need to reset dependent objects; overflow is now handled
240 // in regIOobject::upToDate
241 }
242
243 return curEvent;
244}
245
246
248{
249 if (!io) return false;
250
251 if (objectRegistry::debug)
252 {
253 Pout<< "objectRegistry::checkIn : "
254 << name() << " : checking in " << io->name()
255 << " of type " << io->type()
256 << endl;
257 }
258
259 objectRegistry& obr = const_cast<objectRegistry&>(*this);
260
261 bool ok = obr.insert(io->name(), io);
262
263 if (!ok && objectRegistry::debug)
264 {
266 << name() << " : Attempt to checkIn object with name "
267 << io->name() << " which was already checked in"
268 << endl;
269 }
270
271 return ok;
272}
273
274
276{
277 if (!io) return false;
278
279 objectRegistry& obr = const_cast<objectRegistry&>(*this);
280
281 iterator iter = obr.find(io->name());
282
283 if (iter.found())
284 {
285 if (objectRegistry::debug)
286 {
287 Pout<< "objectRegistry::checkOut : "
288 << name() << " : checking out " << io->name()
289 << " of type " << io->type()
290 << endl;
291 }
292
293 if (iter.val() != io)
294 {
295 if (objectRegistry::debug)
296 {
298 << name() << " : Attempt to checkOut copy of "
299 << iter.key()
300 << endl;
301 }
302
303 return false;
304 }
305
306 return obr.erase(iter);
307 }
308
309
310 if (objectRegistry::debug)
311 {
312 Pout<< "objectRegistry::checkOut : "
313 << name() << " : could not find " << io->name() << " in registry"
314 << endl;
315 }
316
317 return false;
318}
319
320
322{
323 return checkIn(&io);
324}
325
326
328{
329 return checkOut(&io);
330}
331
332
334{
335 return const_cast<objectRegistry&>(*this).erase(key);
336}
337
338
340{
341 // Free anything owned by the registry, but first unset both
342 // 'ownedByRegistry' and 'registered' flags to ensure that the
343 // regIOobject destructor will not affect the registry
344
345 for (iterator iter = begin(); iter != end(); ++iter)
346 {
347 regIOobject* ptr = iter.val();
348
349 if (ptr && ptr->ownedByRegistry())
350 {
351 if (objectRegistry::debug)
352 {
353 Pout<< "objectRegistry::clear : " << ptr->name() << nl;
354 }
355
356 ptr->release(true); // Relinquish ownership and registration
357 delete ptr; // Delete also clears fileHandler watches
358 }
359 }
360
362}
363
364
366{
369}
370
371
372bool Foam::objectRegistry::erase(const iterator& iter)
373{
374 // Remove from registry - see notes in objectRegistry::clear()
375
376 if (iter.found())
377 {
378 regIOobject* ptr = const_cast<iterator&>(iter).val();
379
380 const bool ok = HashTable<regIOobject*>::erase(iter);
381
382 if (ptr && ptr->ownedByRegistry())
383 {
384 ptr->release(true); // Relinquish ownership and registration
385 delete ptr; // Delete also clears fileHandler watches
386 }
387
388 return ok;
389 }
390
391 return false;
392}
393
394
396{
397 return erase(find(key));
398}
399
400
401Foam::label Foam::objectRegistry::erase(std::initializer_list<word> keys)
402{
403 return eraseImpl(*this, keys.begin(), keys.end());
404}
405
406
408{
409 return eraseImpl(*this, keys.begin(), keys.end());
410}
411
412
414{
415 regIOobject::rename(newName);
416
417 // Adjust dbDir_ as well
418 const auto i = dbDir_.rfind('/');
419
420 if (i == string::npos)
421 {
422 dbDir_ = newName;
423 }
424 else
425 {
426 dbDir_.replace(i+1, string::npos, newName);
427 }
428}
429
430
432(
433 const word& name,
434 const bool recursive
435) const
436{
437 const_iterator iter = cfind(name);
438
439 if (iter.found())
440 {
441 return iter.val();
442 }
443 else if (recursive && this->parentNotTime())
444 {
445 return parent_.cfindIOobject(name, recursive);
446 }
447
448 return nullptr;
449}
450
451
453(
454 const word& name,
455 const bool recursive
456) const
457{
458 return cfindIOobject(name, recursive);
459}
460
461
463{
464 for (const_iterator iter = cbegin(); iter != cend(); ++iter)
465 {
466 if (iter.val()->modified())
467 {
468 return true;
469 }
470 }
471
472 return false;
473}
474
475
477{
478 for (iterator iter = begin(); iter != end(); ++iter)
479 {
480 if (objectRegistry::debug)
481 {
482 Pout<< "objectRegistry::readModifiedObjects() : "
483 << name() << " : Considering reading object "
484 << iter.key() << endl;
485 }
486
487 iter.val()->readIfModified();
488 }
489}
490
491
493{
494 readModifiedObjects();
495 return true;
496}
497
498
500(
501 IOstreamOption streamOpt,
502 const bool valid
503) const
504{
505 bool ok = true;
506
507 for (const_iterator iter = cbegin(); iter != cend(); ++iter)
508 {
509 if (objectRegistry::debug)
510 {
511 const regIOobject& obj = *iter.val();
512
513 Pout<< "objectRegistry::write() : "
514 << name() << " : Considering writing object "
515 << iter.key() << " of type "
516 << obj.type() << " with writeOpt "
517 << static_cast<int>(obj.writeOpt())
518 << " to file " << obj.objectRelPath() << endl;
519 }
520
521 if (iter.val()->writeOpt() != NO_WRITE)
522 {
523 ok = iter.val()->writeObject(streamOpt, valid) && ok;
524 }
525 }
526
527 return ok;
528}
529
530
531// ************************************************************************* //
bool found
bool checkOut()
Check-out Callback from CallbackRegistry.
Definition: Callback.C:76
bool checkIn()
Register Callback with CallbackRegistry.
Definition: Callback.C:63
A HashTable similar to std::unordered_map.
Definition: HashTable.H:123
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:137
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition: HashTable.C:122
void clearStorage()
Clear the table entries and the table itself.
Definition: HashTable.C:697
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:180
label size() const noexcept
The number of elements in table.
Definition: HashTableI.H:52
iterator find(const Key &key)
Find and return an iterator set at the hashed entry.
Definition: HashTableI.H:114
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition: HashTable.C:440
void clear()
Clear all entries from table.
Definition: HashTable.C:678
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:65
fileName objectRelPath() const
The object path relative to the root.
Definition: IOobject.C:558
writeOption writeOpt() const noexcept
The write option.
Definition: IOobjectI.H:179
The IOstreamOption is a simple container for options an IOstream can normally have.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:329
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition: UListI.H:350
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: UPtrList.H:71
Registry of regIOobjects.
UPtrList< const regIOobject > sorted() const
Return sorted list of objects.
wordList sortedNames() const
The sorted names of all objects.
virtual bool modified() const
Return true if any of the object's files have been modified.
bool isTimeDb() const noexcept
True if the registry is Time.
HashTable< wordHashSet > classes() const
A summary hash of classes used and their associated object names.
virtual ~objectRegistry()
Destructor, with checkOut() for all objects that are ownedByRegistry.
void clearStorage()
Clear all entries from the registry and the table itself.
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write the objects using stream options.
const regIOobject * cfindIOobject(const word &name, const bool recursive=false) const
Return const pointer to the regIOobject.
virtual bool readIfModified()
Read object if modified.
bool erase(const iterator &iter)
Erase an entry specified by the given iterator.
const objectRegistry & subRegistry(const word &name, const bool forceCreate=false, const bool recursive=false) const
Lookup and return a const sub-objectRegistry.
void clear()
Clear all entries from the registry.
UPtrList< const regIOobject > csorted() const
Return sorted list of objects.
void readModifiedObjects()
Read the objects that have been modified.
wordList names() const
The unsorted names of all objects.
virtual void rename(const word &newName)
Rename.
label getEvent() const
Return new event number.
constant condensation/saturation model.
label count() const
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:76
bool ownedByRegistry() const noexcept
Is this object owned by the registry?
Definition: regIOobjectI.H:37
void release(const bool unregister=false) noexcept
Set object as not ownedByRegistry.
Definition: regIOobjectI.H:181
virtual void rename(const word &newName)
Rename.
Definition: regIOobject.C:417
string & replace(const std::string &s1, const std::string &s2, size_type pos=0)
Definition: string.C:108
static constexpr uint64_t npos
Out of range position or size.
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
static label eraseImpl(objectRegistry &obr, InputIter first, InputIter last)
constexpr label labelMax
Definition: label.H:61
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
const direction noexcept
Definition: Scalar.H:223
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
srcOptions erase("case")
thermo validate(args.executable(), "h")
Unary and binary predicates that always return true, useful for templating.
Definition: predicates.H:56