Xcos MVC: manage scicos_graphics and scicos_models as MList 11/15111/4
Clément DAVID [Wed, 27 Aug 2014 07:48:26 +0000 (09:48 +0200)]
Ports' Datatypes are now [1 1 1]] by default, to prevent null sizes.

Using mlist avoid a model::Block merge at graphics or model assignation.
This commit also fix default value of some ports' properties.

Change-Id: I7767ef2e745ea0b10ff1ec4e09e5a946320f5832

scilab/modules/scicos/sci_gateway/cpp/sci_scicos_new.cpp
scilab/modules/scicos/src/cpp/model/Port.hxx
scilab/modules/scicos/src/cpp/view_scilab/BaseAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/BlockAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/ModelAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/ports_management.hxx

index d89cd3a..21a41aa 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "types.hxx"
 #include "string.hxx"
+#include "mlist.hxx"
 #include "list.hxx"
 #include "function.hxx"
 
@@ -50,9 +51,11 @@ using namespace org_scilab_modules_scicos;
 static const std::string funame = "scicos_new";
 
 template<class Adaptor, class Adaptee>
-Adaptor* alloc_and_set(kind_t k, types::String* type_name, types::typed_list &in)
+types::InternalType * alloc_and_set(kind_t k, types::String* type_name, types::typed_list &in)
 {
     Controller controller = Controller();
+
+    // create the associated object
     ScicosID o = controller.createObject(k);
     Adaptor* adaptor = new Adaptor(static_cast<Adaptee*>(controller.getObject(o)));
 
@@ -71,6 +74,32 @@ Adaptor* alloc_and_set(kind_t k, types::String* type_name, types::typed_list &in
     return adaptor;
 }
 
+template<class Adaptor, class Adaptee>
+types::InternalType * alloc_and_set_as_mlist(kind_t k, types::String* type_name, types::typed_list &in)
+{
+    // check header
+    Adaptor adaptor = Adaptor(0);
+    for (size_t i = 1; i < in.size(); i++)
+    {
+        std::wstring name = type_name->get(i);
+        if (!adaptor.hasProperty(name))
+        {
+            Scierror(999, _("%s: Wrong value for input argument #%d: unable to set \"%ls\".\n"), funame.data(), i, name.data());
+            return 0;
+        }
+    }
+
+    // copy the data
+    types::MList* mlist = new types::MList();
+    mlist->set(0, type_name->clone());
+    for (size_t i = 1; i < in.size(); i++)
+    {
+        mlist->set(i, in[i]);
+    }
+
+    return mlist;
+}
+
 types::Function::ReturnValue sci_scicos_new(types::typed_list &in, int _iRetCount, types::typed_list &out)
 {
     if (in.size() < 1)
@@ -141,7 +170,7 @@ types::Function::ReturnValue sci_scicos_new(types::typed_list &in, int _iRetCoun
             out.push_back(returnType);
             break;
         case view_scilab::Adapters::GRAPHIC_ADAPTER:
-            returnType = alloc_and_set<view_scilab::GraphicsAdapter, model::Block>(BLOCK, type_name, in);
+            returnType = alloc_and_set_as_mlist<view_scilab::GraphicsAdapter, model::Block>(BLOCK, type_name, in);
             if (returnType == 0)
             {
                 return types::Function::Error;
@@ -157,7 +186,7 @@ types::Function::ReturnValue sci_scicos_new(types::typed_list &in, int _iRetCoun
             out.push_back(returnType);
             break;
         case view_scilab::Adapters::MODEL_ADAPTER:
-            returnType = alloc_and_set<view_scilab::ModelAdapter, model::Block>(BLOCK, type_name, in);
+            returnType = alloc_and_set_as_mlist<view_scilab::ModelAdapter, model::Block>(BLOCK, type_name, in);
             if (returnType == 0)
             {
                 return types::Function::Error;
@@ -165,7 +194,7 @@ types::Function::ReturnValue sci_scicos_new(types::typed_list &in, int _iRetCoun
             out.push_back(returnType);
             break;
         case view_scilab::Adapters::PARAMS_ADAPTER:
-            returnType = alloc_and_set<view_scilab::ParamsAdapter, model::Diagram>(DIAGRAM, type_name, in);
+            returnType = alloc_and_set_as_mlist<view_scilab::ParamsAdapter, model::Diagram>(DIAGRAM, type_name, in);
             if (returnType == 0)
             {
                 return types::Function::Error;
index b907a55..48a7b8a 100644 (file)
@@ -60,7 +60,7 @@ private:
     {
         if (dataType == 0)
         {
-            v.resize(3, 0);
+            v.resize(3, 1);
         }
         else
         {
index a8e8a04..e62e0a0 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "user.hxx"
 #include "internal.hxx"
+#include "mlist.hxx"
 #include "string.hxx"
 
 #include "Controller.hxx"
@@ -132,6 +133,87 @@ public:
     }
 
     /**
+     * property as MList accessors
+     */
+
+    types::InternalType* getAsMList(const Controller& controller)
+    {
+        types::MList* mlist = new types::MList();
+
+        typename property<Adaptor>::props_t properties = property<Adaptor>::fields;
+        std::sort(properties.begin(), properties.end(), property<Adaptor>::original_index_cmp);
+
+        // create the header
+        types::String* header = new types::String(1 + properties.size(), 1);
+        header->set(0, Adaptor::getSharedTypeStr().c_str());
+        int index = 1;
+        for (typename property<Adaptor>::props_t_it it = properties.begin(); it != properties.end(); ++it, ++index)
+        {
+            header->set(index, it->name.c_str());
+        }
+
+        // set the mlist field value
+        index = 1;
+        for (typename property<Adaptor>::props_t_it it = properties.begin(); it != properties.end(); ++it, ++index)
+        {
+            mlist->set(index, it->get(*static_cast<Adaptor*>(this), controller));
+        }
+
+        return mlist;
+    }
+
+    bool setAsMList(types::InternalType* v, Controller& controller)
+    {
+        typename property<Adaptor>::props_t properties = property<Adaptor>::fields;
+        std::sort(properties.begin(), properties.end(), property<Adaptor>::original_index_cmp);
+
+        if (v->getType() != types::InternalType::ScilabMList)
+        {
+            return false;
+        }
+        types::MList* current = v->getAs<types::MList>();
+        if (current->getSize() != static_cast<int>(1 + properties.size()))
+        {
+            return false;
+        }
+
+        // check the header
+        types::String* header = current->getFieldNames();
+        if (header->getSize() != static_cast<int>(1 + properties.size()))
+        {
+            return false;
+        }
+        if (header->get(0) != Adaptor::getSharedTypeStr())
+        {
+            return false;
+        }
+        int index = 1;
+        for (typename property<Adaptor>::props_t_it it = properties.begin(); it != properties.end(); ++it, ++index)
+        {
+            if (header->get(index) != it->name)
+            {
+                return false;
+            }
+        }
+
+        // this is a valid mlist, get each mlist field value and pass it to the right property decoder
+        index = 1;
+        for (typename property<Adaptor>::props_t_it it = properties.begin(); it != properties.end(); ++it, ++index)
+        {
+            // DEBUG LOG:
+            // std::wcerr << Adaptor::getSharedTypeStr() << L" set " << it->name << std::endl;
+
+            bool status = it->set(*static_cast<Adaptor*>(this), current->get(index), controller);
+            if (!status)
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
      * @return the Adaptee instance
      */
     Adaptee* getAdaptee() const
index b48a74f..58a7f82 100644 (file)
@@ -40,19 +40,14 @@ struct graphics
 {
     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
     {
-        return new GraphicsAdapter(adaptor.getAdaptee());
+        GraphicsAdapter localAdaptor = GraphicsAdapter(adaptor.getAdaptee());
+        return localAdaptor.getAsMList(controller);
     }
 
     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        if (v->getType() == types::InternalType::ScilabUserType
-                && v->getShortTypeStr() == GraphicsAdapter::getSharedTypeStr())
-        {
-            GraphicsAdapter* graphics = v->getAs<GraphicsAdapter>();
-            adaptor.setAdaptee(graphics->getAdaptee());
-            return true;
-        }
-        return false;
+        GraphicsAdapter localAdaptor = GraphicsAdapter(adaptor.getAdaptee());
+        return localAdaptor.setAsMList(v, controller);
     }
 };
 
@@ -60,19 +55,14 @@ struct model
 {
     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
     {
-        return new ModelAdapter(adaptor.getAdaptee());
+        ModelAdapter localAdaptor = ModelAdapter(adaptor.getAdaptee());
+        return localAdaptor.getAsMList(controller);
     }
 
     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        if (v->getType() == types::InternalType::ScilabUserType
-                && v->getShortTypeStr() == ModelAdapter::getSharedTypeStr())
-        {
-            ModelAdapter* model = v->getAs<ModelAdapter>();
-            adaptor.setAdaptee(model->getAdaptee());
-            return true;
-        }
-        return false;
+        ModelAdapter localAdaptor = ModelAdapter(adaptor.getAdaptee());
+        return localAdaptor.setAsMList(v, controller);
     }
 };
 
index 39448dc..0a12e2d 100644 (file)
@@ -40,7 +40,7 @@ struct sim
     {
         model::Block* adaptee = adaptor.getAdaptee();
 
-        // First, extact the function Name
+        // First, extract the function Name
         std::string name;
         controller.getObjectProperty(adaptee->id(), adaptee->kind(), SIM_FUNCTION_NAME, name);
         types::String* Name = new types::String(1, 1);
index 039e0cf..06d1525 100644 (file)
@@ -131,7 +131,7 @@ types::InternalType* get_ports_property(const Adaptor& adaptor, object_propertie
 /*
  * Set a Scilab encoded values as a property.
  *
- * \note this method will return false if one of the ports does not exist
+ * \note this method will ignore or return false if one of the ports does not exist, depending on the property setted.
  */
 template<typename Adaptor, object_properties_t p>
 bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, Controller& controller, types::InternalType* v)
@@ -145,13 +145,7 @@ bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, C
     if (v->getType() == types::InternalType::ScilabString)
     {
         types::String* current = v->getAs<types::String>();
-        if (current->getCols() != 0 && current->getCols() != 1)
-        {
-            return false;
-        }
-
-        size_t rows = current->getRows();
-        if (rows != ids.size())
+        if (current->getSize() != ids.size())
         {
             return false;
         }
@@ -201,16 +195,6 @@ bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, C
     else if (v->getType() == types::InternalType::ScilabDouble)
     {
         types::Double* current = v->getAs<types::Double>();
-        if (current->getCols() != 0 && current->getCols() != 1)
-        {
-            return false;
-        }
-
-        size_t rows = current->getRows();
-        if (rows != ids.size())
-        {
-            return false;
-        }
 
         // Translate identifiers: shared variables
         int i = 0;
@@ -219,6 +203,16 @@ bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, C
         switch (p)
         {
             case FIRING:
+                if (current->isEmpty())
+                {
+                    return true;
+                }
+
+                if (current->getSize() != ids.size())
+                {
+                    return false;
+                }
+
                 for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
                 {
                     double firing = current->get(i);
@@ -241,6 +235,12 @@ bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, C
             {
                 datatypeIndex++;
 
+                // ignore the set without error
+                if (current->getSize() != ids.size())
+                {
+                    return true;
+                }
+
                 for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
                 {
                     std::vector<int> v;
@@ -328,8 +328,10 @@ void updateNewPort(ScicosID oldPort, int newPort, Controller& controller,
         {
             case DATATYPE_TYPE:
                 datatypeIndex++;
+                // no break
             case DATATYPE_COLS:
                 datatypeIndex++;
+                // no break
             case DATATYPE_ROWS:
             {
                 datatypeIndex++;
@@ -366,8 +368,10 @@ bool addNewPort(ScicosID newPortID, int newPort, const std::vector<ScicosID>& ch
         {
             case DATATYPE_TYPE:
                 datatypeIndex++;
+                // no break
             case DATATYPE_COLS:
                 datatypeIndex++;
+                // no break
             case DATATYPE_ROWS:
             {
                 datatypeIndex++;