reworked functionObjectList to use PtrList

- This was originally plan 'B', but it is actually probably more efficient
  than using PtrDictionary anyhow.
- straightened out the return value logic, but it wasn't being used anywhere
  anyhow.
- new 'updated_' data member avoids inadvertent execution in the read()
  method when execution is turned off.
This commit is contained in:
Mark Olesen 2008-12-19 09:29:58 +01:00
parent 707dbe066f
commit 79e9a90c0e
5 changed files with 272 additions and 79 deletions

View File

@ -0,0 +1,3 @@
PtrListTest.C
EXE = $(FOAM_USER_APPBIN)/PtrListTest

View File

View File

@ -0,0 +1,112 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
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 2 of the License, or (at your
option) any later version.
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
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Application
Description
\*---------------------------------------------------------------------------*/
#include "OSspecific.H"
#include "scalar.H"
#include "IOstreams.H"
#include "PtrList.H"
using namespace Foam;
class Scalar
{
scalar data_;
public:
Scalar()
:
data_(0)
{}
Scalar(scalar val)
:
data_(val)
{}
~Scalar()
{
Info <<"delete Scalar: " << data_ << endl;
}
friend Ostream& operator<<(Ostream& os, const Scalar& val)
{
os << val.data_;
return os;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
PtrList<Scalar> list1(10);
PtrList<Scalar> list2(15);
forAll(list1, i)
{
list1.set(i, new Scalar(1.3*i));
}
forAll(list2, i)
{
list2.set(i, new Scalar(10 + 1.3*i));
}
Info<<"list1: " << list1 << endl;
Info<<"list2: " << list2 << endl;
Info<<"indirectly delete some items via set(.., 0) :" << endl;
for (label i = 0; i < 3; i++)
{
list1.set(i, 0);
}
Info<<"transfer list2 -> list1:" << endl;
list1.transfer(list2);
Info<<"list1: " << list1 << endl;
Info<<"list2: " << list2 << endl;
Info<<"indirectly delete some items via setSize :" << endl;
list1.setSize(4);
Info<<"list1: " << list1 << endl;
Info<< nl << "Done." << endl;
return 0;
}
// ************************************************************************* //

View File

@ -27,6 +27,26 @@ License
#include "functionObjectList.H"
#include "Time.H"
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
Foam::functionObject* Foam::functionObjectList::remove(const word& key)
{
functionObject* ptr = 0;
// Find index of existing functionObject
HashTable<label>::iterator fnd = indices_.find(key);
if (fnd != indices_.end())
{
// remove the pointer from the old list
ptr = functions_.set(fnd(), 0).ptr();
indices_.erase(fnd);
}
return ptr;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjectList::functionObjectList
@ -35,24 +55,28 @@ Foam::functionObjectList::functionObjectList
const bool execution
)
:
HashPtrTable<functionObject>(),
functions_(),
indices_(),
time_(t),
foDict_(t.controlDict()),
execution_(execution)
parentDict_(t.controlDict()),
execution_(execution),
updated_(false)
{}
Foam::functionObjectList::functionObjectList
(
const Time& t,
const dictionary& foDict,
const dictionary& parentDict,
const bool execution
)
:
HashPtrTable<functionObject>(),
functions_(),
indices_(),
time_(t),
foDict_(foDict),
execution_(execution)
parentDict_(parentDict),
execution_(execution),
updated_(false)
{}
@ -66,52 +90,28 @@ Foam::functionObjectList::~functionObjectList()
bool Foam::functionObjectList::start()
{
if (execution_)
{
bool ok = false;
if (foDict_.found("functions"))
{
HashPtrTable<functionObject> functions
(
foDict_.lookup("functions"),
functionObject::iNew(time_)
);
transfer(functions);
forAllIter(HashPtrTable<functionObject>, *this, iter)
{
ok = iter()->start() && ok;
}
}
return ok;
}
else
{
return true;
}
return read();
}
bool Foam::functionObjectList::execute()
{
bool ok = true;
if (execution_)
{
bool ok = false;
forAllIter(HashPtrTable<functionObject>, *this, iter)
if (!updated_)
{
ok = iter()->execute() && ok;
read();
}
return ok;
}
else
{
return true;
forAllIter(PtrList<functionObject>, functions_, iter)
{
ok = iter().execute() && ok;
}
}
return ok;
}
@ -129,46 +129,108 @@ void Foam::functionObjectList::off()
bool Foam::functionObjectList::read()
{
bool read = false;
bool ok = true;
updated_ = execution_;
if (foDict_.found("functions"))
// avoid reading/initializing if execution is off
if (!execution_)
{
HashPtrTable<dictionary> functionDicts(foDict_.lookup("functions"));
return ok;
}
// Update existing and add new functionObjects
forAllConstIter(HashPtrTable<dictionary>, functionDicts, iter)
// Update existing and add new functionObjects
const entry* entryPtr = parentDict_.lookupEntryPtr("functions",false,false);
if (entryPtr)
{
PtrList<functionObject> newPtrs;
HashTable<label> newIndices;
label nFunc = 0;
if (entryPtr->isDict())
{
if (found(iter.key()))
// a dictionary of functionObjects
const dictionary& functionDicts = entryPtr->dict();
newPtrs.setSize(functionDicts.size());
forAllConstIter(dictionary, functionDicts, iter)
{
read = find(iter.key())()->read(*iter()) && read;
// safety:
if (!iter().isDict())
{
continue;
}
const word& key = iter().keyword();
const dictionary& dict = iter().dict();
functionObject* objPtr = remove(key);
if (objPtr)
{
// existing functionObject
ok = objPtr->read(dict) && ok;
}
else
{
// new functionObject
objPtr = functionObject::New(key, time_, dict).ptr();
ok = objPtr->start() && ok;
}
newPtrs.set(nFunc, objPtr);
newIndices.insert(key, nFunc);
nFunc++;
}
else
}
else
{
// a list of functionObjects
PtrList<entry> functionDicts(entryPtr->stream());
newPtrs.setSize(functionDicts.size());
forAllIter(PtrList<entry>, functionDicts, iter)
{
functionObject* functionObjectPtr =
functionObject::New(iter.key(), time_, *iter()).ptr();
// safety:
if (!iter().isDict())
{
continue;
}
const word& key = iter().keyword();
const dictionary& dict = iter().dict();
functionObjectPtr->start();
functionObject* objPtr = remove(key);
if (objPtr)
{
// existing functionObject
ok = objPtr->read(dict) && ok;
}
else
{
// new functionObject
objPtr = functionObject::New(key, time_, dict).ptr();
ok = objPtr->start() && ok;
}
insert(iter.key(), functionObjectPtr);
newPtrs.set(nFunc, objPtr);
newIndices.insert(key, nFunc);
nFunc++;
}
}
// Remove deleted functionObjects
forAllIter(HashPtrTable<functionObject>, *this, iter)
{
if (!functionDicts.found(iter.key()))
{
erase(iter);
}
}
// safety:
newPtrs.setSize(nFunc);
// update PtrList of functionObjects
// also deletes existing, unused functionObjects
functions_.transfer(newPtrs);
indices_.transfer(newIndices);
}
else
{
clear();
read = true;
functions_.clear();
indices_.clear();
}
return read;
return ok;
}

View File

@ -26,8 +26,8 @@ Class
Foam::functionObjectList
Description
List of function objects with execute function which is called for
each object.
List of function objects with execute() function that is called for each
object.
See Also
Foam::functionObject and Foam::OutputFilterFunctionObject
@ -41,7 +41,8 @@ SourceFiles
#define functionObjectList_H
#include "functionObject.H"
#include "HashPtrTable.H"
#include "HashTable.H"
#include "PtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -49,26 +50,41 @@ namespace Foam
{
/*---------------------------------------------------------------------------*\
Class functionObjectList Declaration
Class functionObjectList Declaration
\*---------------------------------------------------------------------------*/
class functionObjectList
:
public HashPtrTable<functionObject>
{
// Private data
//- A list of function objects
// Avoid 'is-a' relationship for protection
PtrList<functionObject> functions_;
//- Quick lookup of the index into the PtrList<functionObject>
// Currently only used to manage rereading/deletion
HashTable<label> indices_;
const Time& time_;
//- Dictionary containing the list of function object specifications
const dictionary& foDict_;
//- Dictionary containing the "functions" entry
// This entry can either be a list or a dictionary of
// functionObject specifications.
const dictionary& parentDict_;
//- Switch for the execution of the functionObjects
bool execution_;
//- Tracks if read() was called while execution was turned off
bool updated_;
// Private Member Functions
//- Remove and return the function object pointer by name.
// Return NULL if it didn't exist.
functionObject* remove(const word&);
//- Disallow default bitwise copy construct
functionObjectList(const functionObjectList&);
@ -85,17 +101,17 @@ public:
functionObjectList
(
const Time&,
const bool execution = true
const bool execution=true
);
//- Construct from Time, functionObject dictionary and the execution
// setting
//- Construct from Time, dictionary with "functions" entry
// and the execution setting
functionObjectList
(
const Time&,
const dictionary& foDict,
const bool execution = true
const dictionary& parentDict,
const bool execution=true
);
@ -118,7 +134,7 @@ public:
//- Switch the function objects off
virtual void off();
//- Read and set the function objects if their data has changed
//- Read and set the function objects if their data have changed
virtual bool read();
};