diff --git a/applications/test/PtrList/Make/files b/applications/test/PtrList/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..4bfd49bde04e8d290f2aa7041966dfc8b3dc6c04 --- /dev/null +++ b/applications/test/PtrList/Make/files @@ -0,0 +1,3 @@ +PtrListTest.C + +EXE = $(FOAM_USER_APPBIN)/PtrListTest diff --git a/applications/test/PtrList/Make/options b/applications/test/PtrList/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/applications/test/PtrList/PtrListTest.C b/applications/test/PtrList/PtrListTest.C new file mode 100644 index 0000000000000000000000000000000000000000..8de64a9d3cdfb6a7f2250a7059caacd0c40350f6 --- /dev/null +++ b/applications/test/PtrList/PtrListTest.C @@ -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; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/functionObjectList/functionObjectList.C b/src/OpenFOAM/db/functionObjectList/functionObjectList.C index 760cf83a2a51907a7dc1ae7ecc5ae06dbdabc5a1..8bb900edfd083eb66740c56ee0289a57a62f22e6 100644 --- a/src/OpenFOAM/db/functionObjectList/functionObjectList.C +++ b/src/OpenFOAM/db/functionObjectList/functionObjectList.C @@ -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_; + + // avoid reading/initializing if execution is off + if (!execution_) + { + return ok; + } - if (foDict_.found("functions")) + // Update existing and add new functionObjects + const entry* entryPtr = parentDict_.lookupEntryPtr("functions",false,false); + if (entryPtr) { - HashPtrTable<dictionary> functionDicts(foDict_.lookup("functions")); + PtrList<functionObject> newPtrs; + HashTable<label> newIndices; - // Update existing and add new functionObjects - forAllConstIter(HashPtrTable<dictionary>, functionDicts, iter) - { - if (found(iter.key())) - { - read = find(iter.key())()->read(*iter()) && read; - } - else - { - functionObject* functionObjectPtr = - functionObject::New(iter.key(), time_, *iter()).ptr(); + label nFunc = 0; - functionObjectPtr->start(); + if (entryPtr->isDict()) + { + // a dictionary of functionObjects + const dictionary& functionDicts = entryPtr->dict(); + newPtrs.setSize(functionDicts.size()); - insert(iter.key(), functionObjectPtr); + forAllConstIter(dictionary, functionDicts, iter) + { + // 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++; } } - - // Remove deleted functionObjects - forAllIter(HashPtrTable<functionObject>, *this, iter) + else { - if (!functionDicts.found(iter.key())) + // a list of functionObjects + PtrList<entry> functionDicts(entryPtr->stream()); + newPtrs.setSize(functionDicts.size()); + + forAllIter(PtrList<entry>, functionDicts, iter) { - erase(iter); + // 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++; } } + + // 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; } diff --git a/src/OpenFOAM/db/functionObjectList/functionObjectList.H b/src/OpenFOAM/db/functionObjectList/functionObjectList.H index 78462b653bef92507b97496d6b552c26cbc89cc4..1b0d51c066f8907504a7bf9ce96aaf14cc99eba6 100644 --- a/src/OpenFOAM/db/functionObjectList/functionObjectList.H +++ b/src/OpenFOAM/db/functionObjectList/functionObjectList.H @@ -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(); };