Xcos MVC: handle graphics and model port creation 68/14968/2
Clément DAVID [Fri, 1 Aug 2014 09:10:29 +0000 (11:10 +0200)]
Port can be created on : model.in and graphics.pin setters. This commit
share all logic on port_management.hxx and allow future use. A
templatized implementation has been used to reduce the size of the code.

Change-Id: I6197a8ece013184d489128eb0bacf6db4edaf2bf

17 files changed:
scilab/modules/ast/includes/exps/location.hxx
scilab/modules/scicos/Makefile.in
scilab/modules/scicos/includes/utilities.hxx
scilab/modules/scicos/sci_gateway/cpp/sci_scicos_new.cpp
scilab/modules/scicos/src/cpp/LoggerView.cpp
scilab/modules/scicos/src/cpp/Model.cpp
scilab/modules/scicos/src/cpp/Model.hxx
scilab/modules/scicos/src/cpp/Model_getObjectProperties.cpp
scilab/modules/scicos/src/cpp/Model_setObjectProperties.cpp
scilab/modules/scicos/src/cpp/model/BaseObject.hxx
scilab/modules/scicos/src/cpp/model/Block.hxx
scilab/modules/scicos/src/cpp/model/Port.hxx
scilab/modules/scicos/src/cpp/view_scilab/BaseAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/GraphicsAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/ModelAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/TextAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/ports_management.hxx

index 52036d4..1b00cad 100644 (file)
@@ -36,11 +36,11 @@ public:
     }
     /** \} */
 
-    Location(int _first_line, int _last_line, int _first_column, int _last_column) : first_line(_first_line), last_line(_last_line), first_column(_first_column), last_column(_last_column)
+    Location(int _first_line, int _last_line, int _first_column, int _last_column) : first_line(_first_line), first_column(_first_column), last_line(_last_line), last_column(_last_column)
     {
     }
 
-    Location(const Location & l) : first_line(l.first_line), last_line(l.last_line), first_column(l.first_column), last_column(l.last_column)
+    Location(const Location & l) : first_line(l.first_line), first_column(l.first_column), last_line(l.last_line), last_column(l.last_column)
     {
     }
 
index 02db0b5..faa2faa 100644 (file)
@@ -216,7 +216,6 @@ am__libsciscicos_algo_la_SOURCES_DIST = src/c/noscicos/noscicos.c \
        src/cpp/view_scilab/ScsAdapter.cpp \
        src/cpp/view_scilab/StateAdapter.cpp \
        src/cpp/view_scilab/TextAdapter.cpp \
-       src/cpp/view_scilab/ports_management.cpp \
        src/c/scilab5_needed_stubs.c src/c/tree.c \
        src/c/scicos_malloc.c src/c/scicos_print.c src/c/import.c \
        src/c/scicos.c src/c/scicos_free.c src/c/sciblk2.c \
@@ -247,8 +246,7 @@ am__objects_2 = src/cpp/libsciscicos_algo_la-Controller.lo \
        src/cpp/view_scilab/libsciscicos_algo_la-ParamsAdapter.lo \
        src/cpp/view_scilab/libsciscicos_algo_la-ScsAdapter.lo \
        src/cpp/view_scilab/libsciscicos_algo_la-StateAdapter.lo \
-       src/cpp/view_scilab/libsciscicos_algo_la-TextAdapter.lo \
-       src/cpp/view_scilab/libsciscicos_algo_la-ports_management.lo
+       src/cpp/view_scilab/libsciscicos_algo_la-TextAdapter.lo
 am__objects_3 = src/c/libsciscicos_algo_la-scilab5_needed_stubs.lo \
        src/c/libsciscicos_algo_la-tree.lo \
        src/c/libsciscicos_algo_la-scicos_malloc.lo \
@@ -889,8 +887,7 @@ src/cpp/view_scilab/ModelAdapter.cpp \
 src/cpp/view_scilab/ParamsAdapter.cpp \
 src/cpp/view_scilab/ScsAdapter.cpp \
 src/cpp/view_scilab/StateAdapter.cpp \
-src/cpp/view_scilab/TextAdapter.cpp \
-src/cpp/view_scilab/ports_management.cpp
+src/cpp/view_scilab/TextAdapter.cpp
 
 SCICOS_C_SOURCES = \
 src/c/scilab5_needed_stubs.c \
@@ -1442,9 +1439,6 @@ src/cpp/view_scilab/libsciscicos_algo_la-StateAdapter.lo:  \
 src/cpp/view_scilab/libsciscicos_algo_la-TextAdapter.lo:  \
        src/cpp/view_scilab/$(am__dirstamp) \
        src/cpp/view_scilab/$(DEPDIR)/$(am__dirstamp)
-src/cpp/view_scilab/libsciscicos_algo_la-ports_management.lo:  \
-       src/cpp/view_scilab/$(am__dirstamp) \
-       src/cpp/view_scilab/$(DEPDIR)/$(am__dirstamp)
 src/c/$(am__dirstamp):
        @$(MKDIR_P) src/c
        @: > src/c/$(am__dirstamp)
@@ -1950,7 +1944,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/view_scilab/$(DEPDIR)/libsciscicos_algo_la-ScsAdapter.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/view_scilab/$(DEPDIR)/libsciscicos_algo_la-StateAdapter.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/view_scilab/$(DEPDIR)/libsciscicos_algo_la-TextAdapter.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/cpp/view_scilab/$(DEPDIR)/libsciscicos_algo_la-ports_management.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/scicos_sundials/src/cvode/$(DEPDIR)/libscisundials_la-cvode.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/scicos_sundials/src/cvode/$(DEPDIR)/libscisundials_la-cvode_dense.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/scicos_sundials/src/cvode/$(DEPDIR)/libscisundials_la-cvode_direct.Plo@am__quote@
@@ -2635,13 +2628,6 @@ src/cpp/view_scilab/libsciscicos_algo_la-TextAdapter.lo: src/cpp/view_scilab/Tex
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/view_scilab/libsciscicos_algo_la-TextAdapter.lo `test -f 'src/cpp/view_scilab/TextAdapter.cpp' || echo '$(srcdir)/'`src/cpp/view_scilab/TextAdapter.cpp
 
-src/cpp/view_scilab/libsciscicos_algo_la-ports_management.lo: src/cpp/view_scilab/ports_management.cpp
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/cpp/view_scilab/libsciscicos_algo_la-ports_management.lo -MD -MP -MF src/cpp/view_scilab/$(DEPDIR)/libsciscicos_algo_la-ports_management.Tpo -c -o src/cpp/view_scilab/libsciscicos_algo_la-ports_management.lo `test -f 'src/cpp/view_scilab/ports_management.cpp' || echo '$(srcdir)/'`src/cpp/view_scilab/ports_management.cpp
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/view_scilab/$(DEPDIR)/libsciscicos_algo_la-ports_management.Tpo src/cpp/view_scilab/$(DEPDIR)/libsciscicos_algo_la-ports_management.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='src/cpp/view_scilab/ports_management.cpp' object='src/cpp/view_scilab/libsciscicos_algo_la-ports_management.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/view_scilab/libsciscicos_algo_la-ports_management.lo `test -f 'src/cpp/view_scilab/ports_management.cpp' || echo '$(srcdir)/'`src/cpp/view_scilab/ports_management.cpp
-
 sci_gateway/cpp/libsciscicos_cli_la-sci_scicos_new.lo: sci_gateway/cpp/sci_scicos_new.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_cli_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sci_gateway/cpp/libsciscicos_cli_la-sci_scicos_new.lo -MD -MP -MF sci_gateway/cpp/$(DEPDIR)/libsciscicos_cli_la-sci_scicos_new.Tpo -c -o sci_gateway/cpp/libsciscicos_cli_la-sci_scicos_new.lo `test -f 'sci_gateway/cpp/sci_scicos_new.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_scicos_new.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) sci_gateway/cpp/$(DEPDIR)/libsciscicos_cli_la-sci_scicos_new.Tpo sci_gateway/cpp/$(DEPDIR)/libsciscicos_cli_la-sci_scicos_new.Plo
index c0530ed..963349d 100644 (file)
  * The '0' value is used indicate that BaseObject is not handled by the controller.
  */
 typedef long long ScicosID;
-//struct ScicosID
-//{
-//    ScicosID(const ScicosID& u) : v(u.v) {}
-//    typedef unsigned long long uid_container_type;
-//    ScicosID(uid_container_type u) : v(u) {}
-//
-//    inline bool operator<(const ScicosID& u) const
-//    {
-//        return v < u.v;
-//    }
-//    inline bool operator==(const ScicosID& u) const
-//    {
-//        return v == u.v;
-//    }
-//    inline void operator++(int added)
-//    {
-//        v = v + added;
-//    }
-//    friend std::ostream& operator<< (std::ostream &out, const ScicosID& u);
-//private:
-//    uid_container_type v;
-//};
 
 /**
  * Return status of get and set
@@ -98,13 +76,13 @@ enum object_properties_t
     SOURCE_PORT,        //!< model::Link::sourcePort value
     CONTROL_POINTS,     //!< model::Link::controlPoints value
     DATATYPE,           //!< model::Port::dataType value
+    DATATYPE_ROWS,      //!< model::Port::dataType adapter helper
+    DATATYPE_COLS,      //!< model::Port::dataType adapter helper
+    DATATYPE_TYPE,      //!< model::Port::dataType adapter helper
     SOURCE_BLOCK,       //!< model::Port::sourceBlock value
     PORT_KIND,          //!< model::Port::kind value
     IMPLICIT,           //!< model::Port::implicit value
     PORT_NUMBER,        //!< model::Port::portNumber value
-    DATATYPE_ROWS,      //!< model::Port::in value
-    DATATYPE_COLS,      //!< model::Port::in2 value
-    DATATYPE_TYPE,      //!< model::Port::intyp value
     CONNECTED_SIGNALS,  //!< model::Port::connectedSignals value
 };
 
index 634d7a9..0103b5f 100644 (file)
@@ -99,7 +99,7 @@ types::Function::ReturnValue sci_scicos_new(types::typed_list &in, int _iRetCoun
         return types::Function::Error;
     }
 
-    if (type_name->getCols() != in.size())
+    if (type_name->getCols() != (int) in.size())
     {
         Scierror(999, _("%s: Wrong number of input argument: %d expected.\n"), funame.data(), type_name->getCols());
         return types::Function::Error;
index 8a626f6..87024c5 100644 (file)
@@ -32,7 +32,7 @@ LoggerView::~LoggerView()
 // generated with :
 // awk ' $2 == "//!<" {sub(",","", $1); print "case " $1 ":\n    os << \"" $1 "\";\n    break;" }' ~/work/branches/YaSp/scilab/modules/scicos/includes/utilities.hxx
 
-static std::ostream& operator<<(std::ostream& os, update_status_t u)
+std::ostream& operator<<(std::ostream& os, update_status_t u)
 {
     switch (u)
     {
@@ -49,7 +49,7 @@ static std::ostream& operator<<(std::ostream& os, update_status_t u)
     return os;
 }
 
-static std::ostream& operator<<(std::ostream& os, kind_t k)
+std::ostream& operator<<(std::ostream& os, kind_t k)
 {
     switch (k)
     {
@@ -73,7 +73,7 @@ static std::ostream& operator<<(std::ostream& os, kind_t k)
 }
 
 
-static std::ostream& operator<<(std::ostream& os, object_properties_t p)
+std::ostream& operator<<(std::ostream& os, object_properties_t p)
 {
     switch (p)
     {
index 78eab82..a022ccb 100644 (file)
@@ -10,6 +10,8 @@
  *
  */
 
+#include <algorithm>
+
 #include "Model.hxx"
 #include "utilities.hxx"
 
@@ -24,7 +26,7 @@ namespace org_scilab_modules_scicos
 {
 
 Model::Model() :
-    lastId(0)
+    lastId(0), allObjects(), datatypes()
 {
 }
 
@@ -141,4 +143,32 @@ update_status_t Model::setObject(model::BaseObject* o)
     return SUCCESS;
 }
 
+model::Datatype* Model::flyweight(const model::Datatype& d)
+{
+    datatypes_set_t::iterator iter = std::lower_bound(datatypes.begin(), datatypes.end(), &d);
+    if (iter != datatypes.end() && !(d < **iter)) // if d is found
+    {
+        (*iter)->refCount++;
+        return *iter;
+    }
+    else
+    {
+        return *datatypes.insert(iter, new model::Datatype(d));
+    }
+}
+
+void Model::erase(model::Datatype* d)
+{
+    datatypes_set_t::iterator iter = std::lower_bound(datatypes.begin(), datatypes.end(), d);
+    if (iter != datatypes.end() && !(*d < **iter)) // if d is found
+    {
+        (*iter)->refCount--;
+        if ((*iter)->refCount < 0)
+        {
+            datatypes.erase(iter);
+            delete *iter;
+        }
+    }
+}
+
 } /* namespace org_scilab_modules_scicos */
index 2d2ccb5..7d2e457 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef MODEL_HXX_
 #define MODEL_HXX_
 
+#include <vector>
 #include <map>
 #include <string>
 
@@ -28,12 +29,13 @@ public:
     Model();
     ~Model();
 
+    /*
+     * Controller wrapped methods
+     */
+
     ScicosID createObject(kind_t k);
     void deleteObject(ScicosID uid);
 
-    model::BaseObject* getObject(ScicosID uid) const;
-    update_status_t setObject(model::BaseObject* o);
-
     bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, double& v);
     bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, int& v);
     bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, bool& v);
@@ -54,10 +56,23 @@ public:
     update_status_t setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, const std::vector< std::string >& v);
     update_status_t setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, const std::vector<ScicosID>& v);
 
+    /*
+     * Model internal methods
+     */
+
+    model::BaseObject* getObject(ScicosID uid) const;
+    update_status_t setObject(model::BaseObject* o);
+
+    model::Datatype* flyweight(const model::Datatype& d);
+    void erase(model::Datatype* d);
+
 private:
     ScicosID lastId;
     typedef std::map<ScicosID, model::BaseObject*> objects_map_t;
     objects_map_t allObjects;
+
+    typedef std::vector<model::Datatype*> datatypes_set_t;
+    datatypes_set_t datatypes;
 };
 
 } /* namespace org_scilab_modules_scicos */
index d86ce29..307c203 100644 (file)
@@ -414,6 +414,9 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std
         model::Port* o = static_cast<model::Port*>(getObject(uid));
         switch (p)
         {
+            case DATATYPE:
+                o->getDataType(v);
+                return true;
             default:
                 break;
         }
index de6f5de..73dcbe2 100644 (file)
@@ -397,6 +397,8 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
         model::Port* o = static_cast<model::Port*>(getObject(uid));
         switch (p)
         {
+            case DATATYPE:
+                return o->setDataType(this, v);
             default:
                 break;
         }
index 68a98bc..59cbe01 100644 (file)
@@ -109,11 +109,14 @@ struct Geometry
 struct Datatype
 {
 public:
-    Datatype(unsigned int datatype, unsigned int r, unsigned c) :
-        datatype_id(datatype), rows(r), columns(c)
+    Datatype(const std::vector<int>& v) :
+        refCount(0), datatype_id(v[0]), rows(v[1]), columns(v[2])
     {
     }
 
+    // reference counter for the flyweight pattern
+    size_t refCount;
+
     const int datatype_id;
     const int rows;
     const int columns;
@@ -122,6 +125,11 @@ public:
     {
         return datatype_id == d.datatype_id && rows == d.rows && columns == d.columns;
     }
+
+    bool operator<(const Datatype& d) const
+    {
+        return datatype_id < d.datatype_id && rows < d.rows && columns < d.columns;
+    }
 };
 
 /** @}*/
index a1dce6d..04689a2 100644 (file)
@@ -13,7 +13,6 @@
 #ifndef BLOCK_HXX_
 #define BLOCK_HXX_
 
-#include <cassert>
 #include <string>
 #include <vector>
 #include <bitset>
index e6cf3f5..764d7dc 100644 (file)
@@ -44,19 +44,47 @@ private:
         return connectedSignals;
     }
 
-    void setConnectedSignals(const std::vector<ScicosID>& connectedSignals)
+    update_status_t setConnectedSignals(const std::vector<ScicosID>& connectedSignals)
     {
+        if (this->connectedSignals == connectedSignals)
+        {
+            return NO_CHANGES;
+        }
+
         this->connectedSignals = connectedSignals;
+        return SUCCESS;
     }
 
-    Datatype* getDataType() const
+    void getDataType(std::vector<int> v) const
     {
-        return dataType;
+        if (dataType == 0)
+        {
+            v.resize(3, 0);
+        }
+        else
+        {
+            v.resize(3);
+            v[0] = dataType->rows;
+            v[1] = dataType->columns;
+            v[3] = dataType->datatype_id;
+        }
     }
 
-    void setDataType(Datatype* dataType)
+    update_status_t setDataType(Model* model, const std::vector<int>& v)
     {
-        this->dataType = dataType;
+        if (v.size() != 3)
+        {
+            return FAIL;
+        }
+
+        model::Datatype datatype = model::Datatype(v);
+        if (this->dataType != 0 && *this->dataType == datatype)
+        {
+            return NO_CHANGES;
+        }
+
+        this->dataType = model->flyweight(datatype);
+        return SUCCESS;
     }
 
     portKind getKind() const
index 4a7b73c..2e29957 100644 (file)
@@ -18,7 +18,6 @@
 #include <utility>
 #include <iostream>
 
-#include "types.hxx"
 #include "user.hxx"
 
 #include "Controller.hxx"
index 26aac3c..b2dd1f2 100644 (file)
@@ -31,9 +31,6 @@ namespace org_scilab_modules_scicos
 namespace view_scilab
 {
 
-static const wchar_t E[] = L"E";
-static const wchar_t I[] = L"I";
-
 struct orig
 {
 
@@ -263,12 +260,12 @@ struct pin
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property(adaptor, INPUTS, controller, CONNECTED_SIGNALS);
+        return get_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, INPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return update_ports_with_property(adaptor, INPUTS, controller, CONNECTED_SIGNALS, v);
+        return update_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, INPUTS, controller, v);
     }
 };
 
@@ -277,12 +274,12 @@ struct pout
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property(adaptor, OUTPUTS, controller, CONNECTED_SIGNALS);
+        return get_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, OUTPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return update_ports_with_property(adaptor, OUTPUTS, controller, CONNECTED_SIGNALS, v);
+        return update_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, OUTPUTS, controller, v);
     }
 };
 
@@ -291,12 +288,12 @@ struct pein
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property(adaptor, EVENT_INPUTS, controller, CONNECTED_SIGNALS);
+        return get_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, EVENT_INPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return update_ports_with_property(adaptor, EVENT_INPUTS, controller, CONNECTED_SIGNALS, v);
+        return update_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, EVENT_INPUTS, controller, v);
     }
 };
 
@@ -305,12 +302,12 @@ struct peout
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property(adaptor, EVENT_OUTPUTS, controller, CONNECTED_SIGNALS);
+        return get_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, EVENT_OUTPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return update_ports_with_property(adaptor, EVENT_OUTPUTS, controller, CONNECTED_SIGNALS, v);
+        return update_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, EVENT_OUTPUTS, controller, v);
     }
 };
 
@@ -374,12 +371,12 @@ struct in_implicit
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property(adaptor, INPUTS, controller, IMPLICIT);
+        return get_ports_property<GraphicsAdapter, IMPLICIT>(adaptor, INPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return set_ports_property(adaptor, INPUTS, controller, IMPLICIT, v);
+        return set_ports_property<GraphicsAdapter, IMPLICIT>(adaptor, INPUTS, controller, v);
     }
 };
 
@@ -388,12 +385,12 @@ struct out_implicit
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property(adaptor, OUTPUTS, controller, IMPLICIT);
+        return get_ports_property<GraphicsAdapter, IMPLICIT>(adaptor, OUTPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return set_ports_property(adaptor, OUTPUTS, controller, IMPLICIT, v);
+        return set_ports_property<GraphicsAdapter, IMPLICIT>(adaptor, OUTPUTS, controller, v);
     }
 };
 
@@ -402,12 +399,12 @@ struct in_style
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property(adaptor, INPUTS, controller, STYLE);
+        return get_ports_property<GraphicsAdapter, STYLE>(adaptor, INPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return set_ports_property(adaptor, INPUTS, controller, STYLE, v);
+        return set_ports_property<GraphicsAdapter, STYLE>(adaptor, INPUTS, controller, v);
     }
 };
 
@@ -416,12 +413,12 @@ struct out_style
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property(adaptor, OUTPUTS, controller, STYLE);
+        return get_ports_property<GraphicsAdapter, STYLE>(adaptor, OUTPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return set_ports_property(adaptor, OUTPUTS, controller, STYLE, v);
+        return set_ports_property<GraphicsAdapter, STYLE>(adaptor, OUTPUTS, controller, v);
     }
 };
 
@@ -430,12 +427,12 @@ struct in_label
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property(adaptor, INPUTS, controller, LABEL);
+        return get_ports_property<GraphicsAdapter, LABEL>(adaptor, INPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return set_ports_property(adaptor, INPUTS, controller, LABEL, v);
+        return set_ports_property<GraphicsAdapter, LABEL>(adaptor, INPUTS, controller, v);
     }
 };
 
@@ -444,12 +441,12 @@ struct out_label
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property(adaptor, OUTPUTS, controller, LABEL);
+        return get_ports_property<GraphicsAdapter, LABEL>(adaptor, OUTPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return set_ports_property(adaptor, OUTPUTS, controller, LABEL, v);
+        return set_ports_property<GraphicsAdapter, LABEL>(adaptor, OUTPUTS, controller, v);
     }
 };
 
index f2dc0e9..da0c599 100644 (file)
@@ -121,6 +121,120 @@ struct sim
     }
 };
 
+
+struct in
+{
+
+    static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
+    {
+        return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, INPUTS, controller);
+    }
+
+    static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
+    {
+        return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, INPUTS, controller, v);
+    }
+};
+
+struct in2
+{
+
+    static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
+    {
+        return get_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, INPUTS, controller);
+    }
+
+    static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
+    {
+        return set_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, INPUTS, controller, v);
+    }
+};
+
+struct intyp
+{
+
+    static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
+    {
+        return get_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, INPUTS, controller);
+    }
+
+    static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
+    {
+        return set_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, INPUTS, controller, v);
+    }
+};
+
+
+struct out
+{
+
+    static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
+    {
+        return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, OUTPUTS, controller);
+    }
+
+    static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
+    {
+        return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, OUTPUTS, controller, v);
+    }
+};
+
+struct out2
+{
+
+    static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
+    {
+        return get_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, OUTPUTS, controller);
+    }
+
+    static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
+    {
+        return set_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, OUTPUTS, controller, v);
+    }
+};
+
+struct outtyp
+{
+
+    static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
+    {
+        return get_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, OUTPUTS, controller);
+    }
+
+    static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
+    {
+        return set_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, OUTPUTS, controller, v);
+    }
+};
+
+struct evtin
+{
+
+    static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
+    {
+        return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_INPUTS, controller);
+    }
+
+    static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
+    {
+        return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_INPUTS, controller, v);
+    }
+};
+
+struct evtout
+{
+
+    static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
+    {
+        return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_OUTPUTS, controller);
+    }
+
+    static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
+    {
+        return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_OUTPUTS, controller, v);
+    }
+};
+
 template<> property<ModelAdapter>::props_t property<ModelAdapter>::fields = property<ModelAdapter>::props_t();
 
 ModelAdapter::ModelAdapter(const ModelAdapter& o) :
@@ -131,8 +245,16 @@ ModelAdapter::ModelAdapter(org_scilab_modules_scicos::model::Block* o) :
 {
     if (property<ModelAdapter>::properties_has_not_been_set())
     {
-        property<ModelAdapter>::fields.reserve(1);
+        property<ModelAdapter>::fields.reserve(7);
         property<ModelAdapter>::add_property(L"sim", &sim::get, &sim::set);
+        property<ModelAdapter>::add_property(L"in", &in::get, &in::set);
+        property<ModelAdapter>::add_property(L"in2", &in2::get, &in2::set);
+        property<ModelAdapter>::add_property(L"intyp", &intyp::get, &intyp::set);
+        property<ModelAdapter>::add_property(L"out", &out::get, &out::set);
+        property<ModelAdapter>::add_property(L"out2", &out2::get, &out2::set);
+        property<ModelAdapter>::add_property(L"outtyp", &outtyp::get, &outtyp::set);
+        property<ModelAdapter>::add_property(L"evtin", &evtin::get, &evtin::set);
+        property<ModelAdapter>::add_property(L"evtout", &evtout::get, &evtout::set);
     }
 }
 
index 8b35afb..44a4079 100644 (file)
@@ -13,9 +13,6 @@
 #include <string>
 
 #include "internal.hxx"
-#include "list.hxx"
-#include "types.hxx"
-#include "user.hxx"
 
 #include "Controller.hxx"
 #include "TextAdapter.hxx"
index 23f9ffe..dbe9e90 100644 (file)
@@ -32,50 +32,21 @@ namespace view_scilab
 /*
  * Return a Scilab encoded value for a property.
  */
-template<typename Adaptor>
-types::InternalType* get_ports_property(const Adaptor& adaptor, object_properties_t port_kind, const Controller& controller, object_properties_t p)
+template<typename Adaptor, object_properties_t p>
+types::InternalType* get_ports_property(const Adaptor& adaptor, object_properties_t port_kind, const Controller& controller)
 {
-    static const wchar_t E[] = L"E";
-    static const wchar_t I[] = L"I";
     model::Block* adaptee = adaptor.getAdaptee();
 
     // Retrieve the identifiers
     std::vector<ScicosID> ids;
     controller.getObjectProperty(adaptee->id(), adaptee->kind(), port_kind, ids);
 
-    // Translate identifiers to return values
+    // Translate identifiers: shared variables
     int i = 0;
+    size_t datatypeIndex = 0;
+    // Translate identifiers to return values
     switch (p)
     {
-        case CONNECTED_SIGNALS:
-        {
-            double* v;
-            types::Double* o = new types::Double(ids.size(), 1, &v);
-
-            ScicosID diagram;
-            controller.getObjectProperty(adaptee->id(), adaptee->kind(), PARENT_DIAGRAM, diagram);
-
-            std::vector<ScicosID> children;
-            controller.getObjectProperty(diagram, DIAGRAM, CHILDREN, children);
-
-            for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
-            {
-                ScicosID id;
-                controller.getObjectProperty(*it, PORT, p, id);
-
-                std::vector<ScicosID>::iterator found = std::find(children.begin(), children.end(), id);
-
-                if (found != children.end())
-                {
-                    v[i] = std::distance(found, children.begin());
-                }
-                else
-                {
-                    v[i] = 0;
-                }
-            }
-            return o;
-        }
         case STYLE:
         case LABEL:
         {
@@ -88,8 +59,29 @@ types::InternalType* get_ports_property(const Adaptor& adaptor, object_propertie
             }
             return o;
         }
+        case DATATYPE_ROWS:
+            datatypeIndex = 0;
+        // no break
+        case DATATYPE_COLS:
+            datatypeIndex = 1;
+        // no break
+        case DATATYPE_TYPE:
+        {
+            datatypeIndex = 2;
+
+            types::Double* o = new types::Double(ids.size(), 1);
+            for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
+            {
+                std::vector<int> v;
+                controller.getObjectProperty(*it, PORT, DATATYPE, v);
+                o[i] = v[datatypeIndex];
+            }
+            return o;
+        }
         case IMPLICIT:
         {
+            static const wchar_t E[] = L"E";
+            static const wchar_t I[] = L"I";
             types::String* o = new types::String(ids.size(), 1);
             for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
             {
@@ -99,16 +91,32 @@ types::InternalType* get_ports_property(const Adaptor& adaptor, object_propertie
             }
             return o;
         }
-        case DATATYPE_ROWS:
-        case DATATYPE_COLS:
-        case DATATYPE_TYPE:
+        case CONNECTED_SIGNALS:
         {
-            types::Double* o = new types::Double(ids.size(), 1);
+            double* v;
+            types::Double* o = new types::Double(ids.size(), 1, &v);
+
+            ScicosID diagram;
+            controller.getObjectProperty(adaptee->id(), adaptee->kind(), PARENT_DIAGRAM, diagram);
+
+            std::vector<ScicosID> children;
+            controller.getObjectProperty(diagram, DIAGRAM, CHILDREN, children);
+
             for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
             {
-                double v;
-                controller.getObjectProperty(*it, PORT, p, v);
-                o[i] = v;
+                ScicosID id;
+                controller.getObjectProperty(*it, PORT, p, id);
+
+                std::vector<ScicosID>::iterator found = std::find(children.begin(), children.end(), id);
+
+                if (found != children.end())
+                {
+                    v[i] = std::distance(found, children.begin());
+                }
+                else
+                {
+                    v[i] = 0;
+                }
             }
             return o;
         }
@@ -122,11 +130,9 @@ types::InternalType* get_ports_property(const Adaptor& adaptor, object_propertie
  *
  * \note this method will return false if one of the ports does not exist
  */
-template<typename Adaptor>
-bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, Controller& controller, object_properties_t p, types::InternalType* v)
+template<typename Adaptor, object_properties_t p>
+bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, Controller& controller, types::InternalType* v)
 {
-    static const wchar_t E[] = L"E";
-    static const wchar_t I[] = L"I";
     model::Block* adaptee = adaptor.getAdaptee();
 
     // Retrieve the ports identifiers
@@ -147,11 +153,27 @@ bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, C
             return false;
         }
 
+        // Translate identifiers: shared variables
         int i = 0;
+        // Translate identifiers from values
         switch (p)
         {
+            case STYLE:
+            case LABEL:
+            {
+                for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
+                {
+                    char* c_str = wide_string_to_UTF8(current->get(i));
+                    controller.setObjectProperty(*it, PORT, p, std::string(c_str));
+                    FREE(c_str);
+                }
+                return true;
+            }
             case IMPLICIT:
             {
+                static const wchar_t E[] = L"E";
+                static const wchar_t I[] = L"I";
+
                 for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
                 {
                     if (current->get(i) == I)
@@ -169,38 +191,151 @@ bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, C
                 }
                 return true;
             }
+            default:
+                return false;
+        }
+    }
+    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;
+        size_t datatypeIndex = 0;
+        // Translate identifiers from values
+        switch (p)
+        {
             case STYLE:
             case LABEL:
+                // Do nothing, because if the sizes match, then there are already zero concerned ports, so no ports to update
+                return true;
+
+            case DATATYPE_ROWS:
+                datatypeIndex = 0;
+            // no break
+            case DATATYPE_COLS:
+                datatypeIndex = 1;
+            // no break
+            case DATATYPE_TYPE:
             {
-                std::vector<std::string> style = std::vector<std::string>(current->getSize());
+                datatypeIndex = 2;
+
                 for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
                 {
-                    char* c_str = wide_string_to_UTF8(current->get(i));
-                    style[i] = std::string(c_str);
-                    FREE(c_str);
-                    controller.setObjectProperty(*it, PORT, p, style[i]);
+                    std::vector<int> v;
+                    controller.getObjectProperty(*it, PORT, DATATYPE, v);
+
+                    double data = current->get(i);
+                    if (std::floor(data) != data)
+                    {
+                        return false;
+                    }
+
+                    v[datatypeIndex] = static_cast<int>(data);
+                    controller.setObjectProperty(*it, PORT, DATATYPE, v);
                 }
                 return true;
             }
-            default:
-                return false;
+
+            case IMPLICIT:
+                // Do nothing, because if the sizes match, then there are already zero concerned ports, so no ports to update
+                return true;
         }
+
     }
-    else if (v->getType() == types::InternalType::ScilabDouble)
+    return false;
+}
+
+template<typename Adaptor, object_properties_t p>
+bool fillNewPorts(std::vector<int>& newPorts, const std::vector<ScicosID>& children, double* d)
+{
+    for (std::vector<int>::iterator it = newPorts.begin(); it != newPorts.end(); ++it, ++d)
     {
-        types::Double* current = v->getAs<types::Double>();
-        if (current->getRows() != 0 || current->getCols() != 0)
+
+        if (p == CONNECTED_SIGNALS)   // the associated link must exist
         {
-            return false;
+            if (0 > *d && *d >= children.size())
+            {
+                return false;
+            }
+        } // no check is performed for other properties as newPorts will contains value not index
+
+        *it = (int) (*d);
+    }
+    return true;
+}
+
+template<typename Adaptor, object_properties_t p>
+void updateNewPort(ScicosID oldPort, int newPort, Controller& controller,
+                   std::vector<ScicosID>& children, std::vector<ScicosID>& deletedObjects)
+{
+    if (p == CONNECTED_SIGNALS)
+    {
+        // update signal and manage deconnection, using newPort as a children index
+        ScicosID oldSignal;
+        controller.getObjectProperty(oldPort, PORT, CONNECTED_SIGNALS, oldSignal);
+        ScicosID newSignal = children[newPort];
+        if (oldSignal != newSignal)
+        {
+            // disconnect the old link
+            ScicosID oldSignalSrc;
+            controller.getObjectProperty(oldSignal, LINK, SOURCE_PORT, oldSignalSrc);
+            ScicosID oldSignalDst;
+            controller.getObjectProperty(oldSignal, LINK, DESTINATION_PORT, oldSignalDst);
+            ScicosID unconnected = 0;
+            if (oldSignalSrc == oldPort)
+            {
+                controller.setObjectProperty(oldSignalDst, PORT, CONNECTED_SIGNALS, unconnected);
+            }
+            else   // oldSignalDst == oldPort
+            {
+                controller.setObjectProperty(oldSignalSrc, PORT, CONNECTED_SIGNALS, unconnected);
+            }
+            // Link de-association is not performed as the link will be removed
+            // connect the new link
+            controller.setObjectProperty(newSignal, LINK, SOURCE_PORT, 0);
+            controller.setObjectProperty(oldPort, PORT, CONNECTED_SIGNALS, newSignal);
+            children.erase(std::find(children.begin(), children.end(), oldSignal));
+            deletedObjects.push_back(oldSignal);
         }
-        if (ids.size() != 0)
+    }
+    else
+    {
+        // update the p property, using newPort as a value
+        controller.setObjectProperty(oldPort, PORT, p, newPort);
+    }
+}
+
+template<typename Adaptor, object_properties_t p>
+bool addNewPort(ScicosID newPortID, int newPort, const std::vector<ScicosID>& children,        Controller& controller)
+{
+    bool status = true;
+    if (p == CONNECTED_SIGNALS)
+    {
+        // set the connected signal if applicable, using newPort as a children index
+        if (newPort != 0)
         {
-            return false;
+            ScicosID signal = children[newPort];
+            status = controller.setObjectProperty(newPortID, PORT, CONNECTED_SIGNALS, signal);
         }
-        // Do nothing, because if the sizes match, then there are already zero concerned ports, so no ports to update
-        return true;
     }
-    return false;
+    else
+    {
+        // set the requested property, using newPort as a value
+        status = controller.setObjectProperty(newPortID, PORT, p, newPort);
+    }
+
+    return status;
 }
 
 /**
@@ -208,8 +343,8 @@ bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, C
  *
  * Create ports if needed, remove ports if needed and set a default property on each port.
  */
-template<typename Adaptor>
-bool update_ports_with_property(const Adaptor& adaptor, object_properties_t port_kind, Controller& controller, object_properties_t p, types::InternalType* v)
+template<typename Adaptor, object_properties_t p>
+bool update_ports_property(const Adaptor& adaptor, object_properties_t port_kind,  Controller& controller, types::InternalType* v)
 {
     model::Block* adaptee = adaptor.getAdaptee();
 
@@ -236,36 +371,11 @@ bool update_ports_with_property(const Adaptor& adaptor, object_properties_t port
     std::vector<ScicosID> previousPorts = oldPorts;
 
     double* d = value->getReal();
-    if (p == CONNECTED_SIGNALS)
-    {
-        for (std::vector<int>::iterator it = newPorts.begin(); it != newPorts.end(); ++it, ++d)
-        {
-            if (0 > *d && *d >= children.size())
-            {
-                return false;
-            }
-
-            *it = (int) * d;
-        }
-    }
-    else
+    if (!fillNewPorts<Adaptor, p>(newPorts, children, d))
     {
-        // Here, we are modyfing either 'in', 'in2' or 'intyp', so the Port ids must remain the same as much as possible (copy the old ones),
-        // and set the new ones to zero (unconnected) if there are any (insert them at the beginning of newPorts).
-        if (newPorts.size() != 0)
-        {
-            //
-            if (newPorts.size() >= oldPorts.size())
-            {
-                std::fill(newPorts.begin(), newPorts.begin() + newPorts.size() - oldPorts.size(), 0);
-                std::copy(oldPorts.begin(), oldPorts.end(), newPorts.begin() + newPorts.size() - oldPorts.size() + 1);
-            }
-            else if (newPorts.size() < oldPorts.size())
-            {
-                std::copy(oldPorts.begin(), oldPorts.begin() + newPorts.size(), newPorts.begin());
-            }
-        }
+        return false;
     }
+
     std::vector<ScicosID> deletedObjects;
 
     // updated ports
@@ -276,44 +386,7 @@ bool update_ports_with_property(const Adaptor& adaptor, object_properties_t port
         int newPort = newPorts.back();
         newPorts.pop_back();
 
-        ScicosID oldSignal;
-        controller.getObjectProperty(oldPort, PORT, CONNECTED_SIGNALS, oldSignal);
-        ScicosID newSignal = children[newPort];
-
-        if (p == CONNECTED_SIGNALS)
-        {
-            if (oldSignal != newSignal)
-            {
-                // disconnect the old link
-                ScicosID oldSignalSrc;
-                controller.getObjectProperty(oldSignal, LINK, SOURCE_PORT, oldSignalSrc);
-                ScicosID oldSignalDst;
-                controller.getObjectProperty(oldSignal, LINK, DESTINATION_PORT, oldSignalDst);
-
-                ScicosID unconnected = 0;
-                if (oldSignalSrc == oldPort)
-                {
-                    controller.setObjectProperty(oldSignalDst, PORT, CONNECTED_SIGNALS, unconnected);
-                }
-                else // oldSignalDst == oldPort
-                {
-                    controller.setObjectProperty(oldSignalSrc, PORT, CONNECTED_SIGNALS, unconnected);
-                }
-                // Link de-association is not performed as the link will be removed
-
-                // connect the new link
-                controller.setObjectProperty(newSignal, LINK, SOURCE_PORT, 0);
-                controller.setObjectProperty(oldPort, PORT, CONNECTED_SIGNALS, newSignal);
-
-                children.erase(std::find(children.begin(), children.end(), oldSignal));
-                deletedObjects.push_back(oldSignal);
-            }
-        }
-        else
-        {
-            // The common port ids (CONNECTED_SIGNALS property) remain the same, so just update the p property
-            controller.setObjectProperty(oldPort, PORT, p, d[newPorts.size() - 1]);
-        }
+        updateNewPort<Adaptor, p>(oldPort, newPort, controller, children, deletedObjects);
     }
 
     // removed ports
@@ -366,18 +439,7 @@ bool update_ports_with_property(const Adaptor& adaptor, object_properties_t port
 
             ScicosID id = controller.createObject(PORT);
             controller.setObjectProperty(id, PORT, SOURCE_BLOCK, adaptee->id());
-            if (p != CONNECTED_SIGNALS)
-            {
-                // In addition to setting the signal to 0 (the 0s at the start of newPorts), set the requested property
-                controller.setObjectProperty(id, PORT, p, d[newPorts.size() - 1]);
-            }
-            // set the connected signal if applicable
-            if (newPort != 0)
-            {
-                ScicosID signal = children[newPort];
-                controller.setObjectProperty(id, PORT, CONNECTED_SIGNALS, signal);
-            }
-
+            addNewPort<Adaptor, p>(id, newPort, children, controller);
             previousPorts.push_back(id);
         }