objectRegistry.C 10.9 KB
Newer Older
1
2
3
4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
OpenFOAM bot's avatar
OpenFOAM bot committed
5
6
7
8
    \\  /    A nd           | Copyright (C) 2015-2019 OpenCFD Ltd.
     \\/     M anipulation  |
-------------------------------------------------------------------------------
                            | Copyright (C) 2011-2017 OpenFOAM Foundation
9
10
11
12
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

13
14
15
16
    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
17
18
19
20
21
22
23

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
24
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
25
26
27
28
29

\*---------------------------------------------------------------------------*/

#include "objectRegistry.H"
#include "Time.H"
30
#include "predicates.H"
31
32
33

// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

34
35
namespace Foam
{
36
    defineTypeNameAndDebug(objectRegistry, 0);
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
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //

namespace Foam
{

// Templated implementation for erase() with iterator range.
// Prefer not to expose directly.
template<class InputIter>
static label eraseImpl(objectRegistry& obr, InputIter first, InputIter last)
{
    label changed = 0;

    for
    (
        const label nTotal = obr.size();
        changed < nTotal && first != last; // Terminate early
        ++first
    )
    {
        if (obr.erase(*first))
        {
            ++changed;
        }
    }

    return changed;
}

} // End namespace Foam


71
72
73
74
75
76
77
78
// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //

bool Foam::objectRegistry::parentNotTime() const
{
    return (&parent_ != dynamic_cast<const objectRegistry*>(&time_));
}


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //

const Foam::regIOobject* Foam::objectRegistry::cfindIOobject
(
    const word& name,
    const bool recursive
) const
{
    const_iterator iter = cfind(name);

    if (iter.found())
    {
        return iter.val();
    }
    else if (recursive && this->parentNotTime())
    {
        return parent_.cfindIOobject(name, recursive);
    }

    return nullptr;
}


102
103
// * * * * * * * * * * * * * * * * Constructors *  * * * * * * * * * * * * * //

104
Foam::objectRegistry::objectRegistry(const Time& t, const label nObjects)
105
106
107
108
109
:
    regIOobject
    (
        IOobject
        (
110
            word::validate(t.caseName()),
111
            t.path(),
112
113
114
115
            t,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE,
            false
mattijs's avatar
mattijs committed
116
117
        ),
        true    // to flag that this is the top-level regIOobject
118
    ),
119
    HashTable<regIOobject*>(nObjects),
120
121
    time_(t),
    parent_(t),
mattijs's avatar
mattijs committed
122
123
    dbDir_(name()),
    event_(1)
124
125
126
{}


127
Foam::objectRegistry::objectRegistry(const IOobject& io, const label nObjects)
128
129
:
    regIOobject(io),
130
    HashTable<regIOobject*>(nObjects),
131
132
    time_(io.time()),
    parent_(io.db()),
mattijs's avatar
mattijs committed
133
134
    dbDir_(parent_.dbDir()/local()/name()),
    event_(1)
135
136
137
138
139
140
141
142
143
{
    writeOpt() = IOobject::AUTO_WRITE;
}


// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //

Foam::objectRegistry::~objectRegistry()
{
144
    objectRegistry::clear();
145
146
147
148
149
}


// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //

150
151
152
153
154
155
Foam::HashTable<Foam::wordHashSet> Foam::objectRegistry::classes() const
{
    return classesImpl(*this, predicates::always());
}


156
157
158
159
160
161
162
Foam::label Foam::objectRegistry::count(const char* clsName) const
{
    // No nullptr check - only called with string literals
    return count(static_cast<word>(clsName));
}


163
164
Foam::wordList Foam::objectRegistry::names() const
{
165
166
    return HashTable<regIOobject*>::toc();
}
167
168


169
170
171
Foam::wordList Foam::objectRegistry::sortedNames() const
{
    return HashTable<regIOobject*>::sortedToc();
172
173
174
}


175
Foam::wordList Foam::objectRegistry::names(const char* clsName) const
176
{
177
178
    // No nullptr check - only called with string literals
    return names(static_cast<word>(clsName));
179
180
181
}


182
Foam::wordList Foam::objectRegistry::sortedNames(const char* clsName) const
183
{
184
185
    // No nullptr check - only called with string literals
    return sortedNames(static_cast<word>(clsName));
186
187
188
}


189
190
const Foam::objectRegistry& Foam::objectRegistry::subRegistry
(
191
    const word& name,
192
193
    const bool forceCreate,
    const bool recursive
194
195
) const
{
196
    if (forceCreate && !foundObject<objectRegistry>(name, recursive))
197
    {
198
        objectRegistry* subObr = new objectRegistry
199
200
201
202
203
204
205
206
207
208
        (
            IOobject
            (
                name,
                time().constant(),
                *this,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            )
        );
209
        subObr->store();
210
    }
211
212

    return lookupObject<objectRegistry>(name, recursive);
213
214
215
}


mattijs's avatar
mattijs committed
216
217
218
219
220
221
Foam::label Foam::objectRegistry::getEvent() const
{
    label curEvent = event_++;

    if (event_ == labelMax)
    {
222
223
        if (objectRegistry::debug)
        {
224
            WarningInFunction
225
226
227
228
                << "Event counter has overflowed. "
                << "Resetting counter on all dependent objects." << nl
                << "This might cause extra evaluations." << endl;
        }
mattijs's avatar
mattijs committed
229
230
231
232
233

        // Reset event counter
        curEvent = 1;
        event_ = 2;

234
235
        // No need to reset dependent objects; overflow is now handled
        // in regIOobject::upToDate
mattijs's avatar
mattijs committed
236
237
238
239
240
241
    }

    return curEvent;
}


242
243
244
245
246
247
bool Foam::objectRegistry::checkIn(regIOobject& io) const
{
    if (objectRegistry::debug)
    {
        Pout<< "objectRegistry::checkIn(regIOobject&) : "
            << name() << " : checking in " << io.name()
248
            << " of type " << io.type()
249
250
251
            << endl;
    }

252
253
254
255
256
257
258
259
260
261
262
263
264
    objectRegistry& obr = const_cast<objectRegistry&>(*this);

    bool ok = obr.insert(io.name(), &io);

    if (!ok && objectRegistry::debug)
    {
        WarningInFunction
            << name() << " : attempted to checkIn object with name "
            << io.name() << " which was already checked in"
            << endl;
    }

    return ok;
265
266
267
268
269
}


bool Foam::objectRegistry::checkOut(regIOobject& io) const
{
270
271
272
    objectRegistry& obr = const_cast<objectRegistry&>(*this);

    iterator iter = obr.find(io.name());
273

274
    if (iter.found())
275
276
277
278
    {
        if (objectRegistry::debug)
        {
            Pout<< "objectRegistry::checkOut(regIOobject&) : "
279
                << name() << " : checking out " << io.name()
280
281
282
                << endl;
        }

283
        if (iter.val() != &io)
284
285
286
        {
            if (objectRegistry::debug)
            {
287
                WarningInFunction
288
289
                    << name() << " : attempt to checkOut copy of "
                    << iter.key()
290
291
292
293
294
                    << endl;
            }

            return false;
        }
mattijs's avatar
mattijs committed
295

296
297
        return obr.erase(iter);
    }
mattijs's avatar
mattijs committed
298

299

300
    if (objectRegistry::debug)
301
    {
302
303
304
        Pout<< "objectRegistry::checkOut(regIOobject&) : "
            << name() << " : could not find " << io.name() << " in registry"
            << endl;
Mark Olesen's avatar
Mark Olesen committed
305
    }
306

Mark Olesen's avatar
Mark Olesen committed
307
308
309
310
    return false;
}


311
312
313
314
315
316
bool Foam::objectRegistry::checkOut(const word& key) const
{
    return const_cast<objectRegistry&>(*this).erase(key);
}


317
318
319
320
321
322
323
324
325
void Foam::objectRegistry::clear()
{
    // Free anything owned by the registry
    for (iterator iter = begin(); iter != end(); ++iter)
    {
        regIOobject* ptr = iter.val();

        if (ptr && ptr->ownedByRegistry())
        {
326
327
328
329
330
331
332
333
            // TBD: may wish to have ptr->clearWatches();

            if (objectRegistry::debug)
            {
                Pout<< "objectRegistry::clear : " << ptr->name()
                    <<  " watches :" << flatOutput(ptr->watchIndices()) << nl;

            }
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
            delete ptr;
        }
    }

    HashTable<regIOobject*>::clear();
}


void Foam::objectRegistry::clearStorage()
{
    objectRegistry::clear();
    HashTable<regIOobject*>::clearStorage();
}


349
350
351
352
353
354
355
356
357
358
359
360
bool Foam::objectRegistry::erase(const iterator& iter)
{
    // Free anything owned by the registry

    if (iter.found())
    {
        regIOobject* ptr = iter.val();

        bool ok = HashTable<regIOobject*>::erase(iter);

        if (ptr && ptr->ownedByRegistry())
        {
361
            // TBD: may wish to have ptr->clearWatches();
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
            delete ptr;
        }

        return ok;
    }

    return false;
}


bool Foam::objectRegistry::erase(const word& key)
{
    return erase(find(key));
}


Foam::label Foam::objectRegistry::erase(std::initializer_list<word> keys)
{
     return eraseImpl(*this, keys.begin(), keys.end());
}


Foam::label Foam::objectRegistry::erase(const UList<word>& keys)
{
    return eraseImpl(*this, keys.begin(), keys.end());
}


Mark Olesen's avatar
Mark Olesen committed
390
391
392
void Foam::objectRegistry::rename(const word& newName)
{
    regIOobject::rename(newName);
393

394
395
    // Adjust dbDir_ as well
    const auto i = dbDir_.rfind('/');
Mark Olesen's avatar
Mark Olesen committed
396
397
398
399
400
401
402
403

    if (i == string::npos)
    {
        dbDir_ = newName;
    }
    else
    {
        dbDir_.replace(i+1, string::npos, newName);
404
405
406
407
    }
}


408
409
410
411
412
413
414
415
416
417
bool Foam::objectRegistry::found
(
    const word& name,
    const bool recursive
) const
{
    return cfindIOobject(name, recursive);
}


418
419
bool Foam::objectRegistry::modified() const
{
420
    for (const_iterator iter = cbegin(); iter != cend(); ++iter)
421
    {
422
        if (iter->modified())
423
        {
424
            return true;
425
426
427
        }
    }

428
    return false;
429
430
431
432
433
434
435
436
437
438
439
}


void Foam::objectRegistry::readModifiedObjects()
{
    for (iterator iter = begin(); iter != end(); ++iter)
    {
        if (objectRegistry::debug)
        {
            Pout<< "objectRegistry::readModifiedObjects() : "
                << name() << " : Considering reading object "
440
                << iter.key() << endl;
441
442
        }

443
        iter->readIfModified();
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
    }
}


bool Foam::objectRegistry::readIfModified()
{
    readModifiedObjects();
    return true;
}


bool Foam::objectRegistry::writeObject
(
    IOstream::streamFormat fmt,
    IOstream::versionNumber ver,
459
460
    IOstream::compressionType cmp,
    const bool valid
461
462
463
464
) const
{
    bool ok = true;

465
    for (const_iterator iter = cbegin(); iter != cend(); ++iter)
466
467
468
469
470
    {
        if (objectRegistry::debug)
        {
            Pout<< "objectRegistry::write() : "
                << name() << " : Considering writing object "
471
                << iter.key()
472
                << " of type " << iter->type()
473
                << " with writeOpt " << static_cast<char>(iter->writeOpt())
474
                << " to file " << iter->objectPath()
475
476
477
                << endl;
        }

478
        if (iter->writeOpt() != NO_WRITE)
479
        {
480
            ok = iter->writeObject(fmt, ver, cmp, valid) && ok;
481
482
483
484
485
486
487
488
        }
    }

    return ok;
}


// ************************************************************************* //