diff --git a/App/App.pro b/App/App.pro index 43577a37ab067e0e6f28de20aa687c2bca76d115..35a9741a4ebfe0551f54b13a2d8e823fc09f1b98 100644 --- a/App/App.pro +++ b/App/App.pro @@ -13,7 +13,9 @@ SOURCES += \ src/TestRoughness.cpp \ src/TestDWBAFormFactor.cpp \ src/SampleFactory.cpp \ - src/StandardSamples.cpp + src/StandardSamples.cpp \ + src/CommandLine.cpp \ + src/TestFactory.cpp HEADERS += \ inc/DrawHelper.h \ @@ -25,7 +27,9 @@ HEADERS += \ inc/TestRoughness.h \ inc/TestDWBAFormFactor.h \ inc/SampleFactory.h \ - inc/StandardSamples.h + inc/StandardSamples.h \ + inc/CommandLine.h \ + inc/TestFactory.h INCLUDEPATH += ./inc DEPENDPATH += ./inc diff --git a/App/inc/CommandLine.h b/App/inc/CommandLine.h new file mode 100644 index 0000000000000000000000000000000000000000..78870af2a8fe472888c7193f299c579a17ce3114 --- /dev/null +++ b/App/inc/CommandLine.h @@ -0,0 +1,45 @@ +#ifndef COMMANDLINE_H +#define COMMANDLINE_H +// ******************************************************************** +// * The BornAgain project * +// * Simulation of neutron and x-ray scattering at grazing incidence * +// * * +// * LICENSE AND DISCLAIMER * +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris * +// * eget quam orci. Quisque porta varius dui, quis posuere nibh * +// * mollis quis. Mauris commodo rhoncus porttitor. * +// ******************************************************************** +//! @file CommandLine.h +//! @brief Definition of CommandLine class +//! @author Scientific Computing Group at FRM II +//! @date 01.05.2012 + +#include <string> +#include <vector> + + +//- ------------------------------------------------------------------- +//! @class CommandLine +//! @brief Simple hadling of command line parameters +//- ------------------------------------------------------------------- +class CommandLine +{ +public: + CommandLine(int argc, char **argv) + { + for(int i=1; i<argc; i++) m_pars.push_back(std::string(argv[i])); + } + + //bool operator==(std::string name) { return std::find(m_pars.begin(), m_pars.end(), name)==m_pars.end() ? false : true; } + //bool operator!=(std::string name) { return std::find(m_pars.begin(), m_pars.end(), name)==m_pars.end() ? true : false; } + std::string &operator[](int i) {return m_pars.at(i); } + + size_t size() { return m_pars.size(); } + + bool find(std::string name) {return std::find(m_pars.begin(), m_pars.end(), name)==m_pars.end() ? false : true; } +private: + std::vector<std::string > m_pars; + +}; + +#endif // COMMANDLINE_H diff --git a/App/inc/SampleFactory.h b/App/inc/SampleFactory.h index 0b27e8db880f3a1bfe7a0c8ecc7d03b656cda947..5ffd8b43984891f872797093e0d3030392ac1859 100644 --- a/App/inc/SampleFactory.h +++ b/App/inc/SampleFactory.h @@ -30,12 +30,12 @@ public: static SampleFactory &instance(); //! create sample described by given sampleId - ISample *createStandard(int sampleId); + ISample *createItem(int sampleId); - typedef ISample* (*CreateSampleCallback) (); + typedef ISample* (*CreateItemCallback) (); //! save pointer to the function which will be used for object creation - bool RegisterSample(int sampleId, CreateSampleCallback CreateFn); + bool registerItem(int itemId, CreateItemCallback CreateFn); //! return number of register standard samples size_t getNumberOfSamples() const { return m_callbacks.size(); } @@ -58,10 +58,10 @@ private: static bool m_destroyed; //! holds pointers to function which create sample of given type (which is int) - typedef std::map<int, CreateSampleCallback > SampleCallbackMap_t; + typedef std::map<int, CreateItemCallback > CallbackMap_t; //! holds pointers to function which create sample of given type (which is int) - SampleCallbackMap_t m_callbacks; + CallbackMap_t m_callbacks; }; #endif // SAMPLEFACTORY_H diff --git a/App/inc/StandardSamples.h b/App/inc/StandardSamples.h index edee0f5923f92a7c0581fbeca0dc8d1f8add18fa..6aa9ea52c4e9e07842003e5ada679c86bfe2ac2e 100644 --- a/App/inc/StandardSamples.h +++ b/App/inc/StandardSamples.h @@ -9,15 +9,15 @@ namespace StandardSamples{ ISample *AirOnSubstrate(); const int id_AirOnSubstrate = 0; -const bool reg_AirOnSubstrate = SampleFactory::instance().RegisterSample(id_AirOnSubstrate, AirOnSubstrate); +const bool reg_AirOnSubstrate = SampleFactory::instance().registerItem(id_AirOnSubstrate, AirOnSubstrate); ISample *SubstrateOnSubstrate(); const int id_SubstrateOnSubstrate = 1; -const bool reg_SubstrateOnSubstrate = SampleFactory::instance().RegisterSample(id_SubstrateOnSubstrate, SubstrateOnSubstrate); +const bool reg_SubstrateOnSubstrate = SampleFactory::instance().registerItem(id_SubstrateOnSubstrate, SubstrateOnSubstrate); ISample *SimpleMultilayer(); const int id_SimpleMultilayer = 2; -const bool reg_SimpleMultilayer = SampleFactory::instance().RegisterSample(id_SimpleMultilayer, SimpleMultilayer); +const bool reg_SimpleMultilayer = SampleFactory::instance().registerItem(id_SimpleMultilayer, SimpleMultilayer); } diff --git a/App/inc/TestDWBAFormFactor.h b/App/inc/TestDWBAFormFactor.h index 825c79e6281535285ccc18756f27bbbe69602c86..283358272d7e8fe8efc20539a1c697d17bf84cde 100644 --- a/App/inc/TestDWBAFormFactor.h +++ b/App/inc/TestDWBAFormFactor.h @@ -14,13 +14,13 @@ //! @author herk //! @date 02.05.2012 - -#include "IAlgorithm.h" +#include "IFunctionalTest.h" #include "OutputData.h" #include "FormFactorCylinder.h" #include "DWBAFormFactor.h" -class TestDWBAFormFactor : public IAlgorithm + +class TestDWBAFormFactor : public IFunctionalTest { public: TestDWBAFormFactor(); @@ -36,4 +36,5 @@ private: complex_t reflection_fresnel(double alpha_i); complex_t transmission_fresnel(double alpha_i); + #endif /* TESTDWBAFORMFACTOR_H_ */ diff --git a/App/inc/TestDiffuseScattering.h b/App/inc/TestDiffuseScattering.h index c8f3ff996ff0bc9f3f093703163b03598cd0cc04..d40255b9005e39f95c69de1b5a4aa3de9ccea20d 100644 --- a/App/inc/TestDiffuseScattering.h +++ b/App/inc/TestDiffuseScattering.h @@ -14,10 +14,10 @@ //! @author Scientific Computing Group at FRM II //! @date 01.04.2012 -#include "IAlgorithm.h" +#include "IFunctionalTest.h" #include "MultiLayer.h" -class TestDiffuseScattering : public IAlgorithm +class TestDiffuseScattering : public IFunctionalTest { public: TestDiffuseScattering(); @@ -27,6 +27,8 @@ public: void test1(const MultiLayer &sample); double test1_a(const MultiLayer &sample, const kvector_t &ki, const kvector_t &kf); + static bool registered; }; + #endif // TESTDIFFUSESCATTERING_H diff --git a/App/inc/TestFactory.h b/App/inc/TestFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..42e98b306a304b8b3779e49410575e468d469b9a --- /dev/null +++ b/App/inc/TestFactory.h @@ -0,0 +1,38 @@ +#ifndef TESTFACTORY_H +#define TESTFACTORY_H +// ******************************************************************** +// * The BornAgain project * +// * Simulation of neutron and x-ray scattering at grazing incidence * +// * * +// * LICENSE AND DISCLAIMER * +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris * +// * eget quam orci. Quisque porta varius dui, quis posuere nibh * +// * mollis quis. Mauris commodo rhoncus porttitor. * +// ******************************************************************** +//! @file TestFactory.h +//! @brief Definition of factory class to hold collection of functional tests +//! @author Scientific Computing Group at FRM II +//! @date 01.05.2012 + +#include <string> +#include <map> +#include "ISingleton.h" +#include "IFactory.h" +#include "IFunctionalTest.h" + + +class TestFactory : public ISingleton<TestFactory>, public IFactory<std::string, IFunctionalTest> +{ +public: + TestFactory(); + virtual ~TestFactory() {} + + //! execute specified test + void execute(std::string name); + + //! execute all registered tests + void execute_all(); + +}; + +#endif // TESTFACTORY_H diff --git a/App/inc/TestFormFactor.h b/App/inc/TestFormFactor.h index 205b8dffa69b58765b347152f2e4af668e8a40b6..b0c1e04e0b4d9fc3de2c7ce0a055e430aa3017b6 100644 --- a/App/inc/TestFormFactor.h +++ b/App/inc/TestFormFactor.h @@ -14,12 +14,11 @@ //! @author herk //! @date 02.05.2012 -#include "IAlgorithm.h" +#include "IFunctionalTest.h" #include "OutputData.h" #include "FormFactorCylinder.h" - -class TestFormFactor : public IAlgorithm +class TestFormFactor : public IFunctionalTest { public: TestFormFactor(); @@ -32,4 +31,5 @@ private: FormFactorCylinder m_ff; }; + #endif // TESTFORMFACTOR_H diff --git a/App/inc/TestFresnelCoeff.h b/App/inc/TestFresnelCoeff.h index 78eb9e7408e36da6817c2ceb7ba9f86304aa1dc9..7d22a0094dc3152d1990922dafc302fe38776655 100644 --- a/App/inc/TestFresnelCoeff.h +++ b/App/inc/TestFresnelCoeff.h @@ -14,18 +14,17 @@ #ifndef TESTFRESNELCOEFF_H #define TESTFRESNELCOEFF_H -#include "IAlgorithm.h" +#include "IFunctionalTest.h" #include "OpticalFresnel.h" #include "MultiLayer.h" #include "OutputData.h" - //- ------------------------------------------------------------------- //! @class TestFresnelCoeff //! @brief Calculate Fresnel coefficients for several typical multilayer //! samples and produce validation plots //- ------------------------------------------------------------------- -class TestFresnelCoeff : public IAlgorithm +class TestFresnelCoeff : public IFunctionalTest { public: TestFresnelCoeff(); @@ -40,4 +39,10 @@ private: }; + + + + + + #endif // TESTFRESNELCOEFF_H diff --git a/App/inc/TestRoughness.h b/App/inc/TestRoughness.h index e300af6b8ce810b519dcc62bfe32a7847b920323..b1ba916fc525747dd2ea04ade1ba4f91ac5a68f7 100644 --- a/App/inc/TestRoughness.h +++ b/App/inc/TestRoughness.h @@ -15,11 +15,17 @@ //! @date 02.05.2012 #include <vector> -#include "IAlgorithm.h" +#include "IFunctionalTest.h" #include "LayerRoughness.h" -class TestRoughness : public IAlgorithm +//- ------------------------------------------------------------------- +//! @class TestRoughness +//! @brief Draw profile of rough surface for different sets of +//! roughness parameters. Two models are used for profile calculation: +//! 1) matrix method 2) fast fourier transform using moving average +//- ------------------------------------------------------------------- +class TestRoughness : public IFunctionalTest { public: TestRoughness(); @@ -39,6 +45,7 @@ public: /// some tests of FFT void test_FFT(); + private: LayerRoughness *m_roughness; // pointer to roughness std::vector<double> m_vx; // x-coordinates of grid along the surface @@ -49,4 +56,7 @@ private: std::vector<TestMethod > m_TestMethods; // collection of class methods which will be used for correlated randoms }; + + + #endif // TESTROUGHNESS_H diff --git a/App/src/CommandLine.cpp b/App/src/CommandLine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9694ac59e466d5af38c2ed2fe58d1c8f616d9502 --- /dev/null +++ b/App/src/CommandLine.cpp @@ -0,0 +1,5 @@ +#include "CommandLine.h" + +//CommandLine::CommandLine() +//{ +//} diff --git a/App/src/SampleFactory.cpp b/App/src/SampleFactory.cpp index 98667d0e55f6167bb23e011b3a146c421de0bfa4..8a7d88a9941c2705f9f5d026ee36acbcfb025b40 100644 --- a/App/src/SampleFactory.cpp +++ b/App/src/SampleFactory.cpp @@ -64,27 +64,27 @@ void SampleFactory::onDeadReference() { // This function is used to automatically register new classes and their // creaion methods /* ************************************************************************* */ -bool SampleFactory::RegisterSample(int sampleId, CreateSampleCallback CreateFn) +bool SampleFactory::registerItem(int itemId, CreateItemCallback CreateFn) { - SampleCallbackMap_t::const_iterator it = m_callbacks.find(sampleId); + CallbackMap_t::const_iterator it = m_callbacks.find(itemId); if( it != m_callbacks.end() ) { - std::cout << "SampleFactory::RegisterSample() -> Panic. Already registered sampleId " << sampleId << std::endl; + std::cout << "SampleFactory::RegisterSample() -> Panic. Already registered itemId " << itemId << std::endl; throw ExistingClassRegistrationException("already registered object"); } - std::cout << "SampleFactory::RegisterSample() -> Info. Registering sample " << sampleId << std::endl; - return m_callbacks.insert( SampleCallbackMap_t::value_type(sampleId, CreateFn)).second; + std::cout << "SampleFactory::RegisterSample() -> Info. Registering sample " << itemId << std::endl; + return m_callbacks.insert( CallbackMap_t::value_type(itemId, CreateFn)).second; } /* ************************************************************************* */ // creation of standard sample of given sampleId type /* ************************************************************************* */ -ISample *SampleFactory::createStandard(int sampleId) +ISample *SampleFactory::createItem(int itemId) { - SampleCallbackMap_t::const_iterator it = m_callbacks.find(sampleId); + CallbackMap_t::const_iterator it = m_callbacks.find(itemId); if( it == m_callbacks.end() ) { // sample with such sampleId have not been registered in the database - std::cout << "SampleFactory::createStandard() -> Panic. Unknown sampleId " << sampleId << std::endl; + std::cout << "SampleFactory::createStandard() -> Panic. Unknown sampleId " << itemId << std::endl; throw UnknownClassRegistrationException("Unknown sampleId"); } // invoke the creation function diff --git a/App/src/TestDWBAFormFactor.cpp b/App/src/TestDWBAFormFactor.cpp index faa4605218a92a3ea95e090a6d24ab0a4ca45c64..000ded066b566933af4285e4577fbea150e426fc 100644 --- a/App/src/TestDWBAFormFactor.cpp +++ b/App/src/TestDWBAFormFactor.cpp @@ -15,6 +15,8 @@ #include <cmath> #include <iostream> + + TestDWBAFormFactor::TestDWBAFormFactor() : m_dwba_ff(new FormFactorCylinder(50.0, 50.0)) { diff --git a/App/src/TestDiffuseScattering.cpp b/App/src/TestDiffuseScattering.cpp index 592b9c4d60c40ebdad79da641a5763f01682fb61..4573195287e4e605537bb9463fab7313a76fa0bf 100644 --- a/App/src/TestDiffuseScattering.cpp +++ b/App/src/TestDiffuseScattering.cpp @@ -17,6 +17,7 @@ #include "MaterialManager.h" + TestDiffuseScattering::TestDiffuseScattering() { std::cout << "TestDiffuseScattering::TestDiffuseScattering() -> Info." << std::endl; diff --git a/App/src/TestFactory.cpp b/App/src/TestFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0640faa54616e58d11e4337994dfd4a13f870d32 --- /dev/null +++ b/App/src/TestFactory.cpp @@ -0,0 +1,54 @@ +#include "TestFactory.h" +#include "TestRoughness.h" +#include "TestFresnelCoeff.h" +#include "TestFormFactor.h" +#include "TestDWBAFormFactor.h" +#include "TestDiffuseScattering.h" + + +//template class ISingleton<IFactory<std::string, IFunctionalTest> >; + + +TestFactory::TestFactory() +{ + setStoreObjects(true); + setDeleteObjects(true); + + registerItem("roughness", IFactoryCreateFunction<TestRoughness, IFunctionalTest> ); + registerItem("fresnel", IFactoryCreateFunction<TestFresnelCoeff, IFunctionalTest> ); + registerItem("formfactor", IFactoryCreateFunction<TestFormFactor, IFunctionalTest> ); + registerItem("dwba", IFactoryCreateFunction<TestDWBAFormFactor, IFunctionalTest> ); + registerItem("diffuse", IFactoryCreateFunction<TestDiffuseScattering, IFunctionalTest> ); +} + + + +/* ************************************************************************* */ +// execute specific functional tests +/* ************************************************************************* */ +void TestFactory::execute(std::string name) +{ + //IFunctionalTest *test = TestFactory::instance().createItem( args[i] ); + IFunctionalTest *test(0); + try { + test = createItem( name ); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + std::cout << "TestFactory::execute() -> Warning. No test with name '" << name << "' is defined." << std::endl; + return; + } + test->execute(); +} + + +/* ************************************************************************* */ +// execute all registered functional tests +/* ************************************************************************* */ +void TestFactory::execute_all() +{ + CallbackMap_t::const_iterator it; + for(it=m_callbacks.begin(); it != m_callbacks.end(); it++ ) { + createItem( it->first )->execute(); + } +} + diff --git a/App/src/TestFormFactor.cpp b/App/src/TestFormFactor.cpp index f2db9c208ee796fdf4914cbf4550dcd899f4514e..ec2675249edca7ec7cd33e14a7fff4971081454e 100644 --- a/App/src/TestFormFactor.cpp +++ b/App/src/TestFormFactor.cpp @@ -8,6 +8,7 @@ #include <cmath> #include <iostream> + TestFormFactor::TestFormFactor() : m_ff(50.0, 50.0) { diff --git a/App/src/TestFresnelCoeff.cpp b/App/src/TestFresnelCoeff.cpp index 2f55d77ae0fb7a2bf841ee745f3ec9ff7289b367..7061903c1b20055ff675cc17ba169120d1916e76 100644 --- a/App/src/TestFresnelCoeff.cpp +++ b/App/src/TestFresnelCoeff.cpp @@ -17,6 +17,7 @@ #include "Units.h" #include "OutputData.h" + TestFresnelCoeff::TestFresnelCoeff() { std::cout << "TestFresnelCoeff::TestFresnelCoeff() -> Info." << std::endl; @@ -33,7 +34,7 @@ void TestFresnelCoeff::execute() // loop over standard samples defined in SampleFactory and StandardSamples size_t nsamples = SampleFactory::instance().getNumberOfSamples(); for(size_t i_sample=0; i_sample<nsamples; i_sample++){ - m_sample = dynamic_cast<MultiLayer *>(SampleFactory::instance().createStandard(i_sample)); + m_sample = dynamic_cast<MultiLayer *>(SampleFactory::instance().createItem(i_sample)); m_coeffs = new OutputData<OpticalFresnel::MultiLayerCoeff_t >; diff --git a/App/src/TestRoughness.cpp b/App/src/TestRoughness.cpp index f15c22f46954b574d6649a036a4d146b16009d51..c02db857eb5518257e7a84122f74627fdb15614f 100644 --- a/App/src/TestRoughness.cpp +++ b/App/src/TestRoughness.cpp @@ -21,7 +21,9 @@ #include <fftw3.h> -TestRoughness::TestRoughness() : m_roughness(0) + +TestRoughness::TestRoughness() : IFunctionalTest("roughness","draw roughness profile"), + m_roughness(0) { } diff --git a/App/src/main.cpp b/App/src/main.cpp index 2ebee5d96d5c57dc0004dd050ee34353adb4382b..7a836880ddad57980034b30b18f70ed5f7d3310b 100644 --- a/App/src/main.cpp +++ b/App/src/main.cpp @@ -1,9 +1,6 @@ -#include "TestFresnelCoeff.h" -#include "TestDiffuseScattering.h" -#include "TestFormFactor.h" -#include "TestDWBAFormFactor.h" -#include "TestRoughness.h" +#include "TestFactory.h" #include "DrawHelper.h" +#include "CommandLine.h" #include <iostream> #include <string> @@ -12,67 +9,36 @@ bool exists(int argc, char **argv, const std::string &stext); + + int main(int argc, char **argv) { std::cout << "Hello Brave New World!" << std::endl; - TApplication theApp("theApp", &argc, argv); - - DrawHelper::SetStyle(); - // user algorithm to test reflection/refraction coefficients for multilayer system - if( exists(argc, argv, "fresnel") ) { - TestFresnelCoeff test; - test.execute(); - } - - // user algorithm to test cross-section for diffuse (uncoherent) scattering - if( exists(argc, argv, "diffuse") ) { - TestDiffuseScattering test; - test.execute(); - } + CommandLine args(argc, argv); // parsing command line arguments - // user algorithm to test the form factor calculation - if( exists(argc, argv,"formfactor") ) { - TestFormFactor test; - test.execute(); - } - - // user algorithm to test roughness - if( exists(argc, argv, "roughness") ) { - TestRoughness test; - test.execute(); - } + TApplication theApp("theApp", &argc, argv); + DrawHelper::SetStyle(); - // user algorithm to test DWBA formfactors - if( exists(argc, argv, "dwba") ) { - TestDWBAFormFactor test; - test.execute(); + // running functional tests + if( args.find("all") ) { + // running all registered tests + TestFactory::instance().execute_all(); + } else { + // running specified tests + for(size_t i=0; i<args.size(); i++) TestFactory::instance().execute( args[i] ); } - // utility which saves user plots in multi-page pdf file - if( exists(argc, argv, "report") ) { + // saving postscript report + if( args.find("report") ) { DrawHelper::SaveReport(); } - if(gApplication) { + // holding graphics if not in the batch mode + if(gApplication && !args.find("-b") ) { std::cout << "main() -> Info. Holding graphics, press ctrl-C to exit..." << std::endl; gApplication->Run(); } - return 0; -} - - -/* ************************************************************************* */ -// check existance -/* ************************************************************************* */ -bool exists(int argc, char **argv, const std::string &stext) -{ - if(argc<=1) return false; - - for(int i=1; i<argc; i++) { - std::string spar(argv[i]); - if( spar.find(stext) != std::string::npos ) return true; - } - return false; + return 0; } diff --git a/Core/Core.pro b/Core/Core.pro index 33fbe33f6f4c1551b25cca287a12167f640c6ee2..853968cf39173a72eecd43c2648a1cd4e0dd1e91 100644 --- a/Core/Core.pro +++ b/Core/Core.pro @@ -31,7 +31,10 @@ SOURCES += \ src/FormFactorCylinder.cpp \ src/Types.cpp \ src/DoubleToComplexInterpolatingFunction.cpp \ - src/DWBAFormFactor.cpp + src/DWBAFormFactor.cpp \ + src/ISingleton.cpp \ + src/IFunctionalTest.cpp \ + src/IFactory.cpp HEADERS += \ inc/ISample.h \ @@ -62,7 +65,10 @@ HEADERS += \ inc/IDoubleToComplexFunction.h \ inc/DoubleToComplexInterpolatingFunction.h \ inc/DWBAFormFactor.h \ - inc/Units.h + inc/Units.h \ + inc/ISingleton.h \ + inc/IFunctionalTest.h \ + inc/IFactory.h INCLUDEPATH += /opt/local/include ./inc DEPENDPATH += ./inc diff --git a/Core/inc/IFactory.h b/Core/inc/IFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..5c25b78b9addb9eca9e753b4aa809b8908e1a0f0 --- /dev/null +++ b/Core/inc/IFactory.h @@ -0,0 +1,109 @@ +#ifndef IFACTORY_H +#define IFACTORY_H +// ******************************************************************** +// * The BornAgain project * +// * Simulation of neutron and x-ray scattering at grazing incidence * +// * * +// * LICENSE AND DISCLAIMER * +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris * +// * eget quam orci. Quisque porta varius dui, quis posuere nibh * +// * mollis quis. Mauris commodo rhoncus porttitor. * +// ******************************************************************** +//! @file IFactory.h +//! @brief Definition of IFactory class +//! @author Scientific Computing Group at FRM II +//! @date 01.05.2012 + +#include <map> +#include <stdexcept> +#include <iostream> +#include <vector> + + +//- ------------------------------------------------------------------- +//! @class IFactory +//! @brief Base class for all factories +//- ------------------------------------------------------------------- +template<class IdentifierType, class AbstractProduct > +class IFactory +{ +public: + IFactory() : m_delete_objects(false), m_store_objects(false) { } + + //! pointer to function which will be used to create object of AbstractProduct base type + typedef AbstractProduct* (*CreateItemCallback) (); + + //! typedef for map which stores correspondance between object identifier and object creation function + typedef std::map<IdentifierType, CreateItemCallback> CallbackMap_t; + + //! create object by calling creation function corresponded to given identifier + AbstractProduct *createItem(const IdentifierType &itemId) + { + typename CallbackMap_t::const_iterator it = m_callbacks.find(itemId); + if( it == m_callbacks.end() ) { + // item with such itemId have not been registered in the database + //std::cout << "IFactory::createItem() -> Warning. No object '" << itemId << "' registered." << std::endl; + throw std::runtime_error("IFactory::createItem() -> Panic. Unknown itemId"); + //return 0; + } + // invoke the creation function + AbstractProduct *x = (it->second)(); + if(m_store_objects) m_objects.push_back(x); + return x; + } + + //! register object's creation function + bool registerItem(const IdentifierType &itemId, CreateItemCallback CreateFn) + { + typename CallbackMap_t::const_iterator it = m_callbacks.find(itemId); + if( it != m_callbacks.end() ) { + throw std::runtime_error("IFactory::createItem() -> Panic. Unknown itemId "); + } + std::cout << "IFactory::RegisterSample() -> Info. Registering sample " << itemId << std::endl; + return m_callbacks.insert( typename CallbackMap_t::value_type(itemId, CreateFn)).second; + } + + ~IFactory() + { + clear(); + } + + //! clear everything + void clear() + { + m_callbacks.clear(); + if(m_delete_objects) { + typename std::vector<AbstractProduct *>::iterator it; + for(it=m_objects.begin(); it!=m_objects.end(); it++) { + delete (*it); + } + } + m_objects.clear(); + } + + //! set flag to delete objects on descruction + void setDeleteObjects(bool delete_objects) { m_delete_objects = delete_objects; } + + //! set flag to store created objects + void setStoreObjects(bool store_objects) { m_store_objects = store_objects; } + +protected: + bool m_delete_objects; //!< will delete created objects on exit then true + bool m_store_objects; //!< will store created objects + CallbackMap_t m_callbacks; //!< map of correspondance of objectsId and creation functions + std::vector<AbstractProduct *> m_objects; +}; + +//! creation function +template<class Derived, class Base > +Base *IFactoryCreateFunction() +{ + return new Derived; +} + + + + +#endif // IFACTORY_H + + diff --git a/Core/inc/IFunctionalTest.h b/Core/inc/IFunctionalTest.h new file mode 100644 index 0000000000000000000000000000000000000000..478a4e7f13ae5d029023a2b4b91228757784dde5 --- /dev/null +++ b/Core/inc/IFunctionalTest.h @@ -0,0 +1,53 @@ +#ifndef IFUNCTIONALTEST_H +#define IFUNCTIONALTEST_H +// ******************************************************************** +// * The BornAgain project * +// * Simulation of neutron and x-ray scattering at grazing incidence * +// * * +// * LICENSE AND DISCLAIMER * +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris * +// * eget quam orci. Quisque porta varius dui, quis posuere nibh * +// * mollis quis. Mauris commodo rhoncus porttitor. * +// ******************************************************************** +//! @file IFunctionalTest.h +//! @brief Defenition of base class for functional tests +//! @author Scientific Computing Group at FRM II +//! @date 01.05.2012 + +#include <string> + + +//- ------------------------------------------------------------------- +//! @class IFunctionalTest +//! @brief Base class for sophisticated functional tests. +//! See also FunctionalTestFactory +//- ------------------------------------------------------------------- +class IFunctionalTest +{ +public: + IFunctionalTest(); + IFunctionalTest(const std::string &name) : m_name(name) {} + IFunctionalTest(const std::string &name, const std::string &descr) : m_name(name), m_description(descr) {} + virtual ~IFunctionalTest(){} + + virtual void execute(); + + //! get name of test + std::string getName() const { return m_name; } + + //! set name of test + void setName(const std::string name) { m_name = name; } + + //! get short description + std::string getDescription() const { return m_description; } + + //! set short description of test + void setDescription(const std::string description) { m_description = description; } + +protected: + std::string m_name; + std::string m_description; + +}; + +#endif // IFUNCTIONALTEST_H diff --git a/Core/inc/ISingleton.h b/Core/inc/ISingleton.h new file mode 100644 index 0000000000000000000000000000000000000000..4e400b4d8d5d1a66c416cc6fd5d4e6cd441f9cba --- /dev/null +++ b/Core/inc/ISingleton.h @@ -0,0 +1,75 @@ +#ifndef ISINGLETON_H +#define ISINGLETON_H +// ******************************************************************** +// * The BornAgain project * +// * Simulation of neutron and x-ray scattering at grazing incidence * +// * * +// * LICENSE AND DISCLAIMER * +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris * +// * eget quam orci. Quisque porta varius dui, quis posuere nibh * +// * mollis quis. Mauris commodo rhoncus porttitor. * +// ******************************************************************** +//! @file ISingleton.h +//! @brief Definition of singleton base template +//! @author Scientific Computing Group at FRM II +//! @date 20.04.2012 + +#include <stdexcept> +#include <iostream> + + +template <class T> +class ISingleton +{ +public: + + static T &instance() + { + // check if exists, if not, then initialise + if( !m_instance) { + // check for dead reference (i.e. object has been initialised but then somebody managed to delete it) + if( m_destroyed ) { + onDeadReference(); + } else { + // first call initalise + create_singleton(); + } + } + std::cout << "ISingleton::instance() -> Info. Accesing instance... " << m_instance << std::endl; + return *m_instance; + } + + virtual ~ISingleton() + { + std::cout << "ISingleton::~ISingleton() -> Deleting singleton" << std::endl; + m_instance = 0; + m_destroyed = true; + } + +protected: + ISingleton() {} + ISingleton(const ISingleton &); + + static void create_singleton() + { + static T theInstance; + m_instance = &theInstance; + std::cout << "ISingleton::create_singleton() -> Info. Creating singleton " << m_instance << std::endl; + } + + static void onDeadReference() + { + throw std::runtime_error("ISingleton::onDeadReference()"); + } + + typedef T* T_Pointer; + + static T_Pointer m_instance; + static bool m_destroyed; +}; + +template<class T > typename ISingleton<T>::T_Pointer ISingleton<T>::m_instance = 0; +template< class T> bool ISingleton<T>::m_destroyed = false; + + +#endif // ISINGLETON_H diff --git a/Core/src/IFactory.cpp b/Core/src/IFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f491231a923f369502ca9c03c295a5defc04e58a --- /dev/null +++ b/Core/src/IFactory.cpp @@ -0,0 +1,5 @@ +#include "IFactory.h" + +//IFactory::IFactory() +//{ +//} diff --git a/Core/src/IFunctionalTest.cpp b/Core/src/IFunctionalTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8da8babfa99702491e77d0d0055e88497f1ca185 --- /dev/null +++ b/Core/src/IFunctionalTest.cpp @@ -0,0 +1,13 @@ +#include "IFunctionalTest.h" +#include "Exceptions.h" + +IFunctionalTest::IFunctionalTest() +{ +} + + +void IFunctionalTest::execute() +{ + throw NotImplementedException("This test can't run."); +} + diff --git a/Core/src/ISingleton.cpp b/Core/src/ISingleton.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2f2bbaf2280b846ebf52db400f837038c9b70a04 --- /dev/null +++ b/Core/src/ISingleton.cpp @@ -0,0 +1,2 @@ +#include "ISingleton.h" +