Pārlūkot izejas kodu

Fix memory errors and improve builder

Eric Ramat 7 gadi atpakaļ
vecāks
revīzija
e9d7b7505d

+ 7 - 6
src/artis/builder/Builder.hpp

@@ -58,6 +58,7 @@ private:
         using boost::property_tree::ptree;
 
         kernel::AbstractModel < U, V >* model = nullptr;
+        kernel::AbstractModels < U, V > submodels;
         std::string name;
         ptree::const_iterator it_type = pt.end();
         ptree::const_iterator it_name = pt.end();
@@ -82,11 +83,6 @@ private:
             }
         }
 
-        // type
-        if (it_type != pt.end()) {
-            model = F::factory().create(
-                it_type->second.get_value < std::string >());
-        }
         // name
         if (it_name != pt.end()) {
             name = it_type->second.get_value < std::string >();
@@ -95,7 +91,7 @@ private:
         if (it_submodels != pt.end()) {
             for (ptree::const_iterator itm = it_submodels->second.begin();
                  itm != it_submodels->second.end(); ++itm) {
-                build_model(itm->second);
+                submodels.push_back(build_model(itm->second));
             }
         }
         // states
@@ -110,6 +106,11 @@ private:
         if (it_externals != pt.end()) {
             build_externals(it_externals->second, model);
         }
+        // type
+        if (it_type != pt.end()) {
+            model = F::factory().create(
+                    it_type->second.get_value < std::string >(), submodels);
+        }
         return model;
     }
 

+ 19 - 15
src/artis/builder/ModelFactory.hpp

@@ -30,9 +30,11 @@
 
 #include <boost/core/demangle.hpp>
 
+#include <artis/kernel/AbstractModel.hpp>
+
 namespace artis { namespace builder {
 
-template < typename M >
+template < typename M, typename U, typename V >
 class ObjectCreator
 {
 public:
@@ -43,13 +45,14 @@ public:
 
     virtual std::string get() const = 0;
 
-    virtual M* operator()() const = 0;
+    virtual M* operator()(artis::kernel::AbstractModels < U,
+                          V > submodels) const = 0;
 };
 
-template < typename M, typename I, typename O >
+template < typename M, typename I, typename O, typename U, typename V >
 class ModelFactory
 {
-    typedef ModelFactory < M, I, O > type;
+    typedef ModelFactory < M, I, O, U, V > type;
 
 public:
     virtual ~ModelFactory()
@@ -63,13 +66,14 @@ public:
                                    std::make_pair(id, creator))).second;
     }
 
-    M* create(const std::string& id)
+    M* create(const std::string& id, artis::kernel::AbstractModels < U,
+              V > submodels)
     {
         std::lock_guard < std::mutex > lock(_mutex);
         typename Creators::const_iterator it = creators.find(id);
 
         if (it != creators.end()) {
-            return (*it->second.second)();
+            return (*it->second.second)(submodels);
         } else {
             return nullptr;
         }
@@ -118,15 +122,15 @@ private:
 
 } }
 
-template < typename M, typename I, typename O >
-std::shared_ptr < artis::builder::ModelFactory < M, I, O > >
-artis::builder::ModelFactory < M, I, O >::_instance;
+template < typename M, typename I, typename O, typename U, typename V >
+std::shared_ptr < artis::builder::ModelFactory < M, I, O, U, V > >
+artis::builder::ModelFactory < M, I, O, U, V >::_instance;
 
-template < typename M, typename I, typename O >
-std::once_flag artis::builder::ModelFactory < M, I, O >::_flag;
+template < typename M, typename I, typename O, typename U, typename V >
+std::once_flag artis::builder::ModelFactory < M, I, O, U, V >::_flag;
 
-#define DECLARE_MODEL(mdl, type, fct)                                   \
-    class creator_##mdl : public artis::builder::ObjectCreator < type > { \
+#define DECLARE_MODEL(mdl, type, fct, U, V )                            \
+    class creator_##mdl : public artis::builder::ObjectCreator < type, U, V > { \
     public:                                                             \
     creator_##mdl()                                                     \
         {                                                               \
@@ -134,8 +138,8 @@ std::once_flag artis::builder::ModelFactory < M, I, O >::_flag;
         }                                                               \
     std::string get() const                                             \
         { return boost::core::demangle(typeid(mdl).name()); }           \
-    type* operator()() const                                            \
-        { return new mdl(); }                                           \
+    type* operator()(artis::kernel::AbstractModels < U, V > submodels) const \
+        { return new mdl(submodels); }                                  \
     static creator_##mdl an_##mdl;                                      \
     };                                                                  \
     creator_##mdl an_##mdl;

+ 3 - 0
src/artis/kernel/AbstractModel.hpp

@@ -155,6 +155,9 @@ protected:
     typename Time::type                       last_time;
 };
 
+template < typename Time, typename Parameters >
+using AbstractModels = std::vector < AbstractModel < Time, Parameters >* >;
+
 } }
 
 #endif

+ 32 - 9
src/test/models.hpp

@@ -38,6 +38,8 @@ struct ModelParameters
 
 using Model = artis::kernel::AbstractModel < artis::utils::DoubleTime,
                                              ModelParameters >;
+using Models = artis::kernel::AbstractModels < artis::utils::DoubleTime,
+        ModelParameters >;
 
 using Trace = artis::utils::Trace < artis::utils::DoubleTime >;
 using TraceElement = artis::utils::TraceElement < artis::utils::DoubleTime >;
@@ -57,7 +59,7 @@ public:
 
     enum internals { DX, BX, IX };
 
-    AModel()
+    AModel(Models = Models())
     {
         Internal(IX, &AModel::_ix);
         Internal(BX, &AModel::_bx);
@@ -103,7 +105,7 @@ public:
     enum internals { IY, IZ, BY, DY };
     enum states { N };
 
-    BModel()
+    BModel(Models = Models())
     {
         // external(IX, &BModel::_ix);
         Externals(int, (( IX, &BModel::_ix )));
@@ -172,15 +174,32 @@ public:
     enum internals { IY, BY, DY, IZ, DX };
     enum states { N };
 
+    RootModel(Models submodels) :
+            _a(dynamic_cast < AModel* >(submodels[0])),
+            _b(dynamic_cast < BModel* >(submodels[1]))
+    {
+        // submodels
+        Submodels(((A, _a), (B, _b)));
+
+        // internals
+        Internal(DX, &RootModel::_dx);
+        InternalsS(((IY, _b, BModel::IY), (IZ, _b, BModel::IZ)));
+        InternalS(BY, _b, BModel::BY);
+
+        // states
+        States(int, ((N, &RootModel::_n)));
+        // State(N, &RootModel::_n);
+    }
+
     RootModel() : _a(new AModel), _b(new BModel)
     {
         // submodels
-        Submodels(((A, _a.get()), (B, _b.get())));
+        Submodels(((A, _a), (B, _b)));
 
         // internals
         Internal(DX, &RootModel::_dx);
-        InternalsS(((IY, _b.get(), BModel::IY), (IZ, _b.get(), BModel::IZ)));
-        InternalS(BY, _b.get(), BModel::BY);
+        InternalsS(((IY, _b, BModel::IY), (IZ, _b, BModel::IZ)));
+        InternalS(BY, _b, BModel::BY);
 
         // states
         States(int, ((N, &RootModel::_n)));
@@ -188,11 +207,15 @@ public:
     }
 
     virtual ~RootModel()
-    { }
+    {
+        delete _a;
+        delete _b;
+    }
 
     void compute(double t, bool /* update */)
     {
-        ::Trace::trace() << ::TraceElement(this->path(this), t, artis::utils::COMPUTE)
+        ::Trace::trace() << ::TraceElement(this->path(this), t,
+                                           artis::utils::COMPUTE)
                          << "Start";
         ::Trace::trace().flush();
         (*_a)(t);
@@ -216,8 +239,8 @@ public:
 
 private:
     // submodels
-    std::unique_ptr < AModel > _a;
-    std::unique_ptr < BModel > _b;
+    AModel* _a;
+    BModel* _b;
 
     //internals
     double _dx;

+ 11 - 6
src/test/test.cpp

@@ -35,12 +35,17 @@
 using namespace artis::kernel;
 using namespace artis::builder;
 
-using Creator = ObjectCreator < Model >;
-using Factory = ModelFactory < Model, int, Creator >;
-
-DECLARE_MODEL(AModel, ::Model, ::Factory);
-DECLARE_MODEL(BModel, ::Model, ::Factory);
-DECLARE_MODEL(RootModel, ::Model, ::Factory);
+using Creator = ObjectCreator < Model, artis::utils::DoubleTime,
+                                ModelParameters >;
+using Factory = ModelFactory < Model, int, Creator, artis::utils::DoubleTime,
+                               ModelParameters >;
+
+DECLARE_MODEL(AModel, ::Model, ::Factory, artis::utils::DoubleTime,
+              ModelParameters);
+DECLARE_MODEL(BModel, ::Model, ::Factory, artis::utils::DoubleTime,
+              ModelParameters);
+DECLARE_MODEL(RootModel, ::Model, ::Factory, artis::utils::DoubleTime,
+              ModelParameters);
 
 typedef artis::kernel::Simulator < RootModel,
                                    artis::utils::DoubleTime,