Scicos: refactor DiagramAdapter / BlockAdapter 38/18638/9
Clément DAVID [Wed, 19 Oct 2016 13:01:49 +0000 (15:01 +0200)]
To reduce memory usage, DiagramAdapter might be either backed by a Diagram
or a Block instead of preserving a types::List copy.

This commit also move the block EXPRS encoding back to the XMIResource file
to avoid mis-copy on clone().

Change-Id: Iaa6e3d7a555466df26afce3f946fd4b7fff2b19d

93 files changed:
scilab/modules/ast/includes/types/internal.hxx
scilab/modules/scicos/includes/Controller.hxx
scilab/modules/scicos/includes/Model.hxx
scilab/modules/scicos/includes/View.hxx
scilab/modules/scicos/includes/XMIResource.hxx
scilab/modules/scicos/includes/adapters_utilities.hxx
scilab/modules/scicos/includes/model/BaseObject.hxx
scilab/modules/scicos/includes/utilities.hxx
scilab/modules/scicos/includes/view_scilab/Adapters.hxx
scilab/modules/scicos/macros/scicos_scicos/do_eval.sci
scilab/modules/scicos/sci_gateway/cpp/sci_scicosDiagramToScilab.cpp
scilab/modules/scicos/sci_gateway/cpp/sci_scicos_new.cpp
scilab/modules/scicos/src/cpp/Controller.cpp
scilab/modules/scicos/src/cpp/LoggerView.cpp
scilab/modules/scicos/src/cpp/LoggerView.hxx
scilab/modules/scicos/src/cpp/Model.cpp
scilab/modules/scicos/src/cpp/Model_getObjectProperties.cpp
scilab/modules/scicos/src/cpp/Model_setObjectProperties.cpp
scilab/modules/scicos/src/cpp/XMIResource_load.cpp
scilab/modules/scicos/src/cpp/XMIResource_save.cpp
scilab/modules/scicos/src/cpp/model/Annotation.hxx
scilab/modules/scicos/src/cpp/model/Block.hxx
scilab/modules/scicos/src/cpp/model/Diagram.hxx
scilab/modules/scicos/src/cpp/model/Link.hxx
scilab/modules/scicos/src/cpp/model/Port.hxx
scilab/modules/scicos/src/cpp/view_scilab/Adapters.cpp
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/BlockAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/CprAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/CprAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/DiagramAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/DiagramAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/GraphicsAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/GraphicsAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/LinkAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/LinkAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/ModelAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/ModelAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/ParamsAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/ParamsAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/ScsAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/ScsAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/StateAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/StateAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/TextAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/TextAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/ports_management.hxx
scilab/modules/scicos/tests/unit_tests/do_eval.dia.ref [new file with mode: 0644]
scilab/modules/scicos/tests/unit_tests/do_eval.tst [new file with mode: 0644]
scilab/modules/scicos/tests/unit_tests/model/Annotation.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Block.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Block_copy_list.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Clone_SuperBlock_in_Diagram.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Clone_SuperBlock_in_Diagram.tst
scilab/modules/scicos/tests/unit_tests/model/Consecutive_init.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Deep_cloning.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Delete_objects.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Diagram.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Diagram_cloning.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Diagram_cloning.tst
scilab/modules/scicos/tests/unit_tests/model/Implicit_link.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Insert_in_SuperBlock.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Link.dia.ref
scilab/modules/scicos/tests/unit_tests/model/SubDiagram_context.dia.ref
scilab/modules/scicos/tests/unit_tests/model/SuperBlock.dia.ref
scilab/modules/scicos/tests/unit_tests/model/SuperBlock_in_SuperBlock.dia.ref
scilab/modules/scicos/tests/unit_tests/model/clone_extract.dia.ref
scilab/modules/scicos/tests/unit_tests/model/from_mlist.dia.ref
scilab/modules/scicos/tests/unit_tests/model/link_preservation.dia.ref
scilab/modules/scicos/tests/unit_tests/model/link_preservation.tst
scilab/modules/scicos/tests/unit_tests/model/prop_wrong.dia.ref
scilab/modules/scicos/tests/unit_tests/model/simple_delete.dia.ref
scilab/modules/xcos/sci_gateway/cpp/sci_xcosDiagramToScilab.cpp
scilab/modules/xcos/src/java/org/scilab/modules/xcos/BrowserView.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/Controller.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/JavaController.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/JavaControllerJNI.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/Kind.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/ObjectProperties.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/PortKind.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/UpdateStatus.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/VectorOfBool.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/VectorOfDouble.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/VectorOfInt.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/VectorOfScicosID.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/VectorOfString.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/View.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/XcosView.java
scilab/modules/xcos/src/jni/JavaController.i
scilab/modules/xcos/src/jni/JavaController_wrap.cxx
scilab/modules/xcos/src/jni/JavaController_wrap.h
scilab/modules/xcos/tests/unit_tests/block_tests/CLOCK_c.tst [new file with mode: 0644]

index ff48792..4f3811e 100644 (file)
@@ -322,7 +322,7 @@ public :
         return m_iRef > _iRef;
     }
 
-    inline int getRef()
+    inline int getRef() const
     {
         return m_iRef;
     }
index 9e4c434..2d9893f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -57,8 +57,15 @@ public:
         referenceObject(o->id());
         return o;
     }
+    template<typename T>
+    T* referenceObject(model::BaseObject* o) const
+    {
+        referenceObject(o->id());
+        return static_cast<T*>(o);
+    }
     void deleteObject(ScicosID uid);
     ScicosID cloneObject(ScicosID uid, bool cloneChildren, bool clonePorts);
+    model::BaseObject* cloneObject(std::map<model::BaseObject*, model::BaseObject*>& mapped, model::BaseObject* initial, bool cloneChildren, bool clonePorts);
 
     kind_t getKind(ScicosID uid) const;
     std::vector<ScicosID> getAll(kind_t k) const;
@@ -70,6 +77,32 @@ public:
         return static_cast<T*>(getObject(uid));
     }
 
+    /*
+     * C++ API
+     */
+
+    template<typename T>
+    bool getObjectProperty(model::BaseObject* object, object_properties_t p, T& v) const
+    {
+        lock(&m_instance.onModelStructuralModification);
+        bool ret = m_instance.model.getObjectProperty(object, p, v);
+        unlock(&m_instance.onModelStructuralModification);
+        return ret;
+    }
+
+    template<typename T>
+    update_status_t setObjectProperty(model::BaseObject* object, object_properties_t p, const T& v)
+    {
+        lock(&m_instance.onModelStructuralModification);
+        update_status_t ret = m_instance.model.setObjectProperty(object, p, v);
+        unlock(&m_instance.onModelStructuralModification);
+        return ret;
+    }
+
+    /*
+     * C / Java API
+     */
+
     bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, double& v) const;
     bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, int& v) const;
     bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, bool& v) const;
@@ -113,6 +146,17 @@ private:
         ~SharedData();
     };
 
+    static inline void lock(std::atomic_flag* m)
+    {
+        while (m->test_and_set(std::memory_order_acquire))  // acquire lock
+            ; // spin
+    }
+
+    static inline void unlock(std::atomic_flag* m)
+    {
+        m->clear(std::memory_order_release);
+    }
+
     /**
      * Shared instance of the data
      *
@@ -124,15 +168,14 @@ private:
      * Methods
      */
 
-    ScicosID cloneObject(std::map<ScicosID, ScicosID>& mapped, ScicosID uid, bool cloneChildren, bool clonePorts);
-    template<typename T> void cloneProperties(model::BaseObject* initial, ScicosID clone);
+    template<typename T> void cloneProperties(model::BaseObject* initial, model::BaseObject* clone);
     template<typename T> bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, T& v) const;
     template<typename T> update_status_t setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, T v);
-    void deepClone(std::map<ScicosID, ScicosID>& mapped, ScicosID uid, ScicosID clone, kind_t k, object_properties_t p, bool cloneIfNotFound);
-    void deepCloneVector(std::map<ScicosID, ScicosID>& mapped, ScicosID uid, ScicosID clone, kind_t k, object_properties_t p, bool cloneIfNotFound);
-    void unlinkVector(ScicosID uid, kind_t k, object_properties_t uid_prop, object_properties_t ref_prop);
-    void unlink(ScicosID uid, kind_t k, object_properties_t uid_prop, object_properties_t ref_prop);
-    void deleteVector(ScicosID uid, kind_t k, object_properties_t uid_prop);
+    void deepClone(std::map<model::BaseObject*, model::BaseObject*>& mapped, model::BaseObject* initial, model::BaseObject* clone, object_properties_t p, bool cloneIfNotFound);
+    void deepCloneVector(std::map<model::BaseObject*, model::BaseObject*>& mapped, model::BaseObject* initial, model::BaseObject* clone, object_properties_t p, bool cloneIfNotFound);
+    void unlinkVector(model::BaseObject* o, object_properties_t uid_prop, object_properties_t ref_prop);
+    void unlink(model::BaseObject* o, object_properties_t uid_prop, object_properties_t ref_prop);
+    void deleteVector(model::BaseObject* o, object_properties_t uid_prop);
 };
 
 } /* namespace org_scilab_modules_scicos */
index bbd6029..24bcee7 100644 (file)
@@ -43,28 +43,39 @@ public:
     unsigned& referenceCount(ScicosID uid);
     void deleteObject(ScicosID uid);
 
-    bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, double& v) const;
-    bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, int& v) const;
-    bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, bool& v) const;
-    bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::string& v) const;
-    bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, ScicosID& v) const;
-    bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::vector<double>& v) const;
-    bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::vector<int>& v) const;
-    bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::vector<bool>& v) const;
-    bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::vector< std::string >& v) const;
-    bool getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::vector<ScicosID>& v) const;
-
-    update_status_t setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, double v);
-    update_status_t setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, int v);
-    update_status_t setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, bool v);
-    update_status_t setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, ScicosID v);
-    update_status_t setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::string v);
-    update_status_t setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, const std::vector<double>& v);
-    update_status_t setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, const std::vector<int>& v);
-    update_status_t setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, const std::vector<bool>& v);
-    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);
+    template<typename T>
+    inline bool getObjectProperty(ScicosID uid, kind_t /*k*/, object_properties_t p, T& v) const
+    {
+        return getObjectProperty(getObject(uid), p, v);
+    }
 
+    template<typename T>
+    inline update_status_t setObjectProperty(ScicosID uid, kind_t /*k*/, object_properties_t p, T v)
+    {
+        return setObjectProperty(getObject(uid), p, v);
+    }
+
+    bool getObjectProperty(model::BaseObject* object, object_properties_t p, double& v) const;
+    bool getObjectProperty(model::BaseObject* object, object_properties_t p, int& v) const;
+    bool getObjectProperty(model::BaseObject* object, object_properties_t p, bool& v) const;
+    bool getObjectProperty(model::BaseObject* object, object_properties_t p, std::string& v) const;
+    bool getObjectProperty(model::BaseObject* object, object_properties_t p, ScicosID& v) const;
+    bool getObjectProperty(model::BaseObject* object, object_properties_t p, std::vector<double>& v) const;
+    bool getObjectProperty(model::BaseObject* object, object_properties_t p, std::vector<int>& v) const;
+    bool getObjectProperty(model::BaseObject* object, object_properties_t p, std::vector<bool>& v) const;
+    bool getObjectProperty(model::BaseObject* object, object_properties_t p, std::vector< std::string >& v) const;
+    bool getObjectProperty(model::BaseObject* object, object_properties_t p, std::vector<ScicosID>& v) const;
+
+    update_status_t setObjectProperty(model::BaseObject* object, object_properties_t p, double v);
+    update_status_t setObjectProperty(model::BaseObject* object, object_properties_t p, int v);
+    update_status_t setObjectProperty(model::BaseObject* object, object_properties_t p, bool v);
+    update_status_t setObjectProperty(model::BaseObject* object, object_properties_t p, ScicosID v);
+    update_status_t setObjectProperty(model::BaseObject* object, object_properties_t p, std::string v);
+    update_status_t setObjectProperty(model::BaseObject* object, object_properties_t p, const std::vector<double>& v);
+    update_status_t setObjectProperty(model::BaseObject* object, object_properties_t p, const std::vector<int>& v);
+    update_status_t setObjectProperty(model::BaseObject* object, object_properties_t p, const std::vector<bool>& v);
+    update_status_t setObjectProperty(model::BaseObject* object, object_properties_t p, const std::vector< std::string >& v);
+    update_status_t setObjectProperty(model::BaseObject* object, object_properties_t p, const std::vector<ScicosID>& v);
     /*
      * Model custom methods
      */
@@ -85,15 +96,7 @@ private:
     ScicosID lastId;
     bool has_looped;
 
-    struct ModelObject
-    {
-        ModelObject(model::BaseObject* o) : m_o(o), m_refCounter(0) {}
-
-        model::BaseObject* m_o;
-        unsigned m_refCounter;
-    };
-
-    typedef std::unordered_map<ScicosID, ModelObject > objects_map_t;
+    typedef std::unordered_map<ScicosID, model::BaseObject* > objects_map_t;
     objects_map_t allObjects;
 
     typedef std::vector<model::Datatype*> datatypes_set_t;
index cec255f..555da2d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -33,6 +33,7 @@ public:
     virtual void objectReferenced(const ScicosID& uid, kind_t kind, unsigned refCount) = 0;
     virtual void objectUnreferenced(const ScicosID& uid, kind_t kind, unsigned refCount) = 0;
     virtual void objectDeleted(const ScicosID& uid, kind_t kind) = 0;
+    virtual void objectCloned(const ScicosID& uid, const ScicosID& cloned, kind_t kind) = 0;
     virtual void propertyUpdated(const ScicosID& uid, kind_t kind, object_properties_t property, update_status_t status) = 0;
 };
 
index 2e53cec..ed86e7f 100644 (file)
@@ -61,6 +61,7 @@ private:
     int loadDoubleArray(xmlTextReaderPtr reader, enum object_properties_t property, const model::BaseObject& o);
     int loadIntArray(xmlTextReaderPtr reader, enum object_properties_t property, const model::BaseObject& o);
     int loadStringArray(xmlTextReaderPtr reader, enum object_properties_t property, const model::BaseObject& o);
+    int loadEncodedStringArray(xmlTextReaderPtr reader, enum object_properties_t property, const model::BaseObject& o);
     int loadBase64(xmlTextReaderPtr reader, enum object_properties_t property, const model::BaseObject& o);
     int loadPoint(xmlTextReaderPtr reader, const model::BaseObject& o);
     int loadGeometry(xmlTextReaderPtr reader, const model::BaseObject& o);
index 3a773eb..b541a40 100644 (file)
@@ -29,4 +29,22 @@ struct link_t
     enum startOrEnd kind;
 };
 
+// partial-link information
+struct partial_link_t
+{
+    link_t from;
+    link_t to;
+};
+
+typedef std::vector<unsigned int> link_indices_t;
+
+// partial-port information
+struct partial_ports_t
+{
+    link_indices_t graphics_pin;
+    link_indices_t graphics_pout;
+    link_indices_t graphics_pein;
+    link_indices_t graphics_peout;
+};
+
 #endif /* ADAPTERS_UTILITIES_HXX_ */
index 54077bf..c1c129d 100644 (file)
@@ -30,20 +30,20 @@ class BaseObject
 {
 public:
     explicit BaseObject(kind_t k) :
-        m_kind(k)
-        // Not initializing m_id on purpose: the ID is given by the model constructor
+        m_id(ScicosID()), m_kind(k), m_refCount()
     {
+        // m_id will be set by the caller
     }
     BaseObject(const BaseObject& b) :
-        m_id(b.m_id), m_kind(b.m_kind)
+        m_id(b.m_id), m_kind(b.m_kind), m_refCount()
     {
     }
     BaseObject(BaseObject&& b) :
-        m_id(b.m_id), m_kind(b.m_kind)
+        m_id(b.m_id), m_kind(b.m_kind), m_refCount()
     {
     }
     BaseObject(ScicosID id, kind_t k) :
-        m_id(id), m_kind(k)
+        m_id(id), m_kind(k), m_refCount()
     {
     }
 
@@ -78,6 +78,11 @@ public:
         return m_kind;
     }
 
+    inline unsigned& refCount()
+    {
+        return m_refCount;
+    }
+
 private:
     /**
      * An id is used as a reference to the current object
@@ -88,6 +93,11 @@ private:
      * Kind of the Object
      */
     kind_t m_kind;
+
+    /**
+     * Refcount of this object
+     */
+    unsigned m_refCount;
 };
 
 /** @defgroup utilities Shared utility classes
index 736ba7e..467721e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -92,8 +92,6 @@ enum object_properties_t
     THICK,              //!< model::Link::thick value
     COLOR,              //!< model::Link & Block & Diagram::color value
     KIND,               //!< model::Link::kind value
-    FROM,               //!< model::Link::from value
-    TO,                 //!< model::Link::to value
     DATATYPE,           //!< model::Port::dataType value
     DATATYPE_ROWS,      //!< model::Port::dataType adapter helper
     DATATYPE_COLS,      //!< model::Port::dataType adapter helper
@@ -125,5 +123,46 @@ enum portKind
     PORT_EOUT
 };
 
+/**
+ * Helper to convert a Property to a Port kind.
+ */
+inline int port_from_property(object_properties_t p)
+{
+    switch (p)
+    {
+        case INPUTS:
+            return PORT_IN;
+        case OUTPUTS:
+            return PORT_OUT;
+        case EVENT_INPUTS:
+            return PORT_EIN;
+        case EVENT_OUTPUTS:
+            return PORT_EOUT;
+        default:
+            return PORT_UNDEF;
+    }
+}
+
+
+/**
+ * Helper to convert a Port kind to a Property.
+ */
+inline object_properties_t property_from_port(int p)
+{
+    switch (p)
+    {
+        case PORT_IN:
+            return INPUTS;
+        case PORT_OUT:
+            return OUTPUTS;
+        case PORT_EIN:
+            return EVENT_INPUTS;
+        case PORT_EOUT:
+            return EVENT_OUTPUTS;
+        default:
+            return MAX_OBJECT_PROPERTIES;
+    }
+}
+
 
 #endif /* UTILITIES_HXX_ */
index d4d04ef..4ea62fa 100644 (file)
@@ -59,7 +59,8 @@ public:
 
     adapters_index_t lookup_by_typename(const std::wstring& name);
     std::wstring get_typename(adapters_index_t index);
-    const model::BaseObject* descriptor(types::InternalType* v);
+    model::BaseObject* descriptor(types::InternalType* v);
+    model::BaseObject* descriptor(adapters_index_t index, types::InternalType* v);
     types::InternalType* allocate_view(ScicosID id, kind_t kind);
 
 private:
index 78fc89e..ae6663d 100644 (file)
@@ -90,6 +90,7 @@ function [scs_m,cpr,needcompile,ok]=do_eval(scs_m,cpr,%scicos_context)
     "    mputl(tt, funam1); "+..
     "end");
     %nx=lstsize(scs_m.objs)
+    %x=scs_m.objs;
     funcprot(%mprt)
     for %kk=1:%nx
         o=scs_m.objs(%kk)
@@ -112,7 +113,7 @@ function [scs_m,cpr,needcompile,ok]=do_eval(scs_m,cpr,%scicos_context)
                     needcompile1=max(needcompile1,needcompile2)
                     full_uids = previous_full_uids;
                     if ok then
-                        scs_m.objs(%kk).model.rpar=sblock
+                        %x(%kk).model.rpar=sblock
                     else
                         return
                     end
@@ -121,7 +122,7 @@ function [scs_m,cpr,needcompile,ok]=do_eval(scs_m,cpr,%scicos_context)
             else
                 model=o.model
                 if ~isdef(o.gui) | ~or(type(evstr(o.gui) == [13 11])) then
-                    if length(o.model.uid) >= 1 then
+                    if length(o.model.uid) >= 1 & getscilabmode() == "STD" then
                         uid = [full_uids o.model.uid];
 
                         html = "<html><body>";
@@ -193,7 +194,7 @@ function [scs_m,cpr,needcompile,ok]=do_eval(scs_m,cpr,%scicos_context)
                         end
                     end
 
-                    scs_m.objs(%kk)=o
+                    %x(%kk)=o
                 else
                     error(msprintf(gettext("%s: Error while calling block %s [uid=''%s'']: invalid parameter (ier=%f, %%scicos_prob=%%%s).\n"), "do_eval", o.gui, o.model.uid, ier, string(%scicos_prob)));
                     ok=%f
@@ -202,6 +203,7 @@ function [scs_m,cpr,needcompile,ok]=do_eval(scs_m,cpr,%scicos_context)
             end
         end
     end
+    scs_m.objs = %x;
     needcompile=needcompile1
     if needcompile==4 then cpr=list(),end
 endfunction
index 8019225..75708f9 100644 (file)
@@ -35,8 +35,8 @@ extern "C"
 using namespace org_scilab_modules_scicos;
 /*--------------------------------------------------------------------------*/
 static char funname[] = "scicosDiagramToScilab";
-types::InternalType* importFile(char const* file);
-bool exportFile(int index, char const* file, types::InternalType* uid);
+static types::InternalType* importFile(char const* file);
+static bool exportFile(int index, char const* file, types::InternalType* uid);
 /*--------------------------------------------------------------------------*/
 types::Function::ReturnValue sci_scicosDiagramToScilab(types::typed_list &in, int _iRetCount, types::typed_list &out)
 {
@@ -121,7 +121,7 @@ types::Function::ReturnValue sci_scicosDiagramToScilab(types::typed_list &in, in
     return types::Function::OK;
 }
 /*--------------------------------------------------------------------------*/
-types::InternalType* importFile(char const* file)
+static types::InternalType* importFile(char const* file)
 {
     // create a diagram
     org_scilab_modules_scicos::Controller controller;
@@ -134,10 +134,11 @@ types::InternalType* importFile(char const* file)
         return nullptr;
     }
 
-    return view_scilab::Adapters::instance().allocate_view(uid, DIAGRAM);
+    types::InternalType* pIT = view_scilab::Adapters::instance().allocate_view(uid, DIAGRAM);
+    return pIT;
 }
 /*--------------------------------------------------------------------------*/
-bool exportFile(int index, char const* file, types::InternalType* type)
+static bool exportFile(int index, char const* file, types::InternalType* type)
 {
     // check that the passed argument is a diagram
     const model::BaseObject* o = view_scilab::Adapters::instance().descriptor(type);
index e852dc4..a572a76 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -61,9 +61,9 @@ types::InternalType * alloc_and_set(kind_t k, types::String* type_name, types::t
 {
     Controller controller;
 
-    // create the associated object
-    ScicosID o = controller.createObject(k);
-    Adaptor* adaptor = new Adaptor(controller, controller.getObject<Adaptee>(o));
+    // create the associated object and own it
+    ScicosID uid = controller.createObject(k);
+    Adaptor* adaptor = new Adaptor(controller, controller.getObject<Adaptee>(uid));
 
     // the first header entry is the type
     for (int i = 1; i < (int)in.size(); i++)
@@ -72,7 +72,7 @@ types::InternalType * alloc_and_set(kind_t k, types::String* type_name, types::t
         if (!adaptor->setProperty(name, in[i], controller))
         {
             Scierror(999, _("%s: Wrong value for input argument #%d: unable to set \"%ls\".\n"), funame.data(), i, name.data());
-            delete adaptor;
+            adaptor->killMe();
             return 0;
         }
     }
@@ -80,38 +80,12 @@ types::InternalType * alloc_and_set(kind_t k, types::String* type_name, types::t
     return adaptor;
 }
 
-template<class Adaptor, class Adaptee>
-types::InternalType * alloc_and_set_as_tlist(types::String* type_name, types::typed_list &in)
+template<class Adaptor, class Adaptee, class T>
+types::InternalType * set_tlist(T* as, types::String* type_name, types::typed_list &in)
 {
-    // check header
-    // The default constructor should be implemented for this Adapter
-    Adaptor adaptor;
-    for (int i = 1; i < (int)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::TList* tlist = new types::TList();
-    tlist->set(0, type_name->clone());
-    for (int i = 1; i < (int)in.size(); i++)
-    {
-        tlist->set(i, in[i]);
-    }
-
-    return tlist;
-}
+    Controller controller;
 
-template<class Adaptor, class Adaptee>
-types::InternalType * alloc_and_set_as_mlist(types::String* type_name, types::typed_list &in)
-{
-    // check header
-    // The default constructor should be implemented for this Adapter
+    // check header by using a null object
     Adaptor adaptor;
     for (int i = 1; i < (int)in.size(); i++)
     {
@@ -124,14 +98,13 @@ types::InternalType * alloc_and_set_as_mlist(types::String* type_name, types::ty
     }
 
     // copy the data
-    types::MList* mlist = new types::MList();
-    mlist->set(0, type_name->clone());
+    as->set(0, type_name->clone());
     for (int i = 1; i < (int)in.size(); i++)
     {
-        mlist->set(i, in[i]);
+        as->set(i, in[i]);
     }
 
-    return mlist;
+    return as;
 }
 
 static types::Function::ReturnValue allocate(types::typed_list &in, int /*_iRetCount*/, types::typed_list &out)
@@ -167,7 +140,7 @@ static types::Function::ReturnValue allocate(types::typed_list &in, int /*_iRetC
             }
             break;
         case view_scilab::Adapters::CPR_ADAPTER:
-            returnType = alloc_and_set_as_tlist<view_scilab::CprAdapter, model::Diagram>(type_name, in);
+            returnType = set_tlist<view_scilab::CprAdapter, model::Diagram>(new types::TList(), type_name, in);
             if (returnType == nullptr)
             {
                 return types::Function::Error;
@@ -181,7 +154,7 @@ static types::Function::ReturnValue allocate(types::typed_list &in, int /*_iRetC
             }
             break;
         case view_scilab::Adapters::GRAPHIC_ADAPTER:
-            returnType = alloc_and_set_as_mlist<view_scilab::GraphicsAdapter, model::Block>(type_name, in);
+            returnType = set_tlist<view_scilab::GraphicsAdapter, model::Block>(new types::MList(), type_name, in);
             if (returnType == nullptr)
             {
                 return types::Function::Error;
@@ -195,14 +168,14 @@ static types::Function::ReturnValue allocate(types::typed_list &in, int /*_iRetC
             }
             break;
         case view_scilab::Adapters::MODEL_ADAPTER:
-            returnType = alloc_and_set_as_mlist<view_scilab::ModelAdapter, model::Block>(type_name, in);
+            returnType = set_tlist<view_scilab::ModelAdapter, model::Block>(new types::MList(), type_name, in);
             if (returnType == nullptr)
             {
                 return types::Function::Error;
             }
             break;
         case view_scilab::Adapters::PARAMS_ADAPTER:
-            returnType = alloc_and_set_as_tlist<view_scilab::ParamsAdapter, model::Diagram>(type_name, in);
+            returnType = set_tlist<view_scilab::ParamsAdapter, model::Diagram>(new types::TList(), type_name, in);
             if (returnType == nullptr)
             {
                 return types::Function::Error;
@@ -216,7 +189,7 @@ static types::Function::ReturnValue allocate(types::typed_list &in, int /*_iRetC
             }
             break;
         case view_scilab::Adapters::STATE_ADAPTER:
-            returnType = alloc_and_set_as_tlist<view_scilab::StateAdapter, model::Diagram>(type_name, in);
+            returnType = set_tlist<view_scilab::StateAdapter, model::Diagram>(new types::TList(), type_name, in);
             if (returnType == nullptr)
             {
                 return types::Function::Error;
index 0eed4d5..951f44a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
 
 #include "utilities.hxx"
 
-#define REF_DEBUG 0
-#if REF_DEBUG
-#include "scilabWrite.hxx"
-#define REF_PRINT(uid, refCount) \
-       do { \
-       std::stringstream print; \
-       print << "referenceObject( " << uid << " ) : " << refCount << '\n'; \
-       scilabForcedWrite(print.str().data()); \
-       } while(0)
-#define UNREF_PRINT(uid, count) \
-       do { \
-       std::stringstream print; \
-       print << "unreferenceObject( " << uid << " ) : " << refCount << '\n'; \
-       scilabForcedWrite(print.str().data()); \
-       } while(0)
-#define CLONE_PRINT(uid, clone) \
-       do { \
-       std::stringstream print; \
-       print << "cloneObject( " << uid << " ) : " << clone << '\n'; \
-       scilabForcedWrite(print.str().data()); \
-       } while(0)
-#else
-#define REF_PRINT(uid, refCount)
-#define UNREF_PRINT(uid, refCount)
-#define CLONE_PRINT(uid, clone)
-#endif
-
 #include "Controller.hxx"
 #include "model/BaseObject.hxx"
 
@@ -62,17 +35,6 @@ extern "C" {
 namespace org_scilab_modules_scicos
 {
 
-static inline void lock(std::atomic_flag* m)
-{
-    while (m->test_and_set(std::memory_order_acquire))  // acquire lock
-        ; // spin
-}
-
-static inline void unlock(std::atomic_flag* m)
-{
-    m->clear(std::memory_order_release);
-}
-
 /*
  * Implement SharedData methods
  */
@@ -191,7 +153,6 @@ unsigned Controller::referenceObject(const ScicosID uid) const
     lock(&m_instance.onModelStructuralModification);
 
     unsigned refCount = m_instance.model.referenceObject(uid);
-    REF_PRINT(uid, refCount);
 
     auto o = m_instance.model.getObject(uid);
     unlock(&m_instance.onModelStructuralModification);
@@ -236,7 +197,6 @@ void Controller::deleteObject(ScicosID uid)
     if (refCount > 0)
     {
         --refCount;
-        UNREF_PRINT(uid, refCount);
 
         lock(&m_instance.onViewsStructuralModification);
         for (view_set_t::iterator iter = m_instance.allViews.begin(); iter != m_instance.allViews.end(); ++iter)
@@ -252,46 +212,46 @@ void Controller::deleteObject(ScicosID uid)
     // disconnect / remove references of weak connected objects and decrement the reference count of all strongly connected objects.
     if (k == ANNOTATION)
     {
-        unlinkVector(uid, k, PARENT_DIAGRAM, CHILDREN);
-        unlinkVector(uid, k, PARENT_BLOCK, CHILDREN);
+        unlinkVector(initial, PARENT_DIAGRAM, CHILDREN);
+        unlinkVector(initial, PARENT_BLOCK, CHILDREN);
         // RELATED_TO is not referenced back
     }
     else if (k == BLOCK)
     {
-        unlinkVector(uid, k, PARENT_DIAGRAM, CHILDREN);
-        unlinkVector(uid, k, PARENT_BLOCK, CHILDREN);
+        unlinkVector(initial, PARENT_DIAGRAM, CHILDREN);
+        unlinkVector(initial, PARENT_BLOCK, CHILDREN);
 
-        deleteVector(uid, k, INPUTS);
-        deleteVector(uid, k, OUTPUTS);
-        deleteVector(uid, k, EVENT_INPUTS);
-        deleteVector(uid, k, EVENT_OUTPUTS);
+        deleteVector(initial, INPUTS);
+        deleteVector(initial, OUTPUTS);
+        deleteVector(initial, EVENT_INPUTS);
+        deleteVector(initial, EVENT_OUTPUTS);
 
-        unlink(uid, k, CHILDREN, PARENT_BLOCK);
-        deleteVector(uid, k, CHILDREN);
+        unlink(initial, CHILDREN, PARENT_BLOCK);
+        deleteVector(initial, CHILDREN);
         // FIXME what about REFERENCED_PORT ?
     }
     else if (k == DIAGRAM)
     {
-        unlink(uid, k, CHILDREN, PARENT_DIAGRAM);
-        deleteVector(uid, k, CHILDREN);
+        unlink(initial, CHILDREN, PARENT_DIAGRAM);
+        deleteVector(initial, CHILDREN);
     }
     else if (k == LINK)
     {
-        unlinkVector(uid, k, PARENT_DIAGRAM, CHILDREN);
-        unlinkVector(uid, k, PARENT_BLOCK, CHILDREN);
+        unlinkVector(initial, PARENT_DIAGRAM, CHILDREN);
+        unlinkVector(initial, PARENT_BLOCK, CHILDREN);
 
-        unlinkVector(uid, k, SOURCE_PORT, CONNECTED_SIGNALS);
-        unlinkVector(uid, k, DESTINATION_PORT, CONNECTED_SIGNALS);
+        unlinkVector(initial, SOURCE_PORT, CONNECTED_SIGNALS);
+        unlinkVector(initial, DESTINATION_PORT, CONNECTED_SIGNALS);
     }
     else if (k == PORT)
     {
-        unlinkVector(uid, k, SOURCE_BLOCK, INPUTS);
-        unlinkVector(uid, k, SOURCE_BLOCK, OUTPUTS);
-        unlinkVector(uid, k, SOURCE_BLOCK, EVENT_INPUTS);
-        unlinkVector(uid, k, SOURCE_BLOCK, EVENT_OUTPUTS);
+        unlinkVector(initial, SOURCE_BLOCK, INPUTS);
+        unlinkVector(initial, SOURCE_BLOCK, OUTPUTS);
+        unlinkVector(initial, SOURCE_BLOCK, EVENT_INPUTS);
+        unlinkVector(initial, SOURCE_BLOCK, EVENT_OUTPUTS);
 
-        unlink(uid, k, CONNECTED_SIGNALS, SOURCE_PORT);
-        unlink(uid, k, CONNECTED_SIGNALS, DESTINATION_PORT);
+        unlink(initial, CONNECTED_SIGNALS, SOURCE_PORT);
+        unlink(initial, CONNECTED_SIGNALS, DESTINATION_PORT);
     }
 
     // delete the object
@@ -307,10 +267,10 @@ void Controller::deleteObject(ScicosID uid)
     unlock(&m_instance.onViewsStructuralModification);
 }
 
-void Controller::unlinkVector(ScicosID uid, kind_t k, object_properties_t uid_prop, object_properties_t ref_prop)
+void Controller::unlinkVector(model::BaseObject* initial, object_properties_t uid_prop, object_properties_t ref_prop)
 {
     ScicosID v;
-    getObjectProperty(uid, k, uid_prop, v);
+    getObjectProperty(initial->id(), initial->kind(), uid_prop, v);
     if (v != ScicosID())
     {
         auto o = getObject(v);
@@ -322,7 +282,7 @@ void Controller::unlinkVector(ScicosID uid, kind_t k, object_properties_t uid_pr
         std::vector<ScicosID> children;
         getObjectProperty(o->id(), o->kind(), ref_prop, children);
 
-        std::vector<ScicosID>::iterator it = std::find(children.begin(), children.end(), uid);
+        std::vector<ScicosID>::iterator it = std::find(children.begin(), children.end(), initial->id());
         if (it != children.end())
         {
             children.erase(it);
@@ -332,10 +292,10 @@ void Controller::unlinkVector(ScicosID uid, kind_t k, object_properties_t uid_pr
     }
 }
 
-void Controller::unlink(ScicosID uid, kind_t k, object_properties_t uid_prop, object_properties_t ref_prop)
+void Controller::unlink(model::BaseObject* initial, object_properties_t uid_prop, object_properties_t ref_prop)
 {
     std::vector<ScicosID> v;
-    getObjectProperty(uid, k, uid_prop, v);
+    getObjectProperty(initial->id(), initial->kind(), uid_prop, v);
     for (const ScicosID id : v)
     {
         if (id != ScicosID())
@@ -349,7 +309,7 @@ void Controller::unlink(ScicosID uid, kind_t k, object_properties_t uid_prop, ob
             // Find which end of the link is connected to the port
             ScicosID oppositeRef;
             getObjectProperty(o->id(), o->kind(), ref_prop, oppositeRef);
-            if (oppositeRef == uid)
+            if (oppositeRef == initial->id())
             {
                 setObjectProperty(o->id(), o->kind(), ref_prop, ScicosID());
             }
@@ -357,10 +317,10 @@ void Controller::unlink(ScicosID uid, kind_t k, object_properties_t uid_prop, ob
     }
 }
 
-void Controller::deleteVector(ScicosID uid, kind_t k, object_properties_t uid_prop)
+void Controller::deleteVector(model::BaseObject* initial, object_properties_t uid_prop)
 {
     std::vector<ScicosID> children;
-    getObjectProperty(uid, k, uid_prop, children);
+    getObjectProperty(initial->id(), initial->kind(), uid_prop, children);
 
     for (ScicosID id : children)
     {
@@ -369,60 +329,67 @@ void Controller::deleteVector(ScicosID uid, kind_t k, object_properties_t uid_pr
 }
 
 template<typename T>
-void Controller::cloneProperties(model::BaseObject* initial, ScicosID clone)
+void Controller::cloneProperties(model::BaseObject* initial, model::BaseObject* clone)
 {
     for (int i = 0; i < MAX_OBJECT_PROPERTIES; ++i)
     {
         enum object_properties_t p = static_cast<enum object_properties_t>(i);
 
         T value;
-        bool status = getObjectProperty(initial->id(), initial->kind(), p, value);
+        bool status = getObjectProperty(initial, p, value);
         if (status)
         {
-            setObjectProperty(clone, initial->kind(), p, value);
+            setObjectProperty(clone, p, value);
         }
     }
 }
 
-ScicosID Controller::cloneObject(std::map<ScicosID, ScicosID>& mapped, ScicosID uid, bool cloneChildren, bool clonePorts)
+model::BaseObject* Controller::cloneObject(std::map<model::BaseObject*, model::BaseObject*>& mapped, model::BaseObject* initial, bool cloneChildren, bool clonePorts)
 {
-    auto initial = getObject(uid);
     const kind_t k = initial->kind();
     ScicosID o = createObject(k);
-    mapped.insert(std::make_pair(uid, o));
+    model::BaseObject* cloned = getObject(o);
+    mapped.insert(std::make_pair(initial, cloned));
+
+    lock(&m_instance.onViewsStructuralModification);
+    for (view_set_t::iterator iter = m_instance.allViews.begin(); iter != m_instance.allViews.end(); ++iter)
+    {
+        (*iter)->objectCloned(initial->id(), o, k);
+    }
+    unlock(&m_instance.onViewsStructuralModification);
 
     // Get then set all properties per type that do not manage ScicosID
-    cloneProperties<double>(initial, o);
-    cloneProperties<int>(initial, o);
-    cloneProperties<bool>(initial, o);
-    cloneProperties<std::string>(initial, o);
-    cloneProperties<std::vector<double> >(initial, o);
-    cloneProperties<std::vector<int> >(initial, o);
-    cloneProperties<std::vector<std::string> >(initial, o);
+    cloneProperties<double>(initial, cloned);
+    cloneProperties<int>(initial, cloned);
+    cloneProperties<bool>(initial, cloned);
+    cloneProperties<std::string>(initial, cloned);
+    cloneProperties<std::vector<double> >(initial, cloned);
+    cloneProperties<std::vector<int> >(initial, cloned);
+    cloneProperties<std::vector<std::string> >(initial, cloned);
 
     // deep copy children, manage ScicosID and std::vector<ScicosID>
     if (k == ANNOTATION)
     {
-        deepClone(mapped, uid, o, k, PARENT_DIAGRAM, false);
-        deepClone(mapped, uid, o, k, PARENT_BLOCK, false);
-        deepClone(mapped, uid, o, k, RELATED_TO, true);
+        deepClone(mapped, initial, cloned, PARENT_DIAGRAM, false);
+        deepClone(mapped, initial, cloned, PARENT_BLOCK, false);
+        deepClone(mapped, initial, cloned, RELATED_TO, true);
     }
     else if (k == BLOCK)
     {
-        deepClone(mapped, uid, o, k, PARENT_DIAGRAM, false);
+        deepClone(mapped, initial, cloned, PARENT_DIAGRAM, false);
         if (clonePorts)
         {
-            // Only copy the block, without any port
-            deepCloneVector(mapped, uid, o, k, INPUTS, true);
-            deepCloneVector(mapped, uid, o, k, OUTPUTS, true);
-            deepCloneVector(mapped, uid, o, k, EVENT_INPUTS, true);
-            deepCloneVector(mapped, uid, o, k, EVENT_OUTPUTS, true);
+            // copy the block and all its ports
+            deepCloneVector(mapped, initial, cloned, INPUTS, true);
+            deepCloneVector(mapped, initial, cloned, OUTPUTS, true);
+            deepCloneVector(mapped, initial, cloned, EVENT_INPUTS, true);
+            deepCloneVector(mapped, initial, cloned, EVENT_OUTPUTS, true);
         }
 
-        deepClone(mapped, uid, o, k, PARENT_BLOCK, false);
+        deepClone(mapped, initial, cloned, PARENT_BLOCK, false);
         if (cloneChildren)
         {
-            deepCloneVector(mapped, uid, o, k, CHILDREN, true);
+            deepCloneVector(mapped, initial, cloned, CHILDREN, true);
         }
         // FIXME what about REFERENCED_PORT ?
     }
@@ -430,32 +397,33 @@ ScicosID Controller::cloneObject(std::map<ScicosID, ScicosID>& mapped, ScicosID
     {
         if (cloneChildren)
         {
-            deepCloneVector(mapped, uid, o, k, CHILDREN, true);
+            deepCloneVector(mapped, initial, cloned, CHILDREN, true);
         }
     }
     else if (k == LINK)
     {
-        deepClone(mapped, uid, o, k, PARENT_DIAGRAM, false);
-        deepClone(mapped, uid, o, k, PARENT_BLOCK, false);
-        deepClone(mapped, uid, o, k, SOURCE_PORT, false);
-        deepClone(mapped, uid, o, k, DESTINATION_PORT, false);
+        deepClone(mapped, initial, cloned, PARENT_DIAGRAM, false);
+        deepClone(mapped, initial, cloned, PARENT_BLOCK, false);
+        deepClone(mapped, initial, cloned, SOURCE_PORT, false);
+        deepClone(mapped, initial, cloned, DESTINATION_PORT, false);
     }
     else if (k == PORT)
     {
-        deepClone(mapped, uid, o, k, SOURCE_BLOCK, false);
-        deepCloneVector(mapped, uid, o, k, CONNECTED_SIGNALS, false);
+        deepClone(mapped, initial, cloned, SOURCE_BLOCK, false);
+        deepCloneVector(mapped, initial, cloned, CONNECTED_SIGNALS, false);
     }
-    return o;
+    return cloned;
 }
 
-void Controller::deepClone(std::map<ScicosID, ScicosID>& mapped, ScicosID uid, ScicosID clone, kind_t k, object_properties_t p, bool cloneIfNotFound)
+void Controller::deepClone(std::map<model::BaseObject*, model::BaseObject*>& mapped, model::BaseObject* initial, model::BaseObject* clone, object_properties_t p, bool cloneIfNotFound)
 {
     ScicosID v;
-    getObjectProperty(uid, k, p, v);
+    getObjectProperty(initial, p, v);
 
-    ScicosID cloned = ScicosID();
+    model::BaseObject* opposite = getObject(v);
+    model::BaseObject* cloned;
 
-    std::map<ScicosID, ScicosID>::iterator it = mapped.find(v);
+    std::map<model::BaseObject*, model::BaseObject*>::iterator it = mapped.find(opposite);
     if (it != mapped.end())
     {
         cloned = it->second;
@@ -466,33 +434,35 @@ void Controller::deepClone(std::map<ScicosID, ScicosID>& mapped, ScicosID uid, S
         {
             if (v != ScicosID())
             {
-                cloned = cloneObject(mapped, v, true, true);
+                cloned = cloneObject(mapped, opposite, true, true);
             }
             else
             {
-                cloned = ScicosID();
+                cloned = nullptr;
             }
         }
         else
         {
-            cloned = ScicosID();
+            cloned = nullptr;
         }
     }
 
-    setObjectProperty(clone, k, p, cloned);
-    // When cloning a Link, connect both extremities together
-    if ((p == SOURCE_PORT || p == DESTINATION_PORT) && cloned != ScicosID())
+    if (cloned == nullptr)
+    {
+        setObjectProperty(clone, p, ScicosID());
+    }
+    else
     {
-        setObjectProperty(cloned, PORT, CONNECTED_SIGNALS, clone);
+        setObjectProperty(clone, p, cloned->id());
     }
 }
 
-void Controller::deepCloneVector(std::map<ScicosID, ScicosID>& mapped, ScicosID uid, ScicosID clone, kind_t k, object_properties_t p, bool cloneIfNotFound)
+void Controller::deepCloneVector(std::map<model::BaseObject*, model::BaseObject*>& mapped, model::BaseObject* initial, model::BaseObject* clone, object_properties_t p, bool cloneIfNotFound)
 {
     std::vector<ScicosID> v;
-    getObjectProperty(uid, k, p, v);
+    getObjectProperty(initial, p, v);
 
-    std::vector<ScicosID> cloned;
+    std::vector<model::BaseObject*> cloned;
     cloned.reserve(v.size());
 
     for (const ScicosID & id : v)
@@ -500,29 +470,14 @@ void Controller::deepCloneVector(std::map<ScicosID, ScicosID>& mapped, ScicosID
         if (id == ScicosID())
         {
             // Deleted Block, the cloning is done at Adapter level
-            cloned.push_back(id);
+            cloned.push_back(nullptr);
             continue;
         }
 
-        std::map<ScicosID, ScicosID>::iterator it = mapped.find(id);
+        model::BaseObject* opposite = getObject(id);
+        std::map<model::BaseObject*, model::BaseObject*>::iterator it = mapped.find(opposite);
         if (it != mapped.end())
         {
-            if (k == PORT)
-            {
-                // We get here if we are cloning a block connected to a link that comes before itself in the objects list,
-                // so which has already been cloned but could not be connected yet.
-                int port_kind;
-                getObjectProperty(clone, PORT, PORT_KIND, port_kind);
-                if (port_kind == PORT_IN || port_kind == PORT_EIN)
-                {
-                    setObjectProperty(it->second, LINK, DESTINATION_PORT, clone);
-                }
-                else
-                {
-                    // FIXME: fix case for implicit ports, in which case connect the first unconnected link end, it doesn't matter which one
-                    setObjectProperty(it->second, LINK, SOURCE_PORT, clone);
-                }
-            }
             cloned.push_back(it->second);
         }
         else
@@ -531,30 +486,67 @@ void Controller::deepCloneVector(std::map<ScicosID, ScicosID>& mapped, ScicosID
             {
                 if (id != ScicosID())
                 {
-                    cloned.push_back(cloneObject(mapped, id, true, true));
+                    model::BaseObject* clone = cloneObject(mapped, opposite, true, true);
+                    cloned.push_back(clone);
                 }
                 else
                 {
-                    cloned.push_back(ScicosID());
+                    cloned.push_back(nullptr);
                 }
             }
             else
             {
-                cloned.push_back(ScicosID());
+                cloned.push_back(getObject(id));
+            }
+        }
+    }
+
+    // update the ScicosID related properties after cloning all the objects
+    if (p == CHILDREN)
+    {
+        for (auto const& it : mapped)
+        {
+            model::BaseObject* initial = it.first;
+            model::BaseObject* cloned = it.second;
+
+            switch (initial->kind())
+            {
+                case PORT:
+                    deepCloneVector(mapped, initial, cloned, CONNECTED_SIGNALS, false);
+                    break;
+                case LINK:
+                    deepClone(mapped, initial, cloned, SOURCE_PORT, false);
+                    deepClone(mapped, initial, cloned, DESTINATION_PORT, false);
+                    break;
+                default:
+                    break;
             }
         }
     }
 
-    setObjectProperty(clone, k, p, cloned);
+    // set the main object vector property
+    std::vector<ScicosID> clonedUIDs(cloned.size());
+    std::transform(cloned.begin(), cloned.end(), clonedUIDs.begin(), [](model::BaseObject * o)
+    {
+        if (o == nullptr)
+        {
+            return ScicosID();
+        }
+        else
+        {
+            return o->id();
+        }
+    });
+
+    setObjectProperty(clone, p, clonedUIDs);
 }
 
 ScicosID Controller::cloneObject(ScicosID uid, bool cloneChildren, bool clonePorts)
 {
-    std::map<ScicosID, ScicosID> mapped;
-    ScicosID clone = cloneObject(mapped, uid, cloneChildren, clonePorts);
-    CLONE_PRINT(uid, clone);
+    std::map<model::BaseObject*, model::BaseObject*> mapped;
+    model::BaseObject* clone = cloneObject(mapped, getObject(uid), cloneChildren, clonePorts);
 
-    return clone;
+    return clone->id();
 }
 
 kind_t Controller::getKind(ScicosID uid) const
index 080bd04..06243b2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -52,12 +52,12 @@ static std::wstring levelTable[] =
 
 static std::string displayTable[] =
 {
-    "Xcos trace: ",
-    "Xcos debug: ",
-    "Xcos info: ",
+    "Xcos trace:   ",
+    "Xcos debug:   ",
+    "Xcos info:    ",
     "Xcos warning: ",
-    "Xcos error: ",
-    "Xcos fatal: ",
+    "Xcos error:   ",
+    "Xcos fatal:   ",
 };
 
 enum LogLevel LoggerView::indexOf(const wchar_t* name)
@@ -338,12 +338,6 @@ std::ostream& operator<<(std::ostream& os, object_properties_t p)
         case KIND:
             os << "KIND";
             break;
-        case FROM:
-            os << "FROM";
-            break;
-        case TO:
-            os << "TO";
-            break;
         case DATATYPE:
             os << "DATATYPE";
             break;
@@ -402,35 +396,49 @@ void LoggerView::objectCreated(const ScicosID& uid, kind_t k)
 {
     std::stringstream ss;
     ss << "objectCreated" << "( " << uid << " , " << k << " )" << '\n';
-    log(LOG_DEBUG, ss);
+    log(LOG_INFO, ss);
 }
 
 void LoggerView::objectReferenced(const ScicosID& uid, kind_t k, unsigned refCount)
 {
     std::stringstream ss;
     ss << "objectReferenced" << "( " << uid << " , " << k << " ) : " << refCount << '\n';
-    log(LOG_DEBUG, ss);
+    log(LOG_TRACE, ss);
 }
 
 void LoggerView::objectUnreferenced(const ScicosID& uid, kind_t k, unsigned refCount)
 {
     std::stringstream ss;
     ss << "objectUnreferenced" << "( " << uid << " , " << k << " ) : " << refCount << '\n';
-    log(LOG_DEBUG, ss);
+    log(LOG_TRACE, ss);
 }
 
 void LoggerView::objectDeleted(const ScicosID& uid, kind_t k)
 {
     std::stringstream ss;
     ss << "objectDeleted" << "( " << uid << " , " << k << " )" << '\n';
-    log(LOG_DEBUG, ss);
+    log(LOG_INFO, ss);
+}
+
+void LoggerView::objectCloned(const ScicosID& uid, const ScicosID& cloned, kind_t k)
+{
+    std::stringstream ss;
+    ss << "objectCloned" << "( " << uid << " , " << cloned << " , " << k << " )" << '\n';
+    log(LOG_INFO, ss);
 }
 
 void LoggerView::propertyUpdated(const ScicosID& uid, kind_t k, object_properties_t p, update_status_t u)
 {
     std::stringstream ss;
     ss << "propertyUpdated" << "( " << uid << " , " << k << " , " << p << " ) : " << u << '\n';
-    log(LOG_TRACE, ss);
+    if (u == NO_CHANGES)
+    {
+        log(LOG_TRACE, ss);
+    }
+    else
+    {
+        log(LOG_DEBUG, ss);
+    }
 }
 
 } /* namespace org_scilab_modules_scicos */
index 4b8c405..621da2e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -73,6 +73,7 @@ public:
     void objectReferenced(const ScicosID& uid, kind_t k, unsigned refCount);
     void objectUnreferenced(const ScicosID& uid, kind_t k, unsigned refCount);
     void objectDeleted(const ScicosID& uid, kind_t k);
+    void objectCloned(const ScicosID& uid, const ScicosID& cloned, kind_t k);
     void propertyUpdated(const ScicosID& uid, kind_t k, object_properties_t p, update_status_t u);
 
 private:
index 33d9e3c..f521ca4 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -129,8 +129,8 @@ unsigned Model::referenceObject(const ScicosID uid)
         return 0;
     }
 
-    ModelObject& modelObject = iter->second;
-    return ++(modelObject.m_refCounter);
+    model::BaseObject* modelObject = iter->second;
+    return ++modelObject->refCount();
 }
 
 unsigned& Model::referenceCount(ScicosID uid)
@@ -141,8 +141,8 @@ unsigned& Model::referenceCount(ScicosID uid)
         throw std::string("key has not been found");
     }
 
-    ModelObject& modelObject = iter->second;
-    return modelObject.m_refCounter;
+    model::BaseObject* modelObject = iter->second;
+    return modelObject->refCount();
 
 }
 
@@ -154,16 +154,15 @@ void Model::deleteObject(ScicosID uid)
         throw std::string("key has not been found");
     }
 
-    ModelObject& modelObject = iter->second;
-    if (modelObject.m_refCounter == 0)
+    model::BaseObject* modelObject = iter->second;
+    if (modelObject->refCount() == 0)
     {
-        model::BaseObject* o = modelObject.m_o;
         allObjects.erase(iter);
-        delete o;
+        delete modelObject;
     }
     else
     {
-        --(modelObject.m_refCounter);
+        --modelObject->refCount();
     }
 }
 
@@ -187,9 +186,9 @@ std::vector<ScicosID> Model::getAll(kind_t k) const
 
     for (objects_map_t::const_iterator it = allObjects.begin(); it != allObjects.end(); ++it)
     {
-        if (it->second.m_o->kind() == k)
+        if (it->second->kind() == k)
         {
-            all.push_back(it->second.m_o->id());
+            all.push_back(it->second->id());
         }
     }
 
@@ -204,7 +203,7 @@ model::BaseObject* Model::getObject(ScicosID uid) const
         return nullptr;
     }
 
-    return iter->second.m_o;
+    return iter->second;
 }
 
 // datatypes being a vector of Datatype pointers, we need a dereferencing comparison operator to use std::lower_bound()
index 2d515f3..ef4ea3c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -33,55 +33,14 @@ extern "C" {
 namespace org_scilab_modules_scicos
 {
 
-/* helper function to decode simple string EXPRS */
-static std::vector<std::string> decode_string_vector(const std::vector<double>& v)
+bool Model::getObjectProperty(model::BaseObject* object, object_properties_t p, double& v)  const
 {
-    std::vector<std::string> ret;
-    std::vector<double>::const_iterator it = v.begin();
-
-    int strHeader = *it++;
-    if (strHeader != sci_strings)
-    {
-        return ret;
-    }
-    unsigned int iDims = *it++;
-
-    // manage multi-dimensionnal arrays (will be serialized as a vector)
-    unsigned int iElements = 1;
-    for (unsigned int i = 0; i < iDims; ++i)
-    {
-        iElements *= static_cast<unsigned int>(*it++);
-    }
-
-    // retrieve the length of each encoded string, stored as a stack
-    std::vector<unsigned int> stringsLength;
-    stringsLength.reserve(iElements + 1);
-    stringsLength.push_back(0);
-    for (unsigned int i = 0; i < iElements; ++i)
-    {
-        stringsLength.push_back(*it++);
-    }
-
-    // Retrieving the pointers (already UTF-8 encoded char*) and store them as strings
-    ret.reserve(iElements);
-    const double* strData = &(*it);
-    for (unsigned int i = 0; i < iElements; ++i)
-    {
-        // push the data
-        ret.push_back((char*) (strData + stringsLength[i]));
-    }
-
-    return ret;
-}
-
-
-bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, double& v)  const
-{
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return false;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -130,13 +89,14 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, dou
     return false;
 }
 
-bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, int& v) const
+bool Model::getObjectProperty(model::BaseObject* object, object_properties_t p, int& v) const
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return false;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -200,13 +160,14 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, int
     return false;
 }
 
-bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, bool& v) const
+bool Model::getObjectProperty(model::BaseObject* object, object_properties_t p, bool& v) const
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return false;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -255,13 +216,14 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, boo
     return false;
 }
 
-bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::string& v) const
+bool Model::getObjectProperty(model::BaseObject* object, object_properties_t p, std::string& v) const
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return false;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -374,13 +336,14 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std
     return false;
 }
 
-bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, ScicosID& v) const
+bool Model::getObjectProperty(model::BaseObject* object, object_properties_t p, ScicosID& v) const
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return false;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -461,13 +424,14 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, Sci
     return false;
 }
 
-bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::vector<double>& v) const
+bool Model::getObjectProperty(model::BaseObject* object, object_properties_t p, std::vector<double>& v) const
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return false;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -552,13 +516,14 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std
     return false;
 }
 
-bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::vector<int>& v) const
+bool Model::getObjectProperty(model::BaseObject* object, object_properties_t p, std::vector<int>& v) const
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return false;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -627,13 +592,14 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std
     return false;
 }
 
-bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::vector<bool>& /*v*/) const
+bool Model::getObjectProperty(model::BaseObject* object, object_properties_t p, std::vector<bool>& /*v*/) const
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return false;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -678,13 +644,14 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std
     return false;
 }
 
-bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::vector<std::string>& v) const
+bool Model::getObjectProperty(model::BaseObject* object, object_properties_t p, std::vector<std::string>& v) const
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return false;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -702,14 +669,6 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std
             case DIAGRAM_CONTEXT:
                 o->getContext(v);
                 return true;
-            case EXPRS:
-            {
-                std::vector<double> data;
-                o->getExprs(data);
-
-                v = decode_string_vector(data);
-                return true;
-            }
             default:
                 break;
         }
@@ -745,13 +704,14 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std
     return false;
 }
 
-bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::vector<ScicosID>& v) const
+bool Model::getObjectProperty(model::BaseObject* object, object_properties_t p, std::vector<ScicosID>& v) const
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return false;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
index c881e02..dec7aba 100644 (file)
@@ -31,56 +31,20 @@ extern "C" {
 #include "sci_types.h"
 }
 
+// Check the model at runtime (children / parent ; block / ports)
+#define SANITY_CHECK 0
+
 namespace org_scilab_modules_scicos
 {
 
-/* helper function to encode simple string EXPRS */
-static std::vector<double> encode_string_vector(const std::vector<std::string>& v)
+update_status_t Model::setObjectProperty(model::BaseObject* object, object_properties_t p, double v)
 {
-    std::vector<double> ret;
-
-    // header
-    ret.push_back(sci_strings);
-
-    // serialize as a Scilab vector
-    ret.push_back(2); // MxN
-    ret.push_back(v.size()); // M
-    ret.push_back(1); // N
-
-    // reserve some space to store the length of each string (including the null terminating character)
-    ret.resize(ret.size() + v.size());
-
-    // store the index and the null terminated UTF-8 strings
-    size_t stringOffset = 0;
-    for (size_t i = 0; i < v.size(); ++i)
-    {
-        const std::string& str = v[i];
-        // length as a 64bit index (as we store on a double vector)
-        size_t len = ((str.size() + 1) * sizeof(char) + sizeof(double) - 1) / sizeof(double);
-
-        // insert the offset
-        auto it = ret.begin() + 4 + i;
-        stringOffset += len;
-        *it = stringOffset;
-
-        // reserve some space for the string
-        size_t size = ret.size();
-        ret.resize(size + len);
-
-        // copy the UTF-8 encoded values
-        std::memcpy(ret.data() + size, str.data(), str.size());
-    }
-
-    return ret;
-}
-
-update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, double v)
-{
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return FAIL;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -128,13 +92,14 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
     return FAIL;
 }
 
-update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, int v)
+update_status_t Model::setObjectProperty(model::BaseObject* object, object_properties_t p, int v)
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return FAIL;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -193,13 +158,14 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
     return FAIL;
 }
 
-update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, bool v)
+update_status_t Model::setObjectProperty(model::BaseObject* object, object_properties_t p, bool v)
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return FAIL;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -247,13 +213,14 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
     return FAIL;
 }
 
-update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, ScicosID v)
+update_status_t Model::setObjectProperty(model::BaseObject* object, object_properties_t p, ScicosID v)
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return FAIL;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -324,13 +291,14 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
     return FAIL;
 }
 
-update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std::string v)
+update_status_t Model::setObjectProperty(model::BaseObject* object, object_properties_t p, std::string v)
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return FAIL;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -422,13 +390,14 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
     return FAIL;
 }
 
-update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, const std::vector<double>& v)
+update_status_t Model::setObjectProperty(model::BaseObject* object, object_properties_t p, const std::vector<double>& v)
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return FAIL;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -501,13 +470,14 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
     return FAIL;
 }
 
-update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, const std::vector<int>& v)
+update_status_t Model::setObjectProperty(model::BaseObject* object, object_properties_t p, const std::vector<int>& v)
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return FAIL;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -569,13 +539,14 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
     return FAIL;
 }
 
-update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, const std::vector<bool>& /*v*/)
+update_status_t Model::setObjectProperty(model::BaseObject* object, object_properties_t p, const std::vector<bool>& /*v*/)
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return FAIL;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -620,13 +591,14 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
     return FAIL;
 }
 
-update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, const std::vector<std::string>& v)
+update_status_t Model::setObjectProperty(model::BaseObject* object, object_properties_t p, const std::vector<std::string>& v)
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return FAIL;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -643,8 +615,6 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
         {
             case DIAGRAM_CONTEXT:
                 return o->setContext(v);
-            case EXPRS:
-                return o->setExprs(encode_string_vector(v));
             default:
                 break;
         }
@@ -679,13 +649,14 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
     return FAIL;
 }
 
-update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properties_t p, const std::vector<ScicosID>& v)
+update_status_t Model::setObjectProperty(model::BaseObject* object, object_properties_t p, const std::vector<ScicosID>& v)
 {
-    model::BaseObject* baseObject = getObject(uid);
+    model::BaseObject* baseObject = object;
     if (baseObject == nullptr)
     {
         return FAIL;
     }
+    kind_t k = object->kind();
 
     if (k == ANNOTATION)
     {
@@ -701,14 +672,93 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
         switch (p)
         {
             case INPUTS:
+#if SANITY_CHECK
+                for (ScicosID port : v)
+                {
+                    model::BaseObject* p = getObject(port);
+
+                    ScicosID parent = ScicosID();
+                    getObjectProperty(p, SOURCE_BLOCK, parent);
+                    if (parent != baseObject->id())
+                    {
+                        abort();
+                    }
+                }
+#endif /* SANITY_CHECK */
                 return o->setIn(v);
             case OUTPUTS:
+#if SANITY_CHECK
+                for (ScicosID port : v)
+                {
+                    model::BaseObject* p = getObject(port);
+
+                    ScicosID parent = ScicosID();
+                    getObjectProperty(p, SOURCE_BLOCK, parent);
+                    if (parent != baseObject->id())
+                    {
+                        abort();
+                    }
+                }
+#endif /* SANITY_CHECK */
                 return o->setOut(v);
             case EVENT_INPUTS:
+#if SANITY_CHECK
+                for (ScicosID port : v)
+                {
+                    model::BaseObject* p = getObject(port);
+
+                    ScicosID parent = ScicosID();
+                    getObjectProperty(p, SOURCE_BLOCK, parent);
+                    if (parent != baseObject->id())
+                    {
+                        abort();
+                    }
+                }
+#endif /* SANITY_CHECK */
                 return o->setEin(v);
             case EVENT_OUTPUTS:
+#if SANITY_CHECK
+                for (ScicosID port : v)
+                {
+                    model::BaseObject* p = getObject(port);
+
+                    ScicosID parent = ScicosID();
+                    getObjectProperty(p, SOURCE_BLOCK, parent);
+                    if (parent != baseObject->id())
+                    {
+                        abort();
+                    }
+                }
+#endif /* SANITY_CHECK */
                 return o->setEout(v);
             case CHILDREN:
+#if SANITY_CHECK
+                for (ScicosID child : v)
+                {
+                    if (child == ScicosID())
+                    {
+                        continue;
+                    }
+
+                    model::BaseObject* c = getObject(child);
+
+                    ScicosID parent = ScicosID();
+                    getObjectProperty(c, PARENT_BLOCK, parent);
+                    if (parent != baseObject->id())
+                    {
+                        abort();
+                    }
+
+                    ScicosID parentDiagram = ScicosID();
+                    getObjectProperty(o, PARENT_DIAGRAM, parentDiagram);
+                    ScicosID parentParentDiagram  = ScicosID();
+                    getObjectProperty(parent, BLOCK, PARENT_DIAGRAM, parentParentDiagram);
+                    if (parentDiagram != parentParentDiagram)
+                    {
+                        abort();
+                    }
+                }
+#endif /* SANITY_CHECK */
                 return o->setChildren(v);
             default:
                 break;
@@ -720,6 +770,30 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
         switch (p)
         {
             case CHILDREN:
+#if SANITY_CHECK
+                for (ScicosID child : v)
+                {
+                    if (child == ScicosID())
+                    {
+                        continue;
+                    }
+
+                    model::BaseObject* c = getObject(child);
+
+                    ScicosID parent = ScicosID();
+                    getObjectProperty(c, PARENT_BLOCK, parent);
+                    if (parent != ScicosID())
+                    {
+                        abort();
+                    }
+
+                    getObjectProperty(c, PARENT_DIAGRAM, parent);
+                    if (parent != baseObject->id())
+                    {
+                        abort();
+                    }
+                }
+#endif /* SANITY_CHECK */
                 return o->setChildren(v);
             default:
                 break;
index 2760824..14ef65c 100644 (file)
@@ -27,6 +27,7 @@ extern "C"
 #include <libxml/xmlerror.h>
 #include <libxml/xmlreader.h>
 
+#include "sci_types.h"
 #include "sciprint.h"
 }
 
@@ -206,6 +207,35 @@ int XMIResource::load(const char* uri)
         if (it != references.end())
         {
             controller.setObjectProperty(ref.m_id, ref.m_kind, ref.m_prop, it->second);
+
+            // change the link kind on re-connection
+            if (ref.m_kind == LINK)
+            {
+                if (ref.m_prop == SOURCE_PORT || ref.m_prop == DESTINATION_PORT)
+                {
+                    int kind;
+                    controller.getObjectProperty(it->second, PORT, PORT_KIND, kind);
+
+                    if (kind == PORT_EIN || kind == PORT_EOUT)
+                    {
+                        // this should be an event link
+                        controller.setObjectProperty(ref.m_id, LINK, COLOR, 5);
+                        controller.setObjectProperty(ref.m_id, LINK, KIND, -1);
+                    }
+                    else
+                    {
+                        bool isImplicit;
+                        controller.getObjectProperty(it->second, PORT, IMPLICIT, isImplicit);
+
+                        if (isImplicit)
+                        {
+                            // this should be a modelica link
+                            controller.setObjectProperty(ref.m_id, LINK, KIND, 2);
+                        }
+                    }
+                    // otherwise this should be a regular link
+                }
+            }
         }
         else
         {
@@ -290,6 +320,114 @@ int XMIResource::loadStringArray(xmlTextReaderPtr reader, enum object_properties
     return 1;
 }
 
+/* helper function to encode simple string */
+static std::vector<double> encode_string_vector(const std::vector<std::string>& v)
+{
+    std::vector<double> ret;
+
+    // header
+    ret.push_back(sci_strings);
+
+    // serialize as a Scilab vector
+    ret.push_back(2); // MxN
+    ret.push_back(v.size()); // M
+    if (v.size() > 0)
+    {
+        ret.push_back(1);    // N
+    }
+    else
+    {
+        ret.push_back(0);
+    }
+
+    // reserve some space to store the length of each string (including the null terminating character)
+    ret.resize(ret.size() + v.size());
+
+    // store the index and the null terminated UTF-8 strings
+    size_t stringOffset = 0;
+    for (size_t i = 0; i < v.size(); ++i)
+    {
+        const std::string& str = v[i];
+        // length as a 64bit index (as we store on a double vector)
+        size_t len = ((str.size() + 1) * sizeof(char) + sizeof(double) - 1) / sizeof(double);
+
+        // insert the offset
+        auto it = ret.begin() + 4 + i;
+        stringOffset += len;
+        *it = stringOffset;
+
+        // reserve some space for the string
+        size_t size = ret.size();
+        ret.resize(size + len);
+
+        // copy the UTF-8 encoded values (\0 terminated thanks to the resize)
+        std::memcpy(ret.data() + size, str.data(), str.size());
+    }
+
+    return ret;
+}
+
+/* helper function to decode simple string */
+static std::vector<std::string> decode_string_vector(const std::vector<double>& v)
+{
+    std::vector<std::string> exprs;
+
+    if (v.size() < 3)
+    {
+        return exprs;
+    }
+
+    // decode header
+    int type = v[0];
+    int iDims = v[1];
+    if (type != sci_strings )
+    {
+        return exprs;
+    }
+    if (iDims < 2)
+    {
+        return exprs;
+    }
+
+    // number of elements (setup the first one)
+    int iElements = v[2];
+    for (int i = 1; i < iDims; ++i)
+    {
+        iElements *= v[2 + i];
+    }
+
+    if (iElements == 0)
+    {
+        return exprs;
+    }
+
+    // decode UTF-8 strings
+    char* pString = (char*) (v.data() + 2 + iDims + iElements);
+    size_t len = static_cast<size_t>(v[2 + iDims]);
+    for (int i = 1; i < iElements; i++)
+    {
+        exprs.emplace_back(pString);
+
+        pString = (char*) (v.data() + 2 + iDims + iElements + len);
+        len = static_cast<size_t>(v[2 + iDims + i]);
+    }
+    exprs.emplace_back(pString);
+
+    return exprs;
+}
+
+int XMIResource::loadEncodedStringArray(xmlTextReaderPtr reader, enum object_properties_t property, const model::BaseObject& o)
+{
+    std::vector<double> v;
+    controller.getObjectProperty(o.id(), o.kind(), property, v);
+
+    std::vector<std::string> exprsAsString = decode_string_vector(v);
+    exprsAsString.push_back(to_string(xmlTextReaderConstValue(reader)));
+
+    controller.setObjectProperty(o.id(), o.kind(), property, encode_string_vector(exprsAsString));
+    return 1;
+}
+
 int XMIResource::loadBase64(xmlTextReaderPtr reader, enum object_properties_t property, const model::BaseObject& o)
 {
     // iterate on attributes
@@ -919,6 +1057,13 @@ int XMIResource::processElement(xmlTextReaderPtr reader)
 
                         // assign the child
                         model::BaseObject parent = processed.back();
+
+                        controller.referenceObject(o);
+                        controller.setObjectProperty(o, BLOCK, PARENT_DIAGRAM, root);
+                        if (parent.kind() == BLOCK)
+                        {
+                            controller.setObjectProperty(o, BLOCK, PARENT_BLOCK, parent.id());
+                        }
                         std::vector<ScicosID> children;
                         controller.getObjectProperty(parent.id(), parent.kind(), CHILDREN, children);
                         children.push_back(o);
@@ -934,6 +1079,13 @@ int XMIResource::processElement(xmlTextReaderPtr reader)
 
                         // assign the child
                         model::BaseObject parent = processed.back();
+
+                        controller.referenceObject(o);
+                        controller.setObjectProperty(o, LINK, PARENT_DIAGRAM, root);
+                        if (parent.kind() == BLOCK)
+                        {
+                            controller.setObjectProperty(o, LINK, PARENT_BLOCK, parent.id());
+                        }
                         std::vector<ScicosID> children;
                         controller.getObjectProperty(parent.id(), parent.kind(), CHILDREN, children);
                         children.push_back(o);
@@ -949,6 +1101,13 @@ int XMIResource::processElement(xmlTextReaderPtr reader)
 
                         // assign the child
                         model::BaseObject parent = processed.back();
+
+                        controller.referenceObject(o);
+                        controller.setObjectProperty(o, ANNOTATION, PARENT_DIAGRAM, root);
+                        if (parent.kind() == BLOCK)
+                        {
+                            controller.setObjectProperty(o, ANNOTATION, PARENT_BLOCK, parent.id());
+                        }
                         std::vector<ScicosID> children;
                         controller.getObjectProperty(parent.id(), parent.kind(), CHILDREN, children);
                         children.push_back(o);
@@ -993,6 +1152,8 @@ int XMIResource::processElement(xmlTextReaderPtr reader)
 
             model::BaseObject parent = processed.back();
             // add the port them to the parent
+            controller.setObjectProperty(o, PORT, SOURCE_BLOCK, parent.id());
+
             std::vector<ScicosID> ports;
             controller.getObjectProperty(parent.id(), parent.kind(), p, ports);
             ports.push_back(o);
@@ -1126,7 +1287,7 @@ int XMIResource::processText(xmlTextReaderPtr reader)
             break;
         case e_expression:
             // expression is a Block property
-            ret = loadStringArray(reader, EXPRS, processed.back());
+            ret = loadEncodedStringArray(reader, EXPRS, processed.back());
             break;
         case e_context:
             // context is a Layer property
index 215ea60..1bb9b66 100644 (file)
@@ -93,11 +93,53 @@ static std::string to_string(double v)
     }
 
     std::string str(15, '\0');
-       // std::snprintf(const_cast<char*>(str.data()), str.size(), "%.6E", v);
+    // std::snprintf(const_cast<char*>(str.data()), str.size(), "%.6E", v);
     std::sprintf(const_cast<char*>(str.data()), "%.6E", v);
     return str;
 }
 
+/* helper function to decode simple string EXPRS */
+static std::vector<std::string> to_string_vector(const std::vector<double>& v)
+{
+    std::vector<std::string> ret;
+    std::vector<double>::const_iterator it = v.begin();
+
+    int strHeader = *it++;
+    if (strHeader != sci_strings)
+    {
+        return ret;
+    }
+    unsigned int iDims = *it++;
+
+    // manage multi-dimensional arrays (will be serialized as a vector)
+    unsigned int iElements = 1;
+    for (unsigned int i = 0; i < iDims; ++i)
+    {
+        iElements *= static_cast<unsigned int>(*it++);
+    }
+
+    // retrieve the length of each encoded string, stored as a stack
+    std::vector<unsigned int> stringsLength;
+    stringsLength.reserve(iElements + 1);
+    stringsLength.push_back(0);
+    for (unsigned int i = 0; i < iElements; ++i)
+    {
+        stringsLength.push_back(*it++);
+    }
+
+    // Retrieving the pointers (already UTF-8 encoded char*) and store them as strings
+    ret.reserve(ret.size() + iElements);
+    for (unsigned int i = 0; i < iElements; ++i)
+    {
+        // push the data
+        const double* strData = &(*(it + stringsLength[i]));
+        ret.emplace_back((char*) strData);
+    }
+
+    return ret;
+}
+
+
 static int writeBase64(xmlTextWriterPtr writer, const char* name, const std::vector<double>& v)
 {
     int status;
@@ -605,8 +647,7 @@ int XMIResource::writeBlock(xmlTextWriterPtr writer, ScicosID id)
     else if (is_string_vector(doubleArrayValue))
     {
         // if this is a string the expression is used
-        std::vector<std::string> values;
-        controller.getObjectProperty(id, BLOCK, EXPRS, values);
+        std::vector<std::string> values = to_string_vector(doubleArrayValue);
 
         for (const std::string& s : values)
         {
index 8874597..486acd3 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
index f548394..35a3113 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -95,8 +95,9 @@ class Block: public BaseObject
 {
 public:
     Block() : BaseObject(BLOCK), m_parentDiagram(ScicosID()), m_interfaceFunction(), m_geometry(),
-        m_description(), m_label(), m_style(), m_uid(), m_sim(), m_in(), m_out(), m_ein(), m_eout(),
-        m_parameter(), m_state(), m_parentBlock(ScicosID()), m_children(), m_childrenColor(), m_context(), m_portReference(ScicosID())
+        m_exprs(), m_description(), m_label(), m_style(), m_nzcross(), m_nmode(), m_equations(), m_uid(),
+        m_sim(), m_in(), m_out(), m_ein(), m_eout(), m_parameter(), m_state(), m_parentBlock(ScicosID()),
+        m_children(), m_childrenColor(), m_context(), m_portReference(ScicosID())
     {
         // m_exprs default value is an empty matrix encoded by var2vec()
         m_exprs = {1, 2, 0, 0, 0};
index 2e9fd94..b95804f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -72,7 +72,7 @@ struct SimulationConfig
 class Diagram: public BaseObject
 {
 public:
-    Diagram() : BaseObject(DIAGRAM), m_title("Untitled"), m_path(), m_properties(), m_debugLevel(), m_context(), m_children(), m_version()
+    Diagram() : BaseObject(DIAGRAM), m_title("Untitled"), m_path(), m_properties(), m_debugLevel(), m_context(), m_children(), m_version("scicos4.4")
     {
         m_color = { -1, 1};
     }
index fae5141..1b06382 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
index e3e708f..15dc4ea 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
index 1397740..bdd37bf 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -79,7 +79,6 @@ Adapters::adapters_index_t Adapters::lookup_by_typename(const std::wstring& name
     return INVALID_ADAPTER;
 }
 
-
 std::wstring Adapters::get_typename(Adapters::adapters_index_t kind)
 {
     for (auto it : adapters)
@@ -93,43 +92,46 @@ std::wstring Adapters::get_typename(Adapters::adapters_index_t kind)
     return L"";
 }
 
-
-const model::BaseObject* Adapters::descriptor(types::InternalType* v)
+model::BaseObject* Adapters::descriptor(types::InternalType* v)
 {
     const std::wstring& name = v->getShortTypeStr();
     adapters_t::iterator it = std::lower_bound(adapters.begin(), adapters.end(), name);
     if (v->isUserType() && it != adapters.end() && !(name < it->name))
     {
-        switch (it->kind)
-        {
-            case BLOCK_ADAPTER:
-                return v->getAs<view_scilab::BlockAdapter>()->getAdaptee();
-            case CPR_ADAPTER:
-                return v->getAs<view_scilab::CprAdapter>()->getAdaptee();
-            case DIAGRAM_ADAPTER:
-                return v->getAs<view_scilab::DiagramAdapter>()->getAdaptee();
-            case GRAPHIC_ADAPTER:
-                return v->getAs<view_scilab::GraphicsAdapter>()->getAdaptee();
-            case LINK_ADAPTER:
-                return v->getAs<view_scilab::LinkAdapter>()->getAdaptee();
-            case MODEL_ADAPTER:
-                return v->getAs<view_scilab::ModelAdapter>()->getAdaptee();
-            case PARAMS_ADAPTER:
-                return v->getAs<view_scilab::ParamsAdapter>()->getAdaptee();
-            case SCS_ADAPTER:
-                return v->getAs<view_scilab::ScsAdapter>()->getAdaptee();
-            case STATE_ADAPTER:
-                return v->getAs<view_scilab::StateAdapter>()->getAdaptee();
-            case TEXT_ADAPTER:
-                return v->getAs<view_scilab::TextAdapter>()->getAdaptee();
-            default:
-                return nullptr;
-        }
+        return descriptor(it->kind, v);
     }
-
     return nullptr;
 }
 
+model::BaseObject* Adapters::descriptor(adapters_index_t index, types::InternalType* v)
+{
+    switch (index)
+    {
+        case BLOCK_ADAPTER:
+            return v->getAs<view_scilab::BlockAdapter>()->getAdaptee();
+        case CPR_ADAPTER:
+            return v->getAs<view_scilab::CprAdapter>()->getAdaptee();
+        case DIAGRAM_ADAPTER:
+            return v->getAs<view_scilab::DiagramAdapter>()->getAdaptee();
+        case GRAPHIC_ADAPTER:
+            return v->getAs<view_scilab::GraphicsAdapter>()->getAdaptee();
+        case LINK_ADAPTER:
+            return v->getAs<view_scilab::LinkAdapter>()->getAdaptee();
+        case MODEL_ADAPTER:
+            return v->getAs<view_scilab::ModelAdapter>()->getAdaptee();
+        case PARAMS_ADAPTER:
+            return v->getAs<view_scilab::ParamsAdapter>()->getAdaptee();
+        case SCS_ADAPTER:
+            return v->getAs<view_scilab::ScsAdapter>()->getAdaptee();
+        case STATE_ADAPTER:
+            return v->getAs<view_scilab::StateAdapter>()->getAdaptee();
+        case TEXT_ADAPTER:
+            return v->getAs<view_scilab::TextAdapter>()->getAdaptee();
+        default:
+            return nullptr;
+    }
+}
+
 types::InternalType* Adapters::allocate_view(ScicosID id, kind_t kind)
 {
     Controller controller;
index 4736daf..6cca132 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -114,17 +114,24 @@ public:
 template<typename Adaptor, typename Adaptee>
 class BaseAdapter : public types::UserType
 {
+    using BaseObject = org_scilab_modules_scicos::model::BaseObject;
 
 public:
-    BaseAdapter() : m_adaptee(nullptr) {};
+    explicit BaseAdapter() : m_adaptee(nullptr) {}
     BaseAdapter(const Controller& /*c*/, Adaptee* adaptee) : m_adaptee(adaptee) {}
     BaseAdapter(const BaseAdapter& adapter) : BaseAdapter(adapter, true) {}
     BaseAdapter(const BaseAdapter& adapter, bool cloneChildren) : m_adaptee(nullptr)
     {
-        Controller controller;
-        ScicosID id = controller.cloneObject(adapter.getAdaptee()->id(), cloneChildren, true);
-        m_adaptee = controller.getObject< Adaptee >(id);
+        if (adapter.getAdaptee() != nullptr)
+        {
+            Controller controller;
+
+            std::map<BaseObject*, BaseObject*> mapped;
+            BaseObject* clone = controller.cloneObject(mapped, adapter.getAdaptee(), cloneChildren, true);
+            m_adaptee = static_cast<Adaptee*>(clone);
+        }
     };
+    BaseAdapter(const BaseAdapter&& adapter) : BaseAdapter(Controller(), adapter.m_adaptee) {}
     ~BaseAdapter()
     {
         if (m_adaptee != nullptr)
@@ -149,7 +156,7 @@ public:
         typename property<Adaptor>::props_t_it found = std::lower_bound(property<Adaptor>::fields.begin(), property<Adaptor>::fields.end(), _sKey);
         if (found != property<Adaptor>::fields.end() && !(_sKey < found->name))
         {
-            return found->get(static_cast<Adaptor*>(this), controller);
+            return found->get(*static_cast<Adaptor*>(this), controller);
         }
         return 0;
     }
@@ -164,6 +171,16 @@ public:
         return false;
     }
 
+    void copyProperties(const Adaptor& adaptor, Controller controller = Controller())
+    {
+        for (const auto& p : property<Adaptor>::fields)
+        {
+            types::InternalType* pIT = p.get(adaptor, controller);
+            p.set(*static_cast<Adaptor*>(this), pIT, controller);
+            pIT->killMe();
+        }
+    }
+
     /**
      * property as TList accessors
      */
@@ -266,7 +283,7 @@ public:
         typename property<Adaptor>::props_t properties = property<Adaptor>::fields;
         std::sort(properties.begin(), properties.end(), property<Adaptor>::original_index_cmp);
 
-        types::Bool* ret = new types::Bool(1, 1 + properties.size());
+        types::Bool* ret = new types::Bool(1, 1 + (int)properties.size());
         ret->set(0, true); // First field is just the Adapter's name, which has been checked by the above conditions
 
         Controller controller;
@@ -286,6 +303,28 @@ public:
     }
 
     /**
+     * Return a default constructed Scilab value
+     */
+    template<typename T>
+    static types::InternalType* default_value()
+    {
+        T* o = new T();
+        o->IncreaseRef();
+        return o;
+    }
+
+    /**
+     * Increase reference count to store a Scilab value
+     */
+    template<typename T>
+    static T* reference_value(T* o)
+    {
+        o->IncreaseRef();
+        return o;
+    }
+
+
+    /**
      * @return the Adaptee
      */
     Adaptee* getAdaptee() const
@@ -315,6 +354,12 @@ private:
         return true;
     }
 
+    // sb.model.rpar.contrib will return a reference to contrib
+    bool isContainer() override final
+    {
+        return true;
+    }
+
     bool extract(const std::wstring & name, types::InternalType *& out) override final
     {
         typename property<Adaptor>::props_t_it found = std::lower_bound(property<Adaptor>::fields.begin(), property<Adaptor>::fields.end(), name);
@@ -396,17 +441,29 @@ private:
         {
             if ((*_pArgs)[i]->isString())
             {
+                Controller controller;
+
                 types::String* pStr = (*_pArgs)[i]->getAs<types::String>();
                 std::wstring name = pStr->get(0);
 
-                Controller controller;
+                Adaptor* work;
+                if (getAdaptee()->refCount() > 0)
+                {
+                    // clone()
+                    work = new Adaptor(*static_cast<Adaptor*>(this));
+                }
+                else
+                {
+                    work = static_cast<Adaptor*>(this);
+                }
+
                 typename property<Adaptor>::props_t_it found = std::lower_bound(property<Adaptor>::fields.begin(), property<Adaptor>::fields.end(), name);
                 if (found != property<Adaptor>::fields.end() && !(name < found->name))
                 {
-                    found->set(*static_cast<Adaptor*>(this), _pSource, controller);
+                    found->set(*work, _pSource, controller);
                 }
 
-                return this;
+                return work;
             }
             else
             {
index 00c8098..4d1e1a6 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -52,8 +52,7 @@ struct graphics
     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
     {
         GraphicsAdapter localAdaptor(controller, controller.referenceObject(adaptor.getAdaptee()));
-        types::InternalType* v = localAdaptor.getAsTList(new types::MList(), controller);
-        return v;
+        return localAdaptor.getAsTList(new types::MList(), controller);
     }
 
     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
@@ -67,116 +66,14 @@ struct model
 {
     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
     {
-        // If we are in a Superblock (has children) then reconstruct a DiagramAdapter, referencing the children
-        DiagramAdapter* subDiagram = nullptr;
-        std::vector<ScicosID> children;
-        controller.getObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, children);
-        if (!children.empty())
-        {
-            if (adaptor.getListObjects()->getSize() > 0)
-            {
-                Controller neededController = const_cast<Controller&>(controller);
-                ScicosID newDiag = neededController.createObject(DIAGRAM);
-                subDiagram = new DiagramAdapter(controller, static_cast<org_scilab_modules_scicos::model::Diagram*>(controller.getObject(newDiag)));
-                neededController.setObjectProperty(newDiag, DIAGRAM, CHILDREN, children);
-
-                for (const ScicosID id : children)
-                {
-                    if (id == ScicosID())
-                    {
-                        // Deleted object
-                    }
-                    else
-                    {
-                        auto o = controller.getObject(id);
-                        neededController.setObjectProperty(o->id(), o->kind(), PARENT_DIAGRAM, newDiag);
-                        neededController.referenceObject(o->id());
-                    }
-                }
-                subDiagram->setFrom(adaptor.getFrom());
-                subDiagram->setTo(adaptor.getTo());
-                subDiagram->setListObjects(adaptor.getListObjects());
-                subDiagram->setContribContent(adaptor.getContribContent());
-
-                std::vector<std::string> context;
-                controller.getObjectProperty(adaptor.getAdaptee()->id(), BLOCK, DIAGRAM_CONTEXT, context);
-                neededController.setObjectProperty(newDiag, DIAGRAM, DIAGRAM_CONTEXT, context);
-            }
-            else
-            {
-                // The children adapters list has not been set yet. Create it, update the adapter and return.
-                types::List* listObjects = new types::List();
-                std::vector<link_t> from;
-                std::vector<link_t> to;
-                for (const ScicosID id : children)
-                {
-                    if (id == ScicosID())
-                    {
-                        // Deleted object
-                    }
-                    else
-                    {
-                        auto o = controller.getObject(id);
-                        controller.referenceObject(o);
-
-                        switch (o->kind())
-                        {
-                            case ANNOTATION :
-                                listObjects->append(new TextAdapter(controller, static_cast<org_scilab_modules_scicos::model::Annotation*>(o)));
-                                break;
-                            case BLOCK :
-                            {
-                                BlockAdapter* block = new BlockAdapter(controller, static_cast<org_scilab_modules_scicos::model::Block*>(o));
-                                listObjects->append(block);
-                                break;
-                            }
-                            default : // LINK
-                                LinkAdapter* link = new LinkAdapter(controller, static_cast<org_scilab_modules_scicos::model::Link*>(o));
-                                from.push_back(link->getFrom());
-                                to.push_back(link->getTo());
-                                listObjects->append(link);
-                                break;
-                        }
-                    }
-                }
-                const_cast<BlockAdapter&>(adaptor).setFrom(from);
-                const_cast<BlockAdapter&>(adaptor).setTo(to);
-                const_cast<BlockAdapter&>(adaptor).setListObjects(listObjects);
-                return nullptr;
-            }
-        }
-
-        ModelAdapter localAdaptor(controller, controller.referenceObject(adaptor.getAdaptee()), subDiagram);
-        types::InternalType* mlist = localAdaptor.getAsTList(new types::MList(), controller)->getAs<types::MList>();
-
-        if (localAdaptor.getDiagram() != nullptr)
-        {
-            // To handle the copy constructor case calling model::set
-            const_cast<BlockAdapter&>(adaptor).setFrom(localAdaptor.getDiagram()->getFrom());
-            const_cast<BlockAdapter&>(adaptor).setTo(localAdaptor.getDiagram()->getTo());
-            const_cast<BlockAdapter&>(adaptor).setListObjects(localAdaptor.getDiagram()->getListObjects());
-            const_cast<BlockAdapter&>(adaptor).setContribContent(localAdaptor.getDiagram()->getContribContent());
-        }
-
-        return mlist;
+        ModelAdapter localAdaptor(controller, controller.referenceObject(adaptor.getAdaptee()));
+        return localAdaptor.getAsTList(new types::MList(), controller);
     }
 
     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        ModelAdapter localAdaptor(controller, controller.referenceObject(adaptor.getAdaptee()), nullptr);
-        if (!localAdaptor.setAsTList(v, controller))
-        {
-            return false;
-        }
-
-        if (localAdaptor.getDiagram() != nullptr)
-        {
-            adaptor.setFrom(localAdaptor.getDiagram()->getFrom());
-            adaptor.setTo(localAdaptor.getDiagram()->getTo());
-            adaptor.setListObjects(localAdaptor.getDiagram()->getListObjects());
-            adaptor.setContribContent(localAdaptor.getDiagram()->getContribContent());
-        }
-        return true;
+        ModelAdapter localAdaptor(controller, controller.referenceObject(adaptor.getAdaptee()));
+        return localAdaptor.setAsTList(v, controller);
     }
 };
 
@@ -229,17 +126,56 @@ struct doc
     }
 };
 
+link_indices_t getPortEnd(const Controller& controller, org_scilab_modules_scicos::model::Block* adaptee, portKind port)
+{
+    ScicosID parent;
+    kind_t parentKind = BLOCK;
+    controller.getObjectProperty(adaptee->id(), adaptee->kind(), PARENT_BLOCK, parent);
+    if (parent == ScicosID())
+    {
+        parentKind = DIAGRAM;
+        controller.getObjectProperty(adaptee->id(), adaptee->kind(), PARENT_DIAGRAM, parent);
+    }
+
+    // early return if this block is out of a hierarchy
+    if (parent == ScicosID())
+    {
+        return link_indices_t();
+    }
+
+    std::vector<ScicosID> children;
+    controller.getObjectProperty(parent, parentKind, CHILDREN, children);
+
+    std::vector<ScicosID> ports;
+    controller.getObjectProperty(parent, parentKind, property_from_port(port), children);
+
+    // store the index of the connected signal, 0 if absent
+    link_indices_t portIndices(ports.size());
+    for (size_t i = 0; i < ports.size(); ++i)
+    {
+        ScicosID signal;
+        controller.getObjectProperty(ports[i], PORT, CONNECTED_SIGNALS, signal);
+
+        if (signal != ScicosID())
+        {
+            auto it = std::find(children.begin(), children.end(), signal);
+            if (it != children.end())
+            {
+                portIndices[i] = (int)std::distance(children.begin(), it);
+            }
+        }
+    }
+
+    return portIndices;
+};
+
 } /* namespace */
 
 template<> property<BlockAdapter>::props_t property<BlockAdapter>::fields = property<BlockAdapter>::props_t();
 
 BlockAdapter::BlockAdapter(const Controller& c, org_scilab_modules_scicos::model::Block* adaptee) :
     BaseAdapter<BlockAdapter, org_scilab_modules_scicos::model::Block>(c, adaptee),
-    doc_content(nullptr),
-    from_vec(),
-    to_vec(),
-    list_objects(nullptr),
-    contrib_content(nullptr)
+    doc_content(default_value<types::List>())
 {
     if (property<BlockAdapter>::properties_have_not_been_set())
     {
@@ -249,60 +185,22 @@ BlockAdapter::BlockAdapter(const Controller& c, org_scilab_modules_scicos::model
         property<BlockAdapter>::add_property(L"gui", &gui::get, &gui::set);
         property<BlockAdapter>::add_property(L"doc", &doc::get, &doc::set);
     }
-
-    setListObjects(new types::List());
-    setContribContent(new types::List());
-    setDocContent(new types::List());
-
-    // model::get will set the adapter's content (listObjects, from_vec & to_vec) if needed
-    Controller controller;
-    model::get(*this, controller);
-
 }
 
 BlockAdapter::BlockAdapter(const BlockAdapter& adapter) :
-    BaseAdapter<BlockAdapter, org_scilab_modules_scicos::model::Block>(adapter, false),
-    doc_content(nullptr),
-    from_vec(),
-    to_vec(),
-    list_objects(nullptr),
-    contrib_content(nullptr)
+    BaseAdapter<BlockAdapter, org_scilab_modules_scicos::model::Block>(adapter),
+    doc_content(reference_value(adapter.doc_content))
 {
     Controller controller;
-
-    if (adapter.getListObjects()->getSize() > 0)
-    {
-        types::InternalType* model = model::get(adapter, controller);
-        model::set(*this, model, controller);
-        model->killMe();
-    }
-    else
-    {
-        setListObjects(new types::List());
-        setContribContent(new types::List());
-    }
-
-    setDocContent(adapter.getDocContent());
+    GraphicsAdapter::add_partial_links_information(controller, adapter.getAdaptee(), getAdaptee());
 }
 
 BlockAdapter::~BlockAdapter()
 {
-    // CHILDREN will be unreferenced on Controller::deleteObject
-
-    if (list_objects != nullptr)
-    {
-        list_objects->DecreaseRef();
-        list_objects->killMe();
-    }
-
-    if (contrib_content != nullptr)
-    {
-        contrib_content->DecreaseRef();
-        contrib_content->killMe();
-    }
-
     doc_content->DecreaseRef();
     doc_content->killMe();
+
+    GraphicsAdapter::remove_partial_links_information(getAdaptee());
 }
 
 std::wstring BlockAdapter::getTypeStr()
@@ -324,74 +222,12 @@ void BlockAdapter::setDocContent(types::InternalType* v)
 {
     types::InternalType* temp = doc_content;
 
-    v->IncreaseRef();
-    doc_content = v;
-
-    if (temp != nullptr)
-    {
-        temp->DecreaseRef();
-        temp->killMe();
-    }
-}
-
-std::vector<link_t> BlockAdapter::getFrom() const
-{
-    return from_vec;
-}
-
-void BlockAdapter::setFrom(const std::vector<link_t>& from)
-{
-    from_vec = from;
-}
-
-std::vector<link_t> BlockAdapter::getTo() const
-{
-    return to_vec;
-}
-
-void BlockAdapter::setTo(const std::vector<link_t>& to)
-{
-    to_vec = to;
-}
-
-types::List* BlockAdapter::getListObjects() const
-{
-    return list_objects;
-}
-
-void BlockAdapter::setListObjects(types::List* v)
-{
-    types::InternalType* temp = list_objects;
-
     // Do not check if v is nullptr on purpose ; it *should* not
     v->IncreaseRef();
-    list_objects = v;
-
-    if (temp != nullptr)
-    {
-        temp->DecreaseRef();
-        temp->killMe();
-    }
-}
-
-types::InternalType* BlockAdapter::getContribContent() const
-{
-    return contrib_content;
-}
-
-void BlockAdapter::setContribContent(types::InternalType* v)
-{
-    types::InternalType* temp = contrib_content;
-
-    // do not check if v is nullptr on purpose ; it *should* not
-    v->IncreaseRef();
-    contrib_content = v;
+    doc_content = v;
 
-    if (temp != nullptr)
-    {
-        temp->DecreaseRef();
-        temp->killMe();
-    }
+    temp->DecreaseRef();
+    temp->killMe();
 }
 
 } /* namespace view_scilab */
index 102f729..747e474 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
 #define BLOCKADAPTER_HXX_
 
 #include <string>
-#include <vector>
 
 #include "internal.hxx"
-#include "list.hxx"
 
 #include "BaseAdapter.hxx"
-#include "adapters_utilities.hxx"
 #include "model/Block.hxx"
 
 namespace org_scilab_modules_scicos
@@ -49,29 +46,8 @@ public:
     types::InternalType* getDocContent() const;
     void setDocContent(types::InternalType* v);
 
-    types::List* getListObjects() const;
-    void setListObjects(types::List* blocks);
-
-    std::vector<link_t> getFrom() const;
-    void setFrom(const std::vector<link_t>& from);
-    std::vector<link_t> getTo() const;
-    void setTo(const std::vector<link_t>& to);
-
-    types::InternalType* getContribContent() const;
-    void setContribContent(types::InternalType* contrib);
-
 private:
     types::InternalType* doc_content;
-
-    // The following content represents the child diagram (in 'model.rpar')
-
-    // Child links info
-    std::vector<link_t> from_vec;
-    std::vector<link_t> to_vec;
-    // Child elements info
-    types::List* list_objects;
-    // child diagram info
-    types::InternalType* contrib_content;
 };
 
 } /* namespace view_scilab */
index 7b7a2d4..7eefadd 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
index 4135d6e..efb02ca 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
index 5f966ab..1a2d5b0 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
  *
  */
 
+#include <bitset>
 #include <string>
 #include <vector>
 #include <sstream>
 #include <algorithm>
+#include <tuple>
 
 #include "types.hxx"
 #include "internal.hxx"
 #include "utilities.hxx"
 #include "adapters_utilities.hxx"
 #include "Controller.hxx"
-#include "DiagramAdapter.hxx"
 #include "controller_helpers.hxx"
 
 #include "view_scilab/Adapters.hxx"
+#include "DiagramAdapter.hxx"
 #include "ParamsAdapter.hxx"
 #include "BlockAdapter.hxx"
+#include "GraphicsAdapter.hxx"
 #include "LinkAdapter.hxx"
 #include "TextAdapter.hxx"
 #include "model/BaseObject.hxx"
+#include "model/Diagram.hxx"
+#include "model/Block.hxx"
 
 extern "C" {
 #include "sci_malloc.h"
@@ -54,9 +59,9 @@ namespace
 {
 
 const std::wstring Deleted (L"Deleted");
-const std::wstring TextSharedTypeStr (L"Text");
-const std::wstring BlockSharedTypeStr (L"Block");
-const std::wstring LinkSharedTypeStr (L"Link");
+const std::wstring Text (L"Text");
+const std::wstring Block (L"Block");
+const std::wstring Link (L"Link");
 
 struct props
 {
@@ -76,15 +81,14 @@ struct props
 
 struct objs
 {
-
     static types::InternalType* get(const DiagramAdapter& adaptor, const Controller& controller)
     {
-        model::Diagram* adaptee = adaptor.getAdaptee();
+        model::BaseObject* adaptee = adaptor.getAdaptee();
 
         std::vector<ScicosID> children;
-        controller.getObjectProperty(adaptee->id(), DIAGRAM, CHILDREN, children);
+        controller.getObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, children);
         types::List* ret = new types::List();
-        int link_i = 0;
+        // TODO: ret.reserve(children.size());
         for (int i = 0; i < static_cast<int>(children.size()); ++i)
         {
             if (children[i] == ScicosID())
@@ -96,117 +100,131 @@ struct objs
                 continue;
             }
 
-            auto o = controller.getObject(children[i]);
-            // Reference objects only if don't come from the copy constructor
-            if (adaptor.getListObjects() != nullptr)
-            {
-                controller.referenceObject(o);
-            }
-
+            model::BaseObject* o = controller.getObject(children[i]);
             switch (o->kind())
             {
                 case ANNOTATION :
-                    ret->append(new TextAdapter(controller, static_cast<model::Annotation*>(o)));
+                    ret->append(new TextAdapter(controller, controller.referenceObject<model::Annotation>(o)));
                     break;
                 case BLOCK :
+                    ret->append(new BlockAdapter(controller, controller.referenceObject<model::Block>(o)));
+                    break;
+                case LINK :
                 {
-                    BlockAdapter* block = new BlockAdapter(controller, static_cast<model::Block*>(o));
-                    if (adaptor.getListObjects() != nullptr)
-                    {
-                        BlockAdapter* oldBlock = adaptor.getListObjects()->get(i)->getAs<BlockAdapter>();
-                        block->setFrom(oldBlock->getFrom());
-                        block->setTo(oldBlock->getTo());
-                        block->setListObjects(oldBlock->getListObjects());
-                        block->setContribContent(oldBlock->getContribContent());
-                    }
-                    else
-                    {
-                        // The diagram doesn't have the list of his children adapters. Create it through BlockAdapter::model::get()
-                        std::wstring Model = L"model";
-                        property<BlockAdapter>::props_t_it found = std::lower_bound(property<BlockAdapter>::fields.begin(), property<BlockAdapter>::fields.end(), Model);
-                        if (found != property<BlockAdapter>::fields.end())
-                        {
-                            types::InternalType* subDiagram = found->get(*block, controller);
-
-                            // Now remove the references that this getter provoked, on the sub-diagram as well as in its sub-objects
-                            types::List* subList = block->getListObjects();
-                            for (int i = 0; i < subList->getSize(); ++i)
-                            {
-                                const Adapters::adapters_index_t adapter_index = Adapters::instance().lookup_by_typename(subList->get(i)->getShortTypeStr());
-                                switch (adapter_index)
-                                {
-                                    case Adapters::BLOCK_ADAPTER :
-                                    {
-                                        BlockAdapter* subBlock = subList->get(i)->getAs<BlockAdapter>();
-                                        const_cast<Controller&>(controller).deleteObject(subBlock->getAdaptee()->id());
-                                        break;
-                                    }
-                                    case Adapters::LINK_ADAPTER :
-                                    {
-                                        LinkAdapter* subLink = subList->get(i)->getAs<LinkAdapter>();
-                                        const_cast<Controller&>(controller).deleteObject(subLink->getAdaptee()->id());
-                                        break;
-                                    }
-                                    default : // TEXT_ADAPTER
-                                    {
-                                        TextAdapter* subText = subList->get(i)->getAs<TextAdapter>();
-                                        const_cast<Controller&>(controller).deleteObject(subText->getAdaptee()->id());
-                                    }
-                                }
-                            }
-                            subDiagram->killMe();
-                        }
-                    }
-                    ret->append(block);
+                    ret->append(new LinkAdapter(controller, controller.referenceObject<model::Link>(o)));
                     break;
                 }
-                default : // LINK
-                    LinkAdapter* link = new LinkAdapter(controller, static_cast<model::Link*>(o));
-                    if (adaptor.getListObjects() != nullptr)
-                    {
-                        link->setFrom(adaptor.getFrom()[link_i]);
-                        link->setTo(adaptor.getTo()[link_i]);
-                        link_i++;
-                    }
-                    ret->append(link);
+                default:
+                {
+                    types::MList* deleted = new types::MList();
+                    deleted->set(0, new types::String(Deleted.data()));
+                    ret->append(deleted);
                     break;
+                }
             }
         }
 
         return ret;
     }
 
+    template <kind_t kind, typename Adapter, typename Adaptee>
+    static Adapter* allocAndSet(types::MList* modelElement, Controller& controller)
+    {
+        ScicosID id = controller.createObject(kind);
+        Adaptee* localAdaptee = controller.getObject<Adaptee>(id);
+
+        Adapter* localAdaptor = new Adapter(controller, localAdaptee);
+        localAdaptor->setAsTList(modelElement, controller);
+
+        return localAdaptor;
+    };
+
     /**
-     * Clone the object if it is owned by something else
+     * Allocate a model element from its mlist() representation
+     *
+     * \param modelElement the mlist representation
+     * \param controller the shared controller
+     * \param o the model object
+     * \param a any adapter compatible with \o
      */
-    static types::InternalType* cloneIfNeeded(types::InternalType* v)
+    static void allocateAsMList(types::MList* modelElement, Controller& controller, model::BaseObject*& o, types::UserType*& a)
     {
-        if (v->getRef() == 0 || v->getRef() == 1)
+        types::String* header = modelElement->getFieldNames();
+
+        if (header->get(0) == Deleted)
         {
-            return v;
+            a = nullptr;
+            o = nullptr;
+        }
+        else if (header->get(0) == Text)
+        {
+            TextAdapter* adapter = allocAndSet<ANNOTATION, TextAdapter, model::Annotation>(modelElement, controller);
+            a = adapter;
+            o = adapter->getAdaptee();
+        }
+        else if (header->get(0) == Block)
+        {
+            BlockAdapter* adapter = allocAndSet<BLOCK, BlockAdapter, model::Block>(modelElement, controller);
+            a = adapter;
+            o = adapter->getAdaptee();
+        }
+        else if (header->get(0) == Link)
+        {
+            LinkAdapter* adapter = allocAndSet<LINK, LinkAdapter, model::Link>(modelElement, controller);
+            a = adapter;
+            o = adapter->getAdaptee();
+        }
+        else
+        {
+            a = nullptr;
+            o = nullptr;
         }
-
-        return v->clone();
     }
 
-    static std::vector<types::InternalType*> extractAndSort(types::List* v)
+    // Helper to manage updates
+    //  * set an adapter at a position
+    //  * clear an adapter (eg. remove object) if the value is nullptr
+    struct update_t
+    {
+        update_t(int index, model::BaseObject* adaptee, types::InternalType* adapter) :
+            index(index), adaptee(adaptee), adapter(adapter) {}
+
+        int index;
+        model::BaseObject* adaptee;
+        types::InternalType* adapter;
+    };
+
+    // Reference all the inserted children before processing them.
+    // This struct (cstr and dstr) will avoid early deletion
+    struct ChildrenToUpdateOwner
     {
-        std::vector<types::InternalType*> ret;
-        if (v == nullptr)
+        ChildrenToUpdateOwner(Controller& controller, const std::vector<update_t>& childrenToUpdate) :
+            controller(controller),
+            childrenToUpdate(childrenToUpdate)
         {
-            return ret;
+            std::for_each(childrenToUpdate.begin(), childrenToUpdate.end(), [&controller] (const update_t& u)
+            {
+                if (u.adaptee != nullptr)
+                {
+                    controller.referenceObject(u.adaptee->id());
+                }
+            });
         }
 
-        ret.reserve(v->getSize());
-        for (int i = 0; i < v->getSize(); ++i)
+        ~ChildrenToUpdateOwner()
         {
-            ret.push_back(v->get(i));
+            std::for_each(childrenToUpdate.begin(), childrenToUpdate.end(), [this] (const update_t& u)
+            {
+                if (u.adaptee != nullptr)
+                {
+                    controller.deleteObject(u.adaptee->id());
+                }
+            });
         }
 
-        std::sort(ret.begin(), ret.end());
-        return ret;
-    }
-
+        Controller& controller;
+        const std::vector<update_t>& childrenToUpdate;
+    };
 
     static bool set(DiagramAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
@@ -217,243 +235,157 @@ struct objs
             return false;
         }
 
-        /*
-         * Always deep clone both the list and children as the PARENT_DIAGRAM property will be updated
-         */
-        model::Diagram* adaptee = adaptor.getAdaptee();
-
+        model::BaseObject* adaptee = adaptor.getAdaptee();
         types::List* argumentList = v->getAs<types::List>();
-        types::List* list = new types::List();
 
-        std::vector<ScicosID> oldDiagramChildren;
-        controller.getObjectProperty(adaptee->id(), DIAGRAM, CHILDREN, oldDiagramChildren);
+        // retrieve the current children to update
+        std::vector<ScicosID> children;
+        controller.getObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, children);
 
         /*
-         * First pass on objects:
-         *  - store IDs if they exists and are valid ; ScicosID() otherwise
-         *  - store all the links to update link connections later
-         *  - store all the valid mlist content ('Text' content)
-         *  - store all the deleted mlist content ('Deleted' content)
+         * Fill a buffer of things to update
          */
 
-        std::vector<ScicosID> diagramChildren;
-        diagramChildren.reserve(argumentList->getSize());
-        std::vector<kind_t> diagramChildrenKind;
-        diagramChildrenKind.reserve(argumentList->getSize());
+        int maxLen = std::max(static_cast<int>(children.size()), argumentList->getSize());
+        children.resize(maxLen);
 
-        std::vector<LinkAdapter*> links;
-        std::vector<int> textAsMListIndices;
-        std::vector<int> deletedAsMListIndices;
+        // work buffer :
+        std::vector<update_t> childrenToUpdate;
 
+        // fill the work buffers accordingly to the arguments
         for (int i = 0; i < argumentList->getSize(); ++i)
         {
-            if (argumentList->get(i)->getType() == types::InternalType::ScilabUserType)
+            types::InternalType* pIT = argumentList->get(i);
+            switch (pIT->getType())
             {
-                const Adapters::adapters_index_t adapter_index = Adapters::instance().lookup_by_typename(argumentList->get(i)->getShortTypeStr());
-
-                ScicosID id;
-                kind_t kind;
-                types::InternalType* adapter;
-                switch (adapter_index)
+                case types::InternalType::ScilabUserType:
                 {
-                    case Adapters::BLOCK_ADAPTER:
+                    model::BaseObject* o = Adapters::instance().descriptor(pIT);
+                    if (o == nullptr)
                     {
-                        BlockAdapter* modelElement = cloneIfNeeded(argumentList->get(i))->getAs<BlockAdapter>();
-                        id = modelElement->getAdaptee()->id();
-                        kind = modelElement->getAdaptee()->kind();
-                        adapter = modelElement;
-                        break;
-                    }
-                    case Adapters::LINK_ADAPTER:
-                    {
-                        LinkAdapter* modelElement = cloneIfNeeded(argumentList->get(i))->getAs<LinkAdapter>();
-                        id = modelElement->getAdaptee()->id();
-                        kind = modelElement->getAdaptee()->kind();
-                        adapter = modelElement;
-
-                        // Do the linking in the next loop, in case the Link points to a Block that has not been added yet
-                        links.push_back(modelElement);
-                        break;
-                    }
-                    case Adapters::TEXT_ADAPTER:
-                    {
-                        TextAdapter* modelElement = cloneIfNeeded(argumentList->get(i))->getAs<TextAdapter>();
-                        id = modelElement->getAdaptee()->id();
-                        kind = modelElement->getAdaptee()->kind();
-                        adapter = modelElement;
-                        break;
-                    }
-                    default:
                         get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for element %d of field %s: unknown Scicos object.\n"), i + 1, "objs");
-                        list->killMe();
                         return false;
-                }
+                    }
 
-                diagramChildren.push_back(id);
-                diagramChildrenKind.push_back(kind);
-                list->set(i, adapter);
-            }
-            else if (argumentList->get(i)->getType() == types::InternalType::ScilabMList)
-            {
-                // Allow to pass mlists to 'objs', representing 'Deleted' or 'Text' objects
-                types::MList* modelElement = argumentList->get(i)->getAs<types::MList>();
-                types::String* header = modelElement->getFieldNames();
+                    // clone if the adapter is used somewhere else (eg. not owned by the list)
+                    if (pIT->getRef() > 1 || o->refCount() > 0) // over-clone some elements but PASS the tests
+                        //                     if (pIT->getRef() > 1) // TODO: investigate why this expression is not enough
+                    {
+                        types::InternalType* clonedAdapter = pIT->clone();
+                        model::BaseObject* cloned = Adapters::instance().descriptor(clonedAdapter);
 
-                if (header->get(0) == Deleted)
-                {
-                    deletedAsMListIndices.push_back(i);
-                    // will be filled later
-                    diagramChildren.push_back(ScicosID());
-                    diagramChildrenKind.push_back(ANNOTATION);
-                }
-                else if (header->get(0) == TextSharedTypeStr)
-                {
-                    textAsMListIndices.push_back(i);
-                    // will be filled later
-                    diagramChildren.push_back(ScicosID());
-                    diagramChildrenKind.push_back(ANNOTATION);
-                }
-                else if (header->get(0) == BlockSharedTypeStr)
-                {
-                    ScicosID localAdaptee = controller.createObject(BLOCK);
-                    BlockAdapter* localAdaptor = new BlockAdapter(controller, controller.getObject<model::Block>(localAdaptee));
-                    if (!localAdaptor->setAsTList(modelElement, controller))
+                        LinkAdapter::add_partial_links_information(controller, o, cloned);
+                        GraphicsAdapter::add_partial_links_information(controller, o, cloned);
+                        childrenToUpdate.emplace_back(i, cloned, clonedAdapter);
+                    }
+                    else
                     {
-                        list->killMe();
-                        return false;
+                        pIT->IncreaseRef();
+                        childrenToUpdate.emplace_back(i, o, pIT);
                     }
-
-                    diagramChildren.push_back(localAdaptee);
-                    list->set(i, localAdaptor);
+                    break;
                 }
-                else if (header->get(0) == LinkSharedTypeStr)
-                {
-                    ScicosID localAdaptee = controller.createObject(LINK);
-                    LinkAdapter* localAdaptor = new LinkAdapter(controller, controller.getObject<model::Link>(localAdaptee));
-                    if (!localAdaptor->setAsTList(modelElement, controller))
+                case types::InternalType::ScilabMList:
+                    model::BaseObject* o;
+                    types::UserType* a;
+                    allocateAsMList(pIT->getAs<types::MList>(), controller, o, a);
+                    childrenToUpdate.emplace_back(i, o, a);
+                    break;
+                case types::InternalType::ScilabList:
+                    // clear on list()
+                    if (pIT->getAs<types::List>()->getSize() != 0)
                     {
-                        list->killMe();
+                        get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for element %d of field %s: unknown Scicos object.\n"), i + 1, "objs");
                         return false;
                     }
-
-                    diagramChildren.push_back(localAdaptee);
-                    list->set(i, localAdaptor);
-
-                    // Do the linking in the next loop, in case the Link points to a Block that has not been added yet
-                    links.push_back(localAdaptor);
-                }
-                else
-                {
-                    get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for element %d of field %s: unknown Scicos object.\n"), i + 1, "objs");
-                    list->killMe();
-                    return false;
-                }
-            }
-            else if (argumentList->get(i)->getType() == types::InternalType::ScilabList)
-            {
-                // Allow to pass empty lists to 'objs', representing deleted Blocks
-                types::List* modelElement = argumentList->get(i)->getAs<types::List>();
-                if (modelElement->getSize() != 0)
-                {
+                    childrenToUpdate.emplace_back(i, nullptr, nullptr);
+                    break;
+                default:
                     get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for element %d of field %s: unknown Scicos object.\n"), i + 1, "objs");
-                    list->killMe();
                     return false;
-                }
-
-                deletedAsMListIndices.push_back(i);
-                // Mark deleted objects with value '0'
-                diagramChildren.push_back(ScicosID());
-                diagramChildrenKind.push_back(ANNOTATION);
-            }
-            else
-            {
-                get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for element %d of field %s: unknown Scicos object.\n"), i + 1, "objs");
-                list->killMe();
-                return false;
             }
         }
 
-        /*
-         * Create all Annotation, decoding mlist content
-         */
-        for (const auto index : textAsMListIndices)
+        // clear trailing objects
+        for (int i = argumentList->getSize() ; i < static_cast<int>(children.size()); ++i)
         {
-            ScicosID localAdaptee = controller.createObject(ANNOTATION);
-            TextAdapter* localAdaptor = new TextAdapter(controller, controller.getObject<model::Annotation>(localAdaptee));
-            if (!localAdaptor->setAsTList(argumentList->get(index), controller))
-            {
-                // Do not return there ; the annotation will be empty
-            }
-
-            diagramChildren[index] = localAdaptee;
+            childrenToUpdate.emplace_back(i, nullptr, nullptr);
         }
 
         /*
-         * Recreate 'Deleted' mlist if needed
+         * Update parent / children
          */
-        for (const auto index : deletedAsMListIndices)
-        {
-            types::MList* deleted = new types::MList();
-            deleted->set(0, new types::String(Deleted.data()));
-
-            list->set(index, deleted);
-        }
+        ChildrenToUpdateOwner tempOwning(controller, childrenToUpdate);
 
-        /*
-         * Set the parent diagram of all the blocks
-         */
-        controller.setObjectProperty(adaptee->id(), DIAGRAM, CHILDREN, diagramChildren);
+        // Process the children / parent relationship
+        ScicosID parentDiagram;
+        controller.getObjectProperty(adaptee->id(), adaptee->kind(), PARENT_DIAGRAM, parentDiagram);
+        for (const auto& update : childrenToUpdate)
         {
-            std::sort(oldDiagramChildren.begin(), oldDiagramChildren.end());
-            for (const ScicosID id : diagramChildren)
+            // reference / derefence the content
+            if (update.adapter == nullptr)
             {
-                if (id != ScicosID() && !std::binary_search(oldDiagramChildren.begin(), oldDiagramChildren.end(), id))
-                {
-                    auto o = controller.getObject(id);
-                    controller.setObjectProperty(o->id(), o->kind(), PARENT_DIAGRAM, adaptee->id());
-
-                    controller.referenceObject(id);
-                }
+                controller.deleteObject(children[update.index]);
+            }
+            else
+            {
+                controller.referenceObject(update.adaptee->id());
+                controller.deleteObject(children[update.index]);
             }
 
-            std::sort(diagramChildren.begin(), diagramChildren.end());
-            for (const ScicosID id : oldDiagramChildren)
+            // manage insertion and field update
+            if (update.adapter == nullptr)
             {
-                if (id != ScicosID() && !std::binary_search(diagramChildren.begin(), diagramChildren.end(), id))
-                {
-                    auto o = controller.getObject(id);
-                    controller.setObjectProperty(o->id(), o->kind(), PARENT_DIAGRAM, ScicosID());
+                children[update.index] = ScicosID();
+            }
+            else
+            {
+                children[update.index] = update.adaptee->id();
 
-                    controller.deleteObject(id);
+                if (adaptee->kind() == BLOCK)
+                {
+                    controller.setObjectProperty(update.adaptee->id(), update.adaptee->kind(), PARENT_DIAGRAM, parentDiagram);
+                    controller.setObjectProperty(update.adaptee->id(), update.adaptee->kind(), PARENT_BLOCK, adaptee->id());
+                }
+                else
+                {
+                    controller.setObjectProperty(update.adaptee->id(), update.adaptee->kind(), PARENT_DIAGRAM, adaptee->id());
+                    controller.setObjectProperty(update.adaptee->id(), update.adaptee->kind(), PARENT_BLOCK, ScicosID());
                 }
             }
         }
 
         /*
-         * Store the children in the local adaptor, avoiding the deletion of argument
-         */
-        v->IncreaseRef();
-        adaptor.setListObjects(list);
-
-        /*
-         * Re-sync the partial link information
+         * Update partial linking information (links then ports)
          */
-        std::vector<link_t> from_content (links.size());
-        std::vector<link_t> to_content (links.size());
-        // Do the linking at model-level
-        for (int i = 0; i < static_cast<int>(links.size()); ++i)
+        for (const auto& update : childrenToUpdate)
         {
-            // Trigger 'from' and 'to' properties
-            from_content[i] = links[i]->getFrom();
-            links[i]->setFromInModel(from_content[i], controller);
+            if (update.adaptee != nullptr && update.adaptee->kind() == LINK)
+            {
+                LinkAdapter::relink(controller, update.adaptee, children);
+            }
+        }
+        for (const auto& update : childrenToUpdate)
+        {
+            if (update.adaptee != nullptr && update.adaptee->kind() == BLOCK)
+            {
+                GraphicsAdapter::relink(controller, update.adaptee, children);
+            }
+        }
 
-            to_content[i] = links[i]->getTo();
-            links[i]->setToInModel(to_content[i], controller);
+        // unref the Adapters as the ownership has been transfered to the Model
+        for (const auto& update : childrenToUpdate)
+        {
+            if (update.adapter != nullptr)
+            {
+                update.adapter->DecreaseRef();
+                update.adapter->killMe();
+            }
         }
-        adaptor.setFrom(from_content);
-        adaptor.setTo(to_content);
 
-        v->DecreaseRef();
+        // set the children after update
+        controller.setObjectProperty(adaptee->id(), adaptee->kind(), CHILDREN, children);
+
         return true;
     }
 };
@@ -463,10 +395,20 @@ struct version
 
     static types::InternalType* get(const DiagramAdapter& adaptor, const Controller& controller)
     {
-        model::Diagram* adaptee = adaptor.getAdaptee();
-
         std::string version;
-        controller.getObjectProperty(adaptee->id(), DIAGRAM, VERSION_NUMBER, version);
+        if (adaptor.getAdaptee()->kind() == BLOCK)
+        {
+            model::Block* adaptee = static_cast<model::Block*>(adaptor.getAdaptee());
+
+            ScicosID parentDiagram;
+            controller.getObjectProperty(adaptee->id(), adaptee->kind(), PARENT_DIAGRAM, parentDiagram);
+            controller.getObjectProperty(parentDiagram, DIAGRAM, VERSION_NUMBER, version);
+        }
+        else
+        {
+            model::Diagram* adaptee = static_cast<model::Diagram*>(adaptor.getAdaptee());
+            controller.getObjectProperty(adaptee->id(), adaptee->kind(), VERSION_NUMBER, version);
+        }
 
         return new types::String(version.data());
     }
@@ -482,13 +424,18 @@ struct version
                 return false;
             }
 
-            model::Diagram* adaptee = adaptor.getAdaptee();
+            if (adaptor.getAdaptee()->kind() != DIAGRAM)
+            {
+                // version field is not present on the model for non-diagram ; let's pass it !
+                return true;
+            }
+            model::Diagram* adaptee = static_cast<model::Diagram*>(adaptor.getAdaptee());
 
             char* c_str = wide_string_to_UTF8(current->get(0));
             std::string version (c_str);
             FREE(c_str);
 
-            controller.setObjectProperty(adaptee->id(), DIAGRAM, VERSION_NUMBER, version);
+            controller.setObjectProperty(adaptee->id(), adaptee->kind(), VERSION_NUMBER, version);
             return true;
         }
         else if (v->getType() == types::InternalType::ScilabDouble)
@@ -500,10 +447,15 @@ struct version
                 return false;
             }
 
-            model::Diagram* adaptee = adaptor.getAdaptee();
+            if (adaptor.getAdaptee()->kind() != DIAGRAM)
+            {
+                get_or_allocate_logger()->log(LOG_ERROR, _("\"%s\" is a read-only field.\n"), "version");
+                return false;
+            }
+            model::Diagram* adaptee = static_cast<model::Diagram*>(adaptor.getAdaptee());
 
             std::string version;
-            controller.setObjectProperty(adaptee->id(), DIAGRAM, VERSION_NUMBER, version);
+            controller.setObjectProperty(adaptee->id(), adaptee->kind(), VERSION_NUMBER, version);
             return true;
         }
 
@@ -522,7 +474,7 @@ struct contrib
 
     static bool set(DiagramAdapter& adaptor, types::InternalType* v, Controller& /*controller*/)
     {
-        adaptor.setContribContent(v->clone());
+        adaptor.setContribContent(v);
         return true;
     }
 };
@@ -531,12 +483,9 @@ struct contrib
 
 template<> property<DiagramAdapter>::props_t property<DiagramAdapter>::fields = property<DiagramAdapter>::props_t();
 
-DiagramAdapter::DiagramAdapter(const Controller& c, org_scilab_modules_scicos::model::Diagram* adaptee) :
-    BaseAdapter<DiagramAdapter, org_scilab_modules_scicos::model::Diagram>(c, adaptee),
-    from_vec(),
-    to_vec(),
-    list_objects(nullptr),
-    contrib_content(nullptr)
+DiagramAdapter::DiagramAdapter(const Controller& c, org_scilab_modules_scicos::model::BaseObject* adaptee) :
+    BaseAdapter<DiagramAdapter, org_scilab_modules_scicos::model::BaseObject>(c, adaptee),
+    contrib_content(default_value<types::List>())
 {
     if (property<DiagramAdapter>::properties_have_not_been_set())
     {
@@ -546,45 +495,17 @@ DiagramAdapter::DiagramAdapter(const Controller& c, org_scilab_modules_scicos::m
         property<DiagramAdapter>::add_property(L"version", &version::get, &version::set);
         property<DiagramAdapter>::add_property(L"contrib", &contrib::get, &contrib::set);
     }
-
-    // objs::set will set the adapter's content (listObjects, from_vec & to_vec) if needed
-    Controller controller;
-    types::List* listObjects = objs::get(*this, controller)->getAs<types::List>();
-    if (listObjects->getSize() > 0)
-    {
-        objs::set(*this, listObjects, controller);
-    }
-
-    setContribContent(new types::List());
 }
 
 DiagramAdapter::DiagramAdapter(const DiagramAdapter& adapter) :
-    BaseAdapter<DiagramAdapter, org_scilab_modules_scicos::model::Diagram>(adapter, true),
-    from_vec(),
-    to_vec(),
-    list_objects(nullptr),
-    contrib_content(nullptr)
+    BaseAdapter<DiagramAdapter, org_scilab_modules_scicos::model::BaseObject>(adapter),
+    contrib_content(reference_value(adapter.contrib_content))
 {
-    Controller controller;
-
-    // set the list and perform from / to links update
-    objs::set(*this, objs::get(*this, controller)->getAs<types::List>(), controller);
-
-    setFrom(adapter.getFrom());
-    setTo(adapter.getTo());
-    setContribContent(adapter.getContribContent());
+    contrib_content->IncreaseRef();
 }
 
 DiagramAdapter::~DiagramAdapter()
 {
-    // CHILDREN will be unreferenced on Controller::deleteObject
-
-    if (list_objects != nullptr)
-    {
-        list_objects->DecreaseRef();
-        list_objects->killMe();
-    }
-
     contrib_content->DecreaseRef();
     contrib_content->killMe();
 }
@@ -598,46 +519,6 @@ std::wstring DiagramAdapter::getShortTypeStr()
     return getSharedTypeStr();
 }
 
-types::List* DiagramAdapter::getListObjects() const
-{
-    return list_objects;
-}
-
-void DiagramAdapter::setListObjects(types::List* v)
-{
-    types::InternalType* temp = list_objects;
-
-    // Do not check if v is nullptr on purpose ; it *should* not
-    v->IncreaseRef();
-    list_objects = v;
-
-    if (temp != nullptr)
-    {
-        temp->DecreaseRef();
-        temp->killMe();
-    }
-}
-
-std::vector<link_t> DiagramAdapter::getFrom() const
-{
-    return from_vec;
-}
-
-void DiagramAdapter::setFrom(const std::vector<link_t>& from)
-{
-    from_vec = from;
-}
-
-std::vector<link_t> DiagramAdapter::getTo() const
-{
-    return to_vec;
-}
-
-void DiagramAdapter::setTo(const std::vector<link_t>& to)
-{
-    to_vec = to;
-}
-
 types::InternalType* DiagramAdapter::getContribContent() const
 {
     return contrib_content;
@@ -645,17 +526,15 @@ types::InternalType* DiagramAdapter::getContribContent() const
 
 void DiagramAdapter::setContribContent(types::InternalType* v)
 {
+    // v and contrib_content should not be nullptr
+
     types::InternalType* temp = contrib_content;
 
-    // do not check if v is nullptr on purpose ; it *should* not
     v->IncreaseRef();
     contrib_content = v;
 
-    if (temp != nullptr)
-    {
-        temp->DecreaseRef();
-        temp->killMe();
-    }
+    temp->DecreaseRef();
+    temp->killMe();
 }
 
 } /* namespace view_scilab */
index 48042cd..8797ef5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
 #define DIAGRAMADAPTER_HXX_
 
 #include <string>
-#include <vector>
 
 #include "internal.hxx"
-#include "list.hxx"
 
-#include "adapters_utilities.hxx"
 #include "BaseAdapter.hxx"
-#include "model/Diagram.hxx"
 
 namespace org_scilab_modules_scicos
 {
 namespace view_scilab
 {
 
-class DiagramAdapter : public BaseAdapter<DiagramAdapter, org_scilab_modules_scicos::model::Diagram>
+class DiagramAdapter : public BaseAdapter<DiagramAdapter, org_scilab_modules_scicos::model::BaseObject>
 {
 public:
-    DiagramAdapter(const Controller& c, org_scilab_modules_scicos::model::Diagram* adaptee);
+    DiagramAdapter(const Controller& c, org_scilab_modules_scicos::model::BaseObject* adaptee);
     DiagramAdapter(const DiagramAdapter& adapter);
     ~DiagramAdapter();
 
@@ -46,25 +42,10 @@ public:
     std::wstring getTypeStr();
     std::wstring getShortTypeStr();
 
-    types::List* getListObjects() const;
-    void setListObjects(types::List* v);
-
-    std::vector<link_t> getFrom() const;
-    void setFrom(const std::vector<link_t>& from);
-    std::vector<link_t> getTo() const;
-    void setTo(const std::vector<link_t>& to);
-
     types::InternalType* getContribContent() const;
     void setContribContent(types::InternalType* v);
 
 private:
-    // Infos for the child links
-    std::vector<link_t> from_vec;
-    std::vector<link_t> to_vec;
-
-    // Infos for the child elements
-    types::List* list_objects;
-
     // User-defined contrib
     types::InternalType* contrib_content;
 };
index 15c8ef2..dbcc279 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -19,6 +19,8 @@
 #include <vector>
 #include <iostream>
 #include <iomanip>
+#include <algorithm>
+#include <functional>
 
 #include "list.hxx"
 #include "tlist.hxx"
@@ -59,6 +61,12 @@ const std::wstring pprop (L"pprop");
 const std::wstring nameF (L"nameF");
 const std::wstring funtxt (L"funtxt");
 
+// shared informations for relinking across adapters hierarchy
+std::map<ScicosID, std::vector<int> > partial_pin;
+std::map<ScicosID, std::vector<int> > partial_pout;
+std::map<ScicosID, std::vector<int> > partial_pein;
+std::map<ScicosID, std::vector<int> > partial_peout;
+
 struct orig
 {
 
@@ -191,17 +199,182 @@ struct exprs
     }
 };
 
+std::vector<int> cached_ports_init(std::map<ScicosID, std::vector<int> >& cache, const model::Block* adaptee, const object_properties_t port_kind, const Controller& controller)
+{
+    auto it = cache.find(adaptee->id());
+    if (it != cache.end())
+    {
+        // if already present, do not refresh it !
+        return it->second;
+    }
+
+    std::vector<ScicosID> ids;
+    controller.getObjectProperty(adaptee->id(), BLOCK, port_kind, ids);
+
+    std::vector<ScicosID> children;
+    ScicosID parentBlock;
+    controller.getObjectProperty(adaptee->id(), BLOCK, PARENT_BLOCK, parentBlock);
+    if (parentBlock == ScicosID())
+    {
+        // Adding to a diagram
+        ScicosID parentDiagram;
+        controller.getObjectProperty(adaptee->id(), BLOCK, PARENT_DIAGRAM, parentDiagram);
+
+        controller.getObjectProperty(parentDiagram, DIAGRAM, CHILDREN, children);
+    }
+    else
+    {
+        // Adding to a superblock
+        controller.getObjectProperty(parentBlock, BLOCK, CHILDREN, children);
+    }
+
+    std::vector<int> ret(ids.size());
+    // foreach ports, resolve it or discard
+    int i = 0;
+    for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
+    {
+        ScicosID id;
+        controller.getObjectProperty(*it, PORT, CONNECTED_SIGNALS, id);
+
+        if (id == ScicosID())
+        {
+            // Unconnected port, no need to search in 'children'
+            ret[i] = 0;
+        }
+        else
+        {
+            std::vector<ScicosID>::iterator found = std::find(children.begin(), children.end(), id);
+            if (found != children.end())
+            {
+                ret[i] = static_cast<int>(std::distance(children.begin(), found)) + 1;
+            }
+            else
+            {
+                // connected link not found ; discard it !
+                ret[i] = 0;
+            }
+        }
+    }
+
+    cache.insert({adaptee->id(), ret});
+    return ret;
+}
+
+types::InternalType* cached_ports_get(std::map<ScicosID, std::vector<int> >& cache, const GraphicsAdapter& adaptor, const object_properties_t port_kind, const Controller& controller)
+{
+    auto it = cache.find(adaptor.getAdaptee()->id());
+    if (it == cache.end())
+    {
+        return get_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, port_kind, controller);
+    }
+
+    std::vector<int> const& ports = it->second;
+
+    double* data;
+    types::Double* ret = new types::Double(static_cast<int>(ports.size()), 1, &data);
+
+#ifdef _MSC_VER
+    std::transform(ports.begin(), ports.end(), stdext::checked_array_iterator<double*>(data, ports.size()), [](int p)
+    {
+        return p;
+    });
+#else
+    std::transform(ports.begin(), ports.end(), data, [](int p)
+    {
+        return p;
+    });
+#endif
+
+    return ret;
+}
+bool cached_ports_set(std::map<ScicosID, std::vector<int> >& cache, GraphicsAdapter& adaptor, const object_properties_t port_kind, Controller& controller, types::InternalType* v)
+{
+    auto it = cache.find(adaptor.getAdaptee()->id());
+    if (it == cache.end())
+    {
+        return update_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, port_kind, controller, v);
+    }
+
+    if (v->getType() != types::InternalType::ScilabDouble)
+    {
+        return false;
+    }
+    types::Double* value = v->getAs<types::Double>();
+
+    // store the updated value locally
+    {
+        std::vector<int>& ports = it->second;
+
+        ports.resize(value->getSize());
+        for (int i = 0; i < value->getSize(); ++i)
+        {
+            ports[i] = static_cast<int>(value->get(i));
+        }
+    }
+
+    // enforce a the same number of port on the Model
+    {
+        const std::vector<int>& ports = it->second;
+
+        std::vector<ScicosID> objects;
+        controller.getObjectProperty(adaptor.getAdaptee()->id(), BLOCK, port_kind, objects);
+
+        if (ports.size() < objects.size())
+        {
+            // remove existing ports
+            for (size_t i = ports.size(); i < objects.size(); ++i)
+            {
+                ScicosID p = objects[i];
+
+                ScicosID signal;
+                controller.getObjectProperty(p, PORT, CONNECTED_SIGNALS, signal);
+                if (signal != ScicosID())
+                {
+                    ScicosID opposite;
+                    controller.getObjectProperty(signal, LINK, DESTINATION_PORT, opposite);
+                    if (opposite == p)
+                    {
+                        controller.setObjectProperty(signal, LINK, DESTINATION_PORT, ScicosID());
+                    }
+                    controller.getObjectProperty(signal, LINK, SOURCE_PORT, opposite);
+                    if (opposite == p)
+                    {
+                        controller.setObjectProperty(signal, LINK, SOURCE_PORT, ScicosID());
+                    }
+                }
+                controller.deleteObject(p);
+            }
+            objects.resize(ports.size());
+        }
+        else
+        {
+            // add missing ports
+            for (size_t i = objects.size(); i < ports.size(); ++i)
+            {
+                ScicosID p = controller.createObject(PORT);
+
+                controller.setObjectProperty(p, PORT, SOURCE_BLOCK, adaptor.getAdaptee()->id());
+                controller.setObjectProperty(p, PORT, PORT_KIND, port_from_property(port_kind));
+
+                objects.push_back(p);
+            }
+        }
+        controller.setObjectProperty(adaptor.getAdaptee()->id(), BLOCK, port_kind, objects);
+    }
+    return true;
+}
+
 struct pin
 {
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, INPUTS, controller);
+        return cached_ports_get(partial_pin, adaptor, INPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return update_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, INPUTS, controller, v);
+        return cached_ports_set(partial_pin, adaptor, INPUTS, controller, v);
     }
 };
 
@@ -210,12 +383,12 @@ struct pout
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, OUTPUTS, controller);
+        return cached_ports_get(partial_pout, adaptor, OUTPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return update_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, OUTPUTS, controller, v);
+        return cached_ports_set(partial_pout, adaptor, OUTPUTS, controller, v);
     }
 };
 
@@ -224,12 +397,12 @@ struct pein
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, EVENT_INPUTS, controller);
+        return cached_ports_get(partial_pein, adaptor, EVENT_INPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return update_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, EVENT_INPUTS, controller, v);
+        return cached_ports_set(partial_pein, adaptor, EVENT_INPUTS, controller, v);
     }
 };
 
@@ -238,12 +411,12 @@ struct peout
 
     static types::InternalType* get(const GraphicsAdapter& adaptor, const Controller& controller)
     {
-        return get_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, EVENT_OUTPUTS, controller);
+        return cached_ports_get(partial_peout, adaptor, EVENT_OUTPUTS, controller);
     }
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return update_ports_property<GraphicsAdapter, CONNECTED_SIGNALS>(adaptor, EVENT_OUTPUTS, controller, v);
+        return cached_ports_set(partial_peout, adaptor, EVENT_OUTPUTS, controller, v);
     }
 };
 
@@ -257,7 +430,7 @@ struct gr_i
 
     static bool set(GraphicsAdapter& adaptor, types::InternalType* v, Controller& /*controller*/)
     {
-        adaptor.setGrIContent(v->clone());
+        adaptor.setGrIContent(v);
         return true;
     }
 };
@@ -468,22 +641,36 @@ static void initialize_fields()
 
 GraphicsAdapter::GraphicsAdapter() :
     BaseAdapter<GraphicsAdapter, org_scilab_modules_scicos::model::Block>(),
-    gr_i_content(types::Double::Empty())
+    gr_i_content(reference_value(types::Double::Empty()))
 {
     initialize_fields();
 }
 
 GraphicsAdapter::GraphicsAdapter(const Controller& c, model::Block* adaptee) :
     BaseAdapter<GraphicsAdapter, org_scilab_modules_scicos::model::Block>(c, adaptee),
-    gr_i_content(types::Double::Empty())
+    gr_i_content(reference_value(types::Double::Empty()))
 {
     initialize_fields();
+
+    Controller controller;
+    cached_ports_init(partial_pin, adaptee, INPUTS, controller);
+    cached_ports_init(partial_pout, adaptee, OUTPUTS, controller);
+    cached_ports_init(partial_pein, adaptee, EVENT_INPUTS, controller);
+    cached_ports_init(partial_peout, adaptee, EVENT_OUTPUTS, controller);
 }
 
 GraphicsAdapter::~GraphicsAdapter()
 {
     gr_i_content->DecreaseRef();
     gr_i_content->killMe();
+
+    if (getAdaptee() != nullptr && getAdaptee()->refCount() == 0)
+    {
+        partial_pin.erase(getAdaptee()->id());
+        partial_pout.erase(getAdaptee()->id());
+        partial_pein.erase(getAdaptee()->id());
+        partial_peout.erase(getAdaptee()->id());
+    }
 }
 
 std::wstring GraphicsAdapter::getTypeStr()
@@ -498,17 +685,117 @@ std::wstring GraphicsAdapter::getShortTypeStr()
 
 types::InternalType* GraphicsAdapter::getGrIContent() const
 {
-    gr_i_content->IncreaseRef();
     return gr_i_content;
 }
 
 void GraphicsAdapter::setGrIContent(types::InternalType* v)
 {
-    gr_i_content->DecreaseRef();
-    gr_i_content->killMe();
+    types::InternalType* temp = gr_i_content;
 
     v->IncreaseRef();
     gr_i_content = v;
+
+    temp->DecreaseRef();
+    temp->killMe();
+}
+
+static void relink_cached(Controller& controller, model::BaseObject* adaptee, const std::vector<ScicosID>& children, std::map<ScicosID, std::vector<int> >& cache, object_properties_t p)
+{
+    auto it = cache.find(adaptee->id());
+    if (it == cache.end())
+    {
+        // unable to relink as there is no information to do so
+        return;
+    }
+    std::vector<int>& cached_information = it->second;
+
+    std::vector<ScicosID> ports;
+    controller.getObjectProperty(adaptee->id(), BLOCK, p, ports);
+
+    if (cached_information.size() != ports.size())
+    {
+        // defensive programming: unable to relink as something goes wrong on the adapters
+        return;
+    }
+
+    bool isConnected = true;
+    for (size_t i = 0; i < cached_information.size(); ++i)
+    {
+        ScicosID connectedSignal;
+        controller.getObjectProperty(ports[i], PORT, CONNECTED_SIGNALS, connectedSignal);
+
+        if (connectedSignal != ScicosID())
+        {
+            cached_information[i] = (int)std::distance(children.begin(), std::find(children.begin(), children.end(), connectedSignal));
+        }
+        else
+        {
+            isConnected = false;
+        }
+    }
+
+    if (isConnected)
+    {
+        cache.erase(it);
+    }
+}
+
+void GraphicsAdapter::relink(Controller& controller, model::BaseObject* adaptee, const std::vector<ScicosID>& children)
+{
+    relink_cached(controller, adaptee, children, partial_pin, INPUTS);
+    relink_cached(controller, adaptee, children, partial_pout, OUTPUTS);
+    relink_cached(controller, adaptee, children, partial_pein, EVENT_INPUTS);
+    relink_cached(controller, adaptee, children, partial_peout, EVENT_OUTPUTS);
+}
+
+void copyOnClone(model::BaseObject* original, model::BaseObject* cloned, std::map<ScicosID, std::vector<int> >& cache)
+{
+
+    auto it = cache.find(original->id());
+    if (it != cache.end())
+        cache.insert({cloned->id(), it->second});
+}
+
+void GraphicsAdapter::add_partial_links_information(Controller& controller, model::BaseObject* original, model::BaseObject* cloned)
+{
+    if (original->kind() == BLOCK)
+    {
+        // add the from / to information if applicable
+        copyOnClone(original, cloned, partial_pin);
+        copyOnClone(original, cloned, partial_pout);
+        copyOnClone(original, cloned, partial_pein);
+        copyOnClone(original, cloned, partial_peout);
+    }
+
+    switch (original->kind())
+    {
+        // handle recursion
+        case DIAGRAM:
+        case BLOCK:
+        {
+            std::vector<ScicosID> originalChildren;
+            controller.getObjectProperty(original->id(), original->kind(), CHILDREN, originalChildren);
+            std::vector<ScicosID> clonedChildren;
+            controller.getObjectProperty(cloned->id(), cloned->kind(), CHILDREN, clonedChildren);
+
+            for (size_t i = 0; i < originalChildren.size(); ++i)
+            {
+                add_partial_links_information(controller, controller.getObject(originalChildren[i]), controller.getObject(clonedChildren[i]));
+            }
+            break;
+        }
+
+        default:
+            break;
+    }
+}
+
+void GraphicsAdapter::remove_partial_links_information(model::BaseObject* o)
+{
+    partial_pin.erase(o->id());
+    partial_pout.erase(o->id());
+    partial_pein.erase(o->id());
+    partial_peout.erase(o->id());
 }
 
 } /* namespace view_scilab */
index d1c6b1f..c9bedb0 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -21,6 +21,7 @@
 #include "internal.hxx"
 
 #include "BaseAdapter.hxx"
+#include "adapters_utilities.hxx"
 #include "model/Block.hxx"
 
 namespace org_scilab_modules_scicos
@@ -46,6 +47,13 @@ public:
     types::InternalType* getGrIContent() const;
     void setGrIContent(types::InternalType* v);
 
+    // move (if possible) the partial information to the model
+    static void relink(Controller& controller, model::BaseObject* adaptee, const std::vector<ScicosID>& children);
+    // manage partial information after a model clone
+    static void add_partial_links_information(Controller& controller, model::BaseObject* original, model::BaseObject* cloned);
+    // remove partial links information (on delete)
+    static void remove_partial_links_information(model::BaseObject* o);
+
 private:
     types::InternalType* gr_i_content;
 };
index a44fd1c..e5c4def 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -15,6 +15,7 @@
 
 #include <string>
 #include <vector>
+#include <map>
 #include <iterator>
 #include <algorithm>
 
@@ -49,6 +50,9 @@ const std::string split ("split");
 const std::string lsplit ("lsplit");
 const std::string limpsplit ("limpsplit");
 
+// shared information for relinking across adapters hierarchy
+std::map<ScicosID, partial_link_t> partial_links;
+
 struct xx
 {
 
@@ -307,11 +311,13 @@ struct ct
     }
 };
 
-link_t getLinkEnd(const LinkAdapter& adaptor, const Controller& controller, const object_properties_t end)
+link_t getLinkEnd(ScicosID adaptee, const Controller& controller, const object_properties_t end)
 {
-    ScicosID adaptee = adaptor.getAdaptee()->id();
-
     link_t ret {0, 0, Start};
+    if (end == DESTINATION_PORT)
+    {
+        ret.kind = End;
+    }
 
     ScicosID endID;
     controller.getObjectProperty(adaptee, LINK, end, endID);
@@ -375,6 +381,10 @@ link_t getLinkEnd(const LinkAdapter& adaptor, const Controller& controller, cons
         {
             ret.kind = End;
         }
+        else
+        {
+            ret.kind = Start;
+        }
     }
     // Default case, the property was initialized at [].
     return ret;
@@ -409,9 +419,8 @@ bool checkConnectivity(const int neededType, const ScicosID port, const ScicosID
     return true;
 }
 
-void setLinkEnd(const ScicosID id, Controller& controller, const object_properties_t end, const link_t& v)
+void setLinkEnd(const ScicosID id, Controller& controller, const object_properties_t end, const link_t& v, const std::vector<ScicosID>& children)
 {
-
     ScicosID from;
     controller.getObjectProperty(id, LINK, SOURCE_PORT, from);
     ScicosID to;
@@ -431,7 +440,6 @@ void setLinkEnd(const ScicosID id, Controller& controller, const object_properti
         default:
             return;
     }
-    ScicosID unconnected = ScicosID();
 
     if (v.block == 0 || v.port == 0)
     {
@@ -444,31 +452,12 @@ void setLinkEnd(const ScicosID id, Controller& controller, const object_properti
         else
         {
             // Untie the old link on the concerned end and set its port as unconnected
-            controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, unconnected);
-            controller.setObjectProperty(id, LINK, end, unconnected);
+            controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, ScicosID());
+            controller.setObjectProperty(id, LINK, end, ScicosID());
         }
         return;
     }
 
-    ScicosID parentDiagram;
-    controller.getObjectProperty(id, LINK, PARENT_DIAGRAM, parentDiagram);
-    std::vector<ScicosID> children;
-    if (parentDiagram != ScicosID())
-    {
-        // Adding to a diagram
-        controller.getObjectProperty(parentDiagram, DIAGRAM, CHILDREN, children);
-    }
-    else
-    {
-        ScicosID parentBlock;
-        controller.getObjectProperty(id, LINK, PARENT_BLOCK, parentBlock);
-        if (parentBlock != ScicosID())
-        {
-            // Adding to a superblock
-            controller.getObjectProperty(parentBlock, BLOCK, CHILDREN, children);
-        }
-    }
-
     // Connect the new one
 
     if (v.kind != Start && v.kind != End)
@@ -618,7 +607,7 @@ void setLinkEnd(const ScicosID id, Controller& controller, const object_properti
     // Disconnect the old port if it was connected. After that, concernedPort will be reused to designate the new port
     if (concernedPort != ScicosID())
     {
-        controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, unconnected);
+        controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, ScicosID());
     }
 
     int nBlockPorts = static_cast<int>(sourceBlockPorts.size());
@@ -634,7 +623,7 @@ void setLinkEnd(const ScicosID id, Controller& controller, const object_properti
             controller.setObjectProperty(concernedPort, PORT, IMPLICIT, newPortIsImplicit);
             controller.setObjectProperty(concernedPort, PORT, PORT_KIND, static_cast<int>(newPortKind));
             controller.setObjectProperty(concernedPort, PORT, SOURCE_BLOCK, blkID);
-            controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, unconnected);
+            controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, ScicosID());
             // Set the default dataType so it is saved in the model
             std::vector<int> dataType;
             controller.getObjectProperty(concernedPort, PORT, DATATYPE, dataType);
@@ -680,8 +669,8 @@ void setLinkEnd(const ScicosID id, Controller& controller, const object_properti
     if (oldLink != ScicosID())
     {
         // Disconnect the old link
-        controller.setObjectProperty(oldLink, LINK, end, unconnected);
-        controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, unconnected);
+        controller.setObjectProperty(oldLink, LINK, end, ScicosID());
+        controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, ScicosID());
     }
 
     // Connect the new source and destination ports together
@@ -730,9 +719,20 @@ bool is_valid(types::Double* o)
 struct from
 {
 
-    static types::InternalType* get(const LinkAdapter& adaptor, const Controller& /*controller*/)
+    static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
     {
-        link_t from_content = adaptor.getFrom();
+        link_t from_content;
+        auto it = partial_links.find(adaptor.getAdaptee()->id());
+        if (it == partial_links.end())
+        {
+            // if not found use the connected value
+            from_content = getLinkEnd(adaptor.getAdaptee()->id(), controller, SOURCE_PORT);
+        }
+        else
+        {
+            // if found, use the partial value
+            from_content = it->second.from;
+        }
 
         double* data;
         types::Double* o = new types::Double(1, 3, &data);
@@ -770,7 +770,19 @@ struct from
             }
         }
 
-        adaptor.setFromInModel(from_content, controller);
+        // store the new data on the adapter, the linking will be performed later on the diagram update
+        auto it = partial_links.find(adaptor.getAdaptee()->id());
+        if (it == partial_links.end())
+        {
+            partial_link_t l;
+            l.from = from_content;
+            l.to = getLinkEnd(adaptor.getAdaptee()->id(), controller, DESTINATION_PORT);
+            partial_links.insert({adaptor.getAdaptee()->id(), l});
+        }
+        else
+        {
+            it->second.from = from_content;
+        }
         return true;
     }
 };
@@ -778,9 +790,21 @@ struct from
 struct to
 {
 
-    static types::InternalType* get(const LinkAdapter& adaptor, const Controller& /*controller*/)
+    static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
     {
-        link_t to_content = adaptor.getTo();
+        link_t to_content;
+        auto it = partial_links.find(adaptor.getAdaptee()->id());
+
+        if (it == partial_links.end())
+        {
+            // if not found use the connected value
+            to_content = getLinkEnd(adaptor.getAdaptee()->id(), controller, DESTINATION_PORT);
+        }
+        else
+        {
+            // if found, use the partial value
+            to_content = it->second.to;
+        }
 
         double* data;
         types::Double* o = new types::Double(1, 3, &data);
@@ -823,7 +847,19 @@ struct to
             }
         }
 
-        adaptor.setToInModel(to_content, controller);
+        // store the new data on the adapter, the linking will be performed later on the diagram update
+        auto it = partial_links.find(adaptor.getAdaptee()->id());
+        if (it == partial_links.end())
+        {
+            partial_link_t l;
+            l.from = getLinkEnd(adaptor.getAdaptee()->id(), controller, SOURCE_PORT);
+            l.to = to_content;
+            partial_links.insert({adaptor.getAdaptee()->id(), l});
+        }
+        else
+        {
+            it->second.to = to_content;
+        }
         return true;
     }
 };
@@ -833,9 +869,7 @@ struct to
 template<> property<LinkAdapter>::props_t property<LinkAdapter>::fields = property<LinkAdapter>::props_t();
 
 LinkAdapter::LinkAdapter(const Controller& c, org_scilab_modules_scicos::model::Link* adaptee) :
-    BaseAdapter<LinkAdapter, org_scilab_modules_scicos::model::Link>(c, adaptee),
-    m_from(),
-    m_to()
+    BaseAdapter<LinkAdapter, org_scilab_modules_scicos::model::Link>(c, adaptee)
 {
     if (property<LinkAdapter>::properties_have_not_been_set())
     {
@@ -848,22 +882,21 @@ LinkAdapter::LinkAdapter(const Controller& c, org_scilab_modules_scicos::model::
         property<LinkAdapter>::add_property(L"from", &from::get, &from::set);
         property<LinkAdapter>::add_property(L"to", &to::get, &to::set);
     }
-
-    // If the Link has been added to a diagram, the following lines will dig up its information at model-level
-    Controller controller;
-    m_from = getLinkEnd(*this, controller, SOURCE_PORT);
-    m_to   = getLinkEnd(*this, controller, DESTINATION_PORT);
 }
 
 LinkAdapter::LinkAdapter(const LinkAdapter& adapter) :
-    BaseAdapter<LinkAdapter, org_scilab_modules_scicos::model::Link>(adapter),
-    m_from(adapter.getFrom()),
-    m_to(adapter.getTo())
+    BaseAdapter<LinkAdapter, org_scilab_modules_scicos::model::Link>(adapter)
 {
+    Controller controller;
+    add_partial_links_information(controller, adapter.getAdaptee(), getAdaptee());
 }
 
 LinkAdapter::~LinkAdapter()
 {
+    if (getAdaptee()->refCount() == 0)
+    {
+        partial_links.erase(getAdaptee()->id());
+    }
 }
 
 std::wstring LinkAdapter::getTypeStr()
@@ -875,58 +908,74 @@ std::wstring LinkAdapter::getShortTypeStr()
     return getSharedTypeStr();
 }
 
-link_t LinkAdapter::getFrom() const
+void LinkAdapter::relink(Controller& controller, model::BaseObject* adaptee, const std::vector<ScicosID>& children)
 {
-    return m_from;
-}
-
-void LinkAdapter::setFrom(const link_t& v)
-{
-    m_from = v;
-}
+    auto it = partial_links.find(adaptee->id());
+    if (it == partial_links.end())
+    {
+        // unable to relink as there is no information to do so
+        return;
+    }
+    partial_link_t l = it->second;
 
-void LinkAdapter::setFromInModel(const link_t& v, Controller& controller)
-{
-    m_from = v;
+    setLinkEnd(adaptee->id(), controller, SOURCE_PORT, l.from, children);
+    setLinkEnd(adaptee->id(), controller, DESTINATION_PORT, l.to, children);
 
-    ScicosID parentDiagram;
-    controller.getObjectProperty(getAdaptee()->id(), LINK, PARENT_DIAGRAM, parentDiagram);
-    ScicosID parentBlock;
-    controller.getObjectProperty(getAdaptee()->id(), LINK, PARENT_BLOCK, parentBlock);
+    // refresh the shared values
+    ScicosID from;
+    controller.getObjectProperty(adaptee->id(), LINK, SOURCE_PORT, from);
+    ScicosID to;
+    controller.getObjectProperty(adaptee->id(), LINK, DESTINATION_PORT, to);
 
-    if (parentDiagram != ScicosID() || parentBlock != ScicosID())
+    bool isConnected = from != ScicosID() && to != ScicosID();
+    if (isConnected)
     {
-        // If the Link has been added to a diagram, do the linking at model-level
-        // If the provided values are wrong, the model is not updated but the info is stored in the Adapter for future attempts
-        setLinkEnd(getAdaptee()->id(), controller, SOURCE_PORT, v);
+        partial_links.erase(it);
     }
 }
 
-link_t LinkAdapter::getTo() const
+void LinkAdapter::add_partial_links_information(Controller& controller, model::BaseObject* original, model::BaseObject* cloned)
 {
-    return m_to;
-}
-
-void LinkAdapter::setTo(const link_t& v)
-{
-    m_to = v;
-}
+    switch (original->kind())
+    {
+        // add the from / to information if applicable
+        case LINK:
+        {
+            auto it = partial_links.find(original->id());
+            if (it != partial_links.end())
+            {
+                partial_links.insert({cloned->id(), it->second});
+            }
+            else
+            {
+                partial_link_t l;
+                l.from = getLinkEnd(original->id(), controller, SOURCE_PORT);
+                l.to = getLinkEnd(original->id(), controller, DESTINATION_PORT);
+                partial_links.insert({cloned->id(), l});
+            }
+            break;
+        }
 
-void LinkAdapter::setToInModel(const link_t& v, Controller& controller)
-{
-    m_to = v;
+        // handle recursion
+        case DIAGRAM:
+        case BLOCK:
+        {
+            std::vector<ScicosID> originalChildren;
+            controller.getObjectProperty(original->id(), original->kind(), CHILDREN, originalChildren);
+            std::vector<ScicosID> clonedChildren;
+            controller.getObjectProperty(cloned->id(), cloned->kind(), CHILDREN, clonedChildren);
 
-    ScicosID parentDiagram;
-    controller.getObjectProperty(getAdaptee()->id(), LINK, PARENT_DIAGRAM, parentDiagram);
-    ScicosID parentBlock;
-    controller.getObjectProperty(getAdaptee()->id(), LINK, PARENT_BLOCK, parentBlock);
+            for (size_t i = 0; i < originalChildren.size(); ++i)
+            {
+                add_partial_links_information(controller, controller.getObject(originalChildren[i]), controller.getObject(clonedChildren[i]));
+            }
+            break;
+        }
 
-    if (parentDiagram != ScicosID() || parentBlock != ScicosID())
-    {
-        // If the Link has been added to a diagram, do the linking at model-level
-        // If the provided values are wrong, the model is not updated but the info is stored in the Adapter for future attempts
-        setLinkEnd(getAdaptee()->id(), controller, DESTINATION_PORT, v);
+        default:
+            break;
     }
+
 }
 
 } /* namespace view_scilab */
index 1c89efa..ef7b474 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -42,16 +42,11 @@ public:
     std::wstring getTypeStr();
     std::wstring getShortTypeStr();
 
-    link_t getFrom() const;
-    void setFrom(const link_t& v);
-    void setFromInModel(const link_t& v, Controller& controller);
-    link_t getTo() const;
-    void setTo(const link_t& v);
-    void setToInModel(const link_t& v, Controller& controller);
+    // move (if possible) the partial informatios to the model
+    static void relink(Controller& controller, model::BaseObject* adaptee, const std::vector<ScicosID>& children);
+    // manage partial information after a model clone
+    static void add_partial_links_information(Controller& controller, model::BaseObject* original, model::BaseObject* cloned);
 
-private:
-    link_t m_from;
-    link_t m_to;
 };
 
 } /* namespace view_scilab */
index 6ca75cb..61a4f85 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -456,7 +456,7 @@ void encodeDims(std::vector<int>& prop_content, types::GenericType* v)
     const int iDims = v->getDims();
     prop_content.push_back(iDims);
 
-    const int index = prop_content.size();
+    const int index = (int)prop_content.size();
     prop_content.resize(index + iDims);
 
     memcpy(&prop_content[index], v->getDimsArray(), iDims * sizeof(int));
@@ -503,8 +503,8 @@ bool encode(std::vector<int>& prop_content, T* v)
 {
     encodeDims(prop_content, v);
 
-    const int index = prop_content.size();
-    const int len = required_length(prop_content, v);
+    const int index = (int)prop_content.size();
+    const int len = (int)required_length(prop_content, v);
     prop_content.resize(index + len);
 
     // Using contiguity of the memory, we save the input into 'prop_content'
@@ -518,7 +518,7 @@ types::Double* decode(std::vector<int>::iterator& prop_it)
     std::vector<int> dims;
     decodeDims(prop_it, dims);
 
-    bool isComplex = *prop_it++;
+    bool isComplex = *prop_it++ != 0;
 
     types::Double* v = new types::Double(static_cast<int>(dims.size()), &dims[0], isComplex);
     memcpy(v->getReal(), &(*prop_it), v->getSize() * sizeof(double));
@@ -540,8 +540,8 @@ bool encode(std::vector<int>& prop_content, types::Double* v)
     // Flag for complex
     prop_content.push_back(v->isComplex());
 
-    const int index = prop_content.size();
-    const int len = required_length(prop_content, v);
+    const int index = (int)prop_content.size();
+    const int len = (int)required_length(prop_content, v);
     prop_content.resize(index + len);
 
     // Using contiguity of the memory, we save the input into 'prop_content'
@@ -587,7 +587,7 @@ bool encode(std::vector<int>& prop_content, types::String* v)
 {
     encodeDims(prop_content, v);
 
-    const int index = prop_content.size();
+    const int index = (int)prop_content.size();
 
     std::vector<char*> utf8;
     utf8.reserve(v->getSize());
@@ -595,7 +595,7 @@ bool encode(std::vector<int>& prop_content, types::String* v)
     std::vector<size_t> str_len;
     str_len.reserve(v->getSize());
 
-    int offset = 0;
+    size_t offset = 0;
     for (int i = 0; i < v->getSize(); i++)
     {
         char* str = wide_string_to_UTF8(v->get(i));
@@ -606,7 +606,7 @@ bool encode(std::vector<int>& prop_content, types::String* v)
         str_len.push_back(len);
 
         offset += (len * sizeof(char) + sizeof(int) - 1) / sizeof(int);
-        prop_content.push_back(offset);
+        prop_content.push_back((int)offset);
     }
 
     // reserve space for the string offsets and contents
@@ -823,7 +823,7 @@ bool setInnerBlocksRefs(ModelAdapter& adaptor, const std::vector<ScicosID>& chil
                     if (!superPorts.empty())
                     {
                         // Arbitrarily take the highest possible value in case the user enters a wrong number
-                        portIndex = superPorts.size();
+                        portIndex = (int)superPorts.size();
                     }
                     else
                     {
@@ -893,13 +893,8 @@ struct rpar
         }
         else // SuperBlock, return the contained diagram (allocating it on demand)
         {
-            DiagramAdapter* diagram = adaptor.getDiagram();
-
-            /*
-             * FIXME: Sync all diagram children as the blocks might be modified by xcos
-             */
-
-            return diagram;
+            DiagramAdapter* d = new DiagramAdapter(controller, controller.referenceObject(adaptor.getAdaptee()));
+            return d;
         }
     }
 
@@ -934,129 +929,26 @@ struct rpar
                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : Diagram expected.\n"), "model", "rpar");
                 return false;
             }
+            const DiagramAdapter* diagram = v->getAs<DiagramAdapter>();
+            DiagramAdapter* superblock = new DiagramAdapter(controller, controller.referenceObject(adaptor.getAdaptee()));
 
-            // Translate 'v' to an DiagramAdapter
-            DiagramAdapter* diagram = v->getAs<DiagramAdapter>();
-
-            adaptor.setDiagram(diagram);
-
-            // Set the diagram children as block children
-            std::vector<ScicosID> diagramChildren;
-            controller.getObjectProperty(diagram->getAdaptee()->id(), DIAGRAM, CHILDREN, diagramChildren);
-            if (diagramChildren.empty())
-            {
-                // bug_12998: If inserting an empty diagram in 'rpar', simulate an empty object
-                diagramChildren.push_back(ScicosID());
-            }
-            std::vector<ScicosID> oldDiagramChildren;
-            controller.getObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, oldDiagramChildren);
-
-            std::sort(oldDiagramChildren.begin(), oldDiagramChildren.end());
-            std::vector<ScicosID> newChildren;
-            std::vector<ScicosID> clonedLinks;
-            for (const ScicosID & id : diagramChildren)
-            {
-                if (id != 0 && !std::binary_search(oldDiagramChildren.begin(), oldDiagramChildren.end(), id))
-                {
-                    ScicosID cloneID = controller.cloneObject(id, true, true);
-                    auto o = controller.getObject(cloneID);
-                    controller.setObjectProperty(o->id(), o->kind(), PARENT_BLOCK, adaptor.getAdaptee()->id());
-
-                    newChildren.push_back(cloneID);
-                    if (o->kind() == LINK)
-                    {
-                        clonedLinks.push_back(cloneID);
-                    }
-                }
-                else
-                {
-                    newChildren.push_back(id);
-                }
-            }
-            controller.setObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, newChildren);
-
-            std::sort(diagramChildren.begin(), diagramChildren.end());
-            for (const ScicosID & id : oldDiagramChildren)
-            {
-                if (id != 0 && !std::binary_search(diagramChildren.begin(), diagramChildren.end(), id))
-                {
-                    auto o = controller.getObject(id);
-                    controller.setObjectProperty(o->id(), o->kind(), PARENT_BLOCK, ScicosID());
+            // copy the values by name to preserve adaptors specific properties
+            superblock->copyProperties(*diagram, controller);
 
-                    controller.deleteObject(id);
-                }
-            }
-
-            // After cloning the diagram elements, re-sync the link information
-            for (int i = 0; i < static_cast<int>(clonedLinks.size()); ++i)
-            {
-                auto o = controller.getObject(clonedLinks[i]);
-                controller.referenceObject(o);
-                LinkAdapter newLink(controller, static_cast<model::Link*>(o));
-                newLink.setFromInModel(diagram->getFrom()[i], controller);
-                newLink.setToInModel(diagram->getTo()[i], controller);
-            }
-
-            // Save the context
-            std::vector<std::string> context;
-            controller.getObjectProperty(diagram->getAdaptee()->id(), DIAGRAM, DIAGRAM_CONTEXT, context);
-            controller.setObjectProperty(adaptor.getAdaptee()->id(), BLOCK, DIAGRAM_CONTEXT, context);
-
-            // Link the Superblock ports to their inner "port blocks"
-            return setInnerBlocksRefs(adaptor, diagramChildren, controller);
+            superblock->killMe();
+            return true;
         }
         else if (v->getType() == types::InternalType::ScilabMList)
         {
-            ScicosID localAdaptee = controller.createObject(DIAGRAM);
-            DiagramAdapter* diagram = new DiagramAdapter(controller, controller.getObject<model::Diagram>(localAdaptee));
+            DiagramAdapter* diagram = new DiagramAdapter(controller, controller.referenceObject(adaptor.getAdaptee()));
             if (!diagram->setAsTList(v, controller))
             {
                 diagram->killMe();
                 return false;
             }
 
-            adaptor.setDiagram(diagram);
-
-            // set the diagram children as block children ; referencing them
-            std::vector<ScicosID> diagramChildren;
-            controller.getObjectProperty(diagram->getAdaptee()->id(), DIAGRAM, CHILDREN, diagramChildren);
-            if (diagramChildren.empty())
-            {
-                // bug_12998: If inserting an empty diagram in 'rpar', simulate an empty object
-                diagramChildren.push_back(ScicosID());
-            }
-            std::vector<ScicosID> oldDiagramChildren;
-            controller.getObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, oldDiagramChildren);
-
-            controller.setObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, diagramChildren);
-            {
-                std::sort(oldDiagramChildren.begin(), oldDiagramChildren.end());
-                for (const ScicosID id : diagramChildren)
-                {
-                    if (id != 0 && !std::binary_search(oldDiagramChildren.begin(), oldDiagramChildren.end(), id))
-                    {
-                        auto o = controller.getObject(id);
-                        controller.setObjectProperty(o->id(), o->kind(), PARENT_BLOCK, adaptor.getAdaptee()->id());
-
-                        controller.referenceObject(id);
-                    }
-                }
-
-                std::sort(diagramChildren.begin(), diagramChildren.end());
-                for (const ScicosID id : oldDiagramChildren)
-                {
-                    if (id != 0 && !std::binary_search(diagramChildren.begin(), diagramChildren.end(), id))
-                    {
-                        auto o = controller.getObject(id);
-                        controller.setObjectProperty(o->id(), o->kind(), PARENT_BLOCK, ScicosID());
-
-                        controller.deleteObject(id);
-                    }
-                }
-            }
-
-            // Link the Superblock ports to their inner "port blocks"
-            return setInnerBlocksRefs(adaptor, diagramChildren, controller);
+            diagram->killMe();
+            return true;
         }
         else
         {
@@ -1322,11 +1214,12 @@ struct label
         std::string label(c_str);
         FREE(c_str);
 
-        if (!isValidCIdentifier(label))
-        {
-            get_or_allocate_logger()->log(LOG_ERROR, _("Wrong value for field %s.%s : Valid C identifier expected.\n"), "model", "label");
-            return false;
-        }
+        // TODO: validate a C/Scilab identifier only
+        //        if (!isValidCIdentifier(label))
+        //        {
+        //            get_or_allocate_logger()->log(LOG_ERROR, _("Wrong value for field %s.%s : Valid C identifier expected.\n"), "model", "label");
+        //            return false;
+        //        }
 
         controller.setObjectProperty(adaptee, BLOCK, LABEL, label);
         return true;
@@ -1534,25 +1427,19 @@ static void initialize_fields()
 }
 
 ModelAdapter::ModelAdapter() :
-    BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(),
-    m_diagramAdapter(nullptr)
+    BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>()
 {
     initialize_fields();
 }
 
-ModelAdapter::ModelAdapter(const Controller& c, model::Block* adaptee, DiagramAdapter* diagramAdapter) :
-    BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(c, adaptee),
-    m_diagramAdapter(diagramAdapter)
+ModelAdapter::ModelAdapter(const Controller& c, model::Block* adaptee) :
+    BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(c, adaptee)
 {
     initialize_fields();
 }
 
 ModelAdapter::~ModelAdapter()
 {
-    if (m_diagramAdapter)
-    {
-        m_diagramAdapter->killMe();
-    }
 }
 
 std::wstring ModelAdapter::getTypeStr()
@@ -1565,16 +1452,5 @@ std::wstring ModelAdapter::getShortTypeStr()
     return getSharedTypeStr();
 }
 
-DiagramAdapter* ModelAdapter::getDiagram() const
-{
-    return m_diagramAdapter;
-}
-
-void ModelAdapter::setDiagram(DiagramAdapter* diagramAdapter)
-{
-    // does not increment reference as this adapter does not own the DiagramAdapter
-    m_diagramAdapter = diagramAdapter;
-}
-
 } /* namespace view_scilab */
 } /* namespace org_scilab_modules_scicos */
index a0dbf8a..7b878d0 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -19,7 +19,6 @@
 #include <string>
 
 #include "BaseAdapter.hxx"
-#include "DiagramAdapter.hxx"
 #include "model/Block.hxx"
 
 namespace org_scilab_modules_scicos
@@ -31,7 +30,7 @@ class ModelAdapter : public BaseAdapter<ModelAdapter, org_scilab_modules_scicos:
 {
 public:
     ModelAdapter();
-    ModelAdapter(const Controller& c, model::Block* adaptee, DiagramAdapter* diagramAdapter);
+    ModelAdapter(const Controller& c, model::Block* adaptee);
     ~ModelAdapter();
 
     static const std::wstring getSharedTypeStr()
@@ -41,12 +40,6 @@ public:
 
     std::wstring getTypeStr();
     std::wstring getShortTypeStr();
-
-    DiagramAdapter* getDiagram() const;
-    void setDiagram(DiagramAdapter* diagramAdapter);
-
-private:
-    DiagramAdapter* m_diagramAdapter;
 };
 
 } /* namespace view_scilab */
index f0feb0b..5661e0f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
@@ -94,9 +94,16 @@ struct title
         ScicosID adaptee = adaptor.getAdaptee()->id();
 
         std::string title;
-        controller.getObjectProperty(adaptee, DIAGRAM, TITLE, title);
         std::string path;
-        controller.getObjectProperty(adaptee, DIAGRAM, PATH, path);
+        if (adaptor.getAdaptee()->kind() == DIAGRAM)
+        {
+            controller.getObjectProperty(adaptee, DIAGRAM, TITLE, title);
+            controller.getObjectProperty(adaptee, DIAGRAM, PATH, path);
+        }
+        else
+        {
+            controller.getObjectProperty(adaptee, BLOCK, LABEL, title);
+        }
 
         types::String* o = new types::String(2, 1);
         o->set(0, title.data());
@@ -138,8 +145,16 @@ struct title
         title = std::string(Title);
         FREE(Title);
 
-        controller.setObjectProperty(adaptee, DIAGRAM, TITLE, title);
-        controller.setObjectProperty(adaptee, DIAGRAM, PATH, path);
+
+        if (adaptor.getAdaptee()->kind() == DIAGRAM)
+        {
+            controller.setObjectProperty(adaptee, DIAGRAM, TITLE, title);
+            controller.setObjectProperty(adaptee, DIAGRAM, PATH, path);
+        }
+        else
+        {
+            controller.setObjectProperty(adaptee, BLOCK, TITLE, title);
+        }
         return true;
     }
 };
@@ -150,6 +165,14 @@ struct tol
     static types::InternalType* get(const ParamsAdapter& adaptor, const Controller& controller)
     {
         ScicosID adaptee = adaptor.getAdaptee()->id();
+        if (adaptor.getAdaptee()->kind() == BLOCK)
+        {
+            controller.getObjectProperty(adaptee, BLOCK, PARENT_DIAGRAM, adaptee);
+            if (adaptee == ScicosID())
+            {
+                return types::Double::Empty();
+            }
+        }
 
         double* data;
         types::Double* o = new types::Double(1, 7, &data);
@@ -167,6 +190,11 @@ struct tol
 
     static bool set(ParamsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
+        if (adaptor.getAdaptee()->kind() == BLOCK)
+        {
+            // ignore the updated value for a block
+            return dummy_property::set(adaptor, v, controller);
+        }
 
         if (v->getType() != types::InternalType::ScilabDouble)
         {
@@ -205,6 +233,14 @@ struct tf
     static types::InternalType* get(const ParamsAdapter& adaptor, const Controller& controller)
     {
         ScicosID adaptee = adaptor.getAdaptee()->id();
+        if (adaptor.getAdaptee()->kind() == BLOCK)
+        {
+            controller.getObjectProperty(adaptee, BLOCK, PARENT_DIAGRAM, adaptee);
+            if (adaptee == ScicosID())
+            {
+                return types::Double::Empty();
+            }
+        }
 
         std::vector<double> tf;
         controller.getObjectProperty(adaptee, DIAGRAM, PROPERTIES, tf);
@@ -214,6 +250,11 @@ struct tf
 
     static bool set(ParamsAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
+        if (adaptor.getAdaptee()->kind() == BLOCK)
+        {
+            // ignore the updated value for a block
+            return dummy_property::set(adaptor, v, controller);
+        }
 
         if (v->getType() != types::InternalType::ScilabDouble)
         {
@@ -248,7 +289,7 @@ struct context
         ScicosID adaptee = adaptor.getAdaptee()->id();
 
         std::vector<std::string> context;
-        controller.getObjectProperty(adaptee, DIAGRAM, DIAGRAM_CONTEXT, context);
+        controller.getObjectProperty(adaptee, adaptor.getAdaptee()->kind(), DIAGRAM_CONTEXT, context);
 
         if (context.size() == 0)
         {
@@ -287,7 +328,7 @@ struct context
                 FREE(c_str);
             }
 
-            controller.setObjectProperty(adaptee, DIAGRAM, DIAGRAM_CONTEXT, context);
+            controller.setObjectProperty(adaptee, adaptor.getAdaptee()->kind(), DIAGRAM_CONTEXT, context);
             return true;
         }
         else if (v->getType() == types::InternalType::ScilabDouble)
@@ -302,7 +343,7 @@ struct context
             ScicosID adaptee = adaptor.getAdaptee()->id();
 
             std::vector<std::string> context;
-            controller.setObjectProperty(adaptee, DIAGRAM, DIAGRAM_CONTEXT, context);
+            controller.setObjectProperty(adaptee, adaptor.getAdaptee()->kind(), DIAGRAM_CONTEXT, context);
             return true;
         }
 
@@ -387,7 +428,7 @@ struct doc
 
     static bool set(ParamsAdapter& adaptor, types::InternalType* v, Controller& /*controller*/)
     {
-        adaptor.setDocContent(v->clone());
+        adaptor.setDocContent(v);
         return true;
     }
 };
@@ -414,15 +455,15 @@ static void initialize_fields()
 }
 
 ParamsAdapter::ParamsAdapter() :
-    BaseAdapter<ParamsAdapter, org_scilab_modules_scicos::model::Diagram>(),
-    doc_content(new types::List())
+    BaseAdapter<ParamsAdapter, org_scilab_modules_scicos::model::BaseObject>(),
+    doc_content(default_value<types::List>())
 {
     initialize_fields();
 }
 
-ParamsAdapter::ParamsAdapter(const Controller& c, org_scilab_modules_scicos::model::Diagram* adaptee) :
-    BaseAdapter<ParamsAdapter, org_scilab_modules_scicos::model::Diagram>(c, adaptee),
-    doc_content(new types::List())
+ParamsAdapter::ParamsAdapter(const Controller& c, org_scilab_modules_scicos::model::BaseObject* adaptee) :
+    BaseAdapter<ParamsAdapter, org_scilab_modules_scicos::model::BaseObject>(c, adaptee),
+    doc_content(default_value<types::List>())
 {
     initialize_fields();
 }
@@ -444,17 +485,18 @@ std::wstring ParamsAdapter::getShortTypeStr()
 
 types::InternalType* ParamsAdapter::getDocContent() const
 {
-    doc_content->IncreaseRef();
     return doc_content;
 }
 
 void ParamsAdapter::setDocContent(types::InternalType* v)
 {
-    doc_content->DecreaseRef();
-    doc_content->killMe();
+    types::InternalType* temp = doc_content;
 
     v->IncreaseRef();
     doc_content = v;
+
+    temp->DecreaseRef();
+    temp->killMe();
 }
 
 } /* namespace view_scilab */
index f8a7418..93bc04c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
 #include "internal.hxx"
 
 #include "BaseAdapter.hxx"
-#include "model/Diagram.hxx"
 
 namespace org_scilab_modules_scicos
 {
 namespace view_scilab
 {
 
-class ParamsAdapter : public BaseAdapter<ParamsAdapter, org_scilab_modules_scicos::model::Diagram>
+class ParamsAdapter : public BaseAdapter<ParamsAdapter, org_scilab_modules_scicos::model::BaseObject>
 {
 public:
     ParamsAdapter();
-    ParamsAdapter(const Controller& c, org_scilab_modules_scicos::model::Diagram* adaptee);
+    ParamsAdapter(const Controller& c, org_scilab_modules_scicos::model::BaseObject* adaptee);
     ~ParamsAdapter();
 
     static const std::wstring getSharedTypeStr()
index 7032d00..356cc86 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
index 06a1c1b..60afd97 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
index 8803e4d..fcf6e00 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
index 5d51f27..8631f29 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
index 8743304..5cbb562 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
index b52f076..ac4783c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
+ *  Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
index 2d18580..020af54 100644 (file)
@@ -35,6 +35,7 @@
 #include "Controller.hxx"
 #include "controller_helpers.hxx"
 #include "model/Port.hxx"
+#include "LinkAdapter.hxx"
 
 extern "C" {
 #include "sci_malloc.h"
@@ -177,10 +178,10 @@ types::InternalType* get_ports_property(const Adaptor& adaptor, const object_pro
                 return new types::Double(1);
             }
             datatypeIndex++;
-            // no break
+        // no break
         case DATATYPE_COLS:
             datatypeIndex++;
-            // no break
+        // no break
         case DATATYPE_ROWS:
         {
             datatypeIndex++;
@@ -206,7 +207,7 @@ types::InternalType* get_ports_property(const Adaptor& adaptor, const object_pro
         }
         case IMPLICIT:
         {
-            if (ids.size() == 0)
+            if (ids.empty())
             {
                 // When no port is present, return an empty matrix
                 return types::Double::Empty();
@@ -226,24 +227,22 @@ types::InternalType* get_ports_property(const Adaptor& adaptor, const object_pro
             double* v;
             types::Double* o = new types::Double((int)ids.size(), 1, &v);
 
-            ScicosID parentDiagram;
-            controller.getObjectProperty(adaptee, BLOCK, PARENT_DIAGRAM, parentDiagram);
-
             std::vector<ScicosID> children;
-            if (parentDiagram != 0)
+
+            ScicosID parentBlock;
+            controller.getObjectProperty(adaptee, BLOCK, PARENT_BLOCK, parentBlock);
+            if (parentBlock == ScicosID())
             {
                 // Adding to a diagram
+                ScicosID parentDiagram;
+                controller.getObjectProperty(adaptee, BLOCK, PARENT_DIAGRAM, parentDiagram);
+
                 controller.getObjectProperty(parentDiagram, DIAGRAM, CHILDREN, children);
             }
             else
             {
-                ScicosID parentBlock;
-                controller.getObjectProperty(adaptee, BLOCK, PARENT_BLOCK, parentBlock);
-                if (parentBlock != 0)
-                {
-                    // Adding to a superblock
-                    controller.getObjectProperty(parentBlock, BLOCK, CHILDREN, children);
-                }
+                // Adding to a superblock
+                controller.getObjectProperty(parentBlock, BLOCK, CHILDREN, children);
             }
 
             for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
@@ -251,20 +250,25 @@ types::InternalType* get_ports_property(const Adaptor& adaptor, const object_pro
                 ScicosID id;
                 controller.getObjectProperty(*it, PORT, p, id);
 
-                v[i] = 0;
-
-                if (id == 0)
+                if (id == ScicosID())
                 {
                     // Unconnected port, no need to search in 'children'
+                    std::cerr << "unconnected port " << id << std::endl;
+                    v[i] = 0;
                 }
                 else
                 {
                     std::vector<ScicosID>::iterator found = std::find(children.begin(), children.end(), id);
-
                     if (found != children.end())
                     {
                         v[i] = static_cast<double>(std::distance(children.begin(), found)) + 1;
                     }
+                    else
+                    {
+                        // connected link not found ; discard it !
+                        v[i] = 0;
+                        std::cerr << "connected port out of hierarchy " << id << std::endl;
+                    }
                 }
             }
             return o;
@@ -345,7 +349,7 @@ bool set_ports_property(const Adaptor& adaptor, const object_properties_t port_k
                         controller.setObjectProperty(ids[i], PORT, p, false);
                     }
                 }
-                for (i = maxSize; i < ids.size(); ++i)
+                for (i = maxSize; i < (int)ids.size(); ++i)
                 {
                     // Tag the missing ports as Explicit. This is done to fix the resizing of pin & pout.
                     controller.setObjectProperty(ids[i], PORT, p, false);
@@ -397,10 +401,10 @@ bool set_ports_property(const Adaptor& adaptor, const object_properties_t port_k
 
             case DATATYPE_TYPE:
                 datatypeIndex++;
-                // no break
+            // no break
             case DATATYPE_COLS:
                 datatypeIndex++;
-                // no break
+            // no break
             case DATATYPE_ROWS:
             {
                 datatypeIndex++;
@@ -470,120 +474,49 @@ bool set_ports_property(const Adaptor& adaptor, const object_properties_t port_k
 /**
  * Fill \a newPorts with \a d values checking content if possible.
  *
- * \param newPorts new ports children's index or value to be filled
- * \param children all object in the current layer (diagram or superblock)
+ * \param newPorts new ports children's value to be filled
  * \param d the C-array values to set
  * \return true on success, false otherwise
  */
-template<typename Adaptor, object_properties_t p>
-inline bool fillNewPorts(std::deque<int>& newPorts, const std::vector<ScicosID>& children, const double* d)
+inline void fillNewPorts(std::deque<int>& newPorts, const double* d)
 {
     for (std::deque<int>::iterator it = newPorts.begin(); it != newPorts.end(); ++it, ++d)
     {
-
-        if (p == CONNECTED_SIGNALS)   // the associated link must exist
-        {
-            if (0 > *d && *d >= children.size())
-            {
-                return false;
-            }
-            *it = static_cast<int>(*d - 1); // 'd' contains indexes
-        } // no check is performed for other properties as newPorts will contains value not index
-        else
-        {
-            *it = static_cast<int>(*d);
-        }
+        *it = static_cast<int>(*d);
     }
-    return true;
 }
 
 /**
  * Set the port value
  *
  * \param oldPort the old port object ID
- * \param newPort new port children's index or value
  * \param controller current transaction instance
  * \param children all object in the current layer (diagram or superblock)
- * \param deletedObjects trash used to delete objects
  */
-template<typename Adaptor, object_properties_t p>
-inline bool updateNewPort(const ScicosID oldPort, int newPort, Controller& controller,
-                          std::vector<ScicosID>& children, std::vector<ScicosID>& deletedObjects)
+template<object_properties_t p>
+inline bool updateNewPort(const ScicosID oldPort, int newPort, Controller& controller)
 {
-    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;
-        if (children.size() > 0 && newPort >= 0)
-        {
-            newSignal = children[newPort];
-        }
-        else
-        {
-            newSignal = 0;
-        }
-
-        if (oldSignal != newSignal)
-        {
-            if (oldSignal == 0)
-            {
-                // FIXME: The port was not linked, check if Link #newSignal has an unconnected end that is connectable to the port (Link kind)
-                return false;
-            }
-            // 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 if there is one
-            if (newSignal != 0)
-            {
-                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
+    // update the p property, using newPort as a value
+    int datatypeIndex = -1;
+    switch (p)
     {
-        // update the p property, using newPort as a value
-        int datatypeIndex = -1;
-        switch (p)
+        case DATATYPE_TYPE:
+            datatypeIndex++;
+        // no break
+        case DATATYPE_COLS:
+            datatypeIndex++;
+        // no break
+        case DATATYPE_ROWS:
         {
-            case DATATYPE_TYPE:
-                datatypeIndex++;
-                // no break
-            case DATATYPE_COLS:
-                datatypeIndex++;
-                // no break
-            case DATATYPE_ROWS:
-            {
-                datatypeIndex++;
-                std::vector<int> datatype;
-                controller.getObjectProperty(oldPort, PORT, DATATYPE, datatype);
-                datatype[datatypeIndex] = newPort;
-                controller.setObjectProperty(oldPort, PORT, DATATYPE, datatype);
-                return true;
-            }
-            default:
-                controller.setObjectProperty(oldPort, PORT, p, newPort);
+            datatypeIndex++;
+            std::vector<int> datatype;
+            controller.getObjectProperty(oldPort, PORT, DATATYPE, datatype);
+            datatype[datatypeIndex] = newPort;
+            return controller.setObjectProperty(oldPort, PORT, DATATYPE, datatype) != FAIL;
         }
+        default:
+            return controller.setObjectProperty(oldPort, PORT, p, newPort) != FAIL;
     }
-    return true;
 }
 
 /**
@@ -591,49 +524,33 @@ inline bool updateNewPort(const ScicosID oldPort, int newPort, Controller& contr
  *
  * \param newPortID the old port object ID
  * \param newPort new port children's index or value
- * \param children all object in the current layer (diagram or superblock)
  * \param controller current transaction instance
  * \return true on success, false otherwise
  */
-template<typename Adaptor, object_properties_t p>
-inline bool addNewPort(const ScicosID newPortID, int newPort, const std::vector<ScicosID>& children, Controller& controller)
+template<object_properties_t p>
+inline bool addNewPort(const ScicosID newPortID, int newPort, Controller& controller)
 {
-    bool status = true;
-    if (p == CONNECTED_SIGNALS)
-    {
-        // set the connected signal if applicable, using newPort as a children index
-        if (children.size() > 0)
-        {
-            ScicosID signal = children[newPort];
-            status = controller.setObjectProperty(newPortID, PORT, CONNECTED_SIGNALS, signal) != FAIL;
-        }
-    }
-    else
+    // set the requested property, using newPort as a value
+    int datatypeIndex = -1;
+    switch (p)
     {
-        // set the requested property, using newPort as a value
-        int datatypeIndex = -1;
-        switch (p)
+        case DATATYPE_TYPE:
+            datatypeIndex++;
+        // no break
+        case DATATYPE_COLS:
+            datatypeIndex++;
+        // no break
+        case DATATYPE_ROWS:
         {
-            case DATATYPE_TYPE:
-                datatypeIndex++;
-                // no break
-            case DATATYPE_COLS:
-                datatypeIndex++;
-                // no break
-            case DATATYPE_ROWS:
-            {
-                datatypeIndex++;
-                std::vector<int> datatype;
-                controller.getObjectProperty(newPortID, PORT, DATATYPE, datatype);
-                datatype[datatypeIndex] = newPort;
-                return controller.setObjectProperty(newPortID, PORT, DATATYPE, datatype) != FAIL;
-            }
-            default:
-                return controller.setObjectProperty(newPortID, PORT, p, newPort) != FAIL;
+            datatypeIndex++;
+            std::vector<int> datatype;
+            controller.getObjectProperty(newPortID, PORT, DATATYPE, datatype);
+            datatype[datatypeIndex] = newPort;
+            return controller.setObjectProperty(newPortID, PORT, DATATYPE, datatype) != FAIL;
         }
+        default:
+            return controller.setObjectProperty(newPortID, PORT, p, newPort) != FAIL;
     }
-
-    return status;
 }
 
 /**
@@ -661,12 +578,12 @@ bool update_ports_property(const Adaptor& adaptor, const object_properties_t por
     controller.getObjectProperty(adaptee, BLOCK, PARENT_DIAGRAM, parentDiagram);
 
     std::vector<ScicosID> children;
-    if (parentBlock != 0)
+    if (parentBlock != ScicosID())
     {
         // Adding to a superblock
         controller.getObjectProperty(parentBlock, BLOCK, CHILDREN, children);
     }
-    if (parentDiagram != 0 && children.empty())
+    else
     {
         // Adding to a diagram
         controller.getObjectProperty(parentDiagram, DIAGRAM, CHILDREN, children);
@@ -680,13 +597,7 @@ bool update_ports_property(const Adaptor& adaptor, const object_properties_t por
     std::deque<ScicosID> oldPorts(previousPorts.begin(), previousPorts.end());
 
     double* d = value->getReal();
-    if (!fillNewPorts<Adaptor, p>(newPorts, children, d))
-    {
-        std::string adapter = adapterName<p>(port_kind);
-        std::string field = adapterFieldName<p>(port_kind);
-        get_or_allocate_logger()->log(LOG_ERROR, _("Wrong value for field %s.%s: Must be in the interval [%d, %d].\n"), adapter.data(), field.data(), 1, children.size());
-        return false;
-    }
+    fillNewPorts(newPorts, d);
 
     std::vector<ScicosID> deletedObjects;
 
@@ -698,7 +609,7 @@ bool update_ports_property(const Adaptor& adaptor, const object_properties_t por
         int newPort = newPorts.front();
         newPorts.pop_front();
 
-        if (!updateNewPort<Adaptor, p>(oldPort, newPort, controller, children, deletedObjects))
+        if (!updateNewPort<p>(oldPort, newPort, controller))
         {
             std::string adapter = adapterName<p>(port_kind);
             std::string field = adapterFieldName<p>(port_kind);
@@ -719,7 +630,7 @@ bool update_ports_property(const Adaptor& adaptor, const object_properties_t por
 
             ScicosID signal;
             controller.getObjectProperty(oldPort, PORT, CONNECTED_SIGNALS, signal);
-            if (signal != 0)
+            if (signal != ScicosID())
             {
                 // the link is connected, disconnect the other side
                 ScicosID oldSignalSrc;
@@ -776,7 +687,7 @@ bool update_ports_property(const Adaptor& adaptor, const object_properties_t por
                     assert(!"Not managed kind of port");
                     return false;
             }
-            addNewPort<Adaptor, p>(id, newPort, children, controller);
+            addNewPort<p>(id, newPort, controller);
             previousPorts.push_back(id);
         }
 
@@ -784,22 +695,6 @@ bool update_ports_property(const Adaptor& adaptor, const object_properties_t por
     }
 
     // remove objects from the model after de-association
-    if (parentDiagram != 0)
-    {
-        for (const ScicosID & id : children)
-        {
-            controller.referenceObject(id);
-        }
-        controller.setObjectProperty(parentDiagram, DIAGRAM, CHILDREN, children);
-    }
-    else if (parentBlock != 0)
-    {
-        for (const ScicosID & id : children)
-        {
-            controller.referenceObject(id);
-        }
-        controller.setObjectProperty(parentBlock, BLOCK, CHILDREN, children);
-    }
     for (std::vector<ScicosID>::iterator it = deletedObjects.begin(); it != deletedObjects.end(); ++it)
     {
         controller.deleteObject(*it);
diff --git a/scilab/modules/scicos/tests/unit_tests/do_eval.dia.ref b/scilab/modules/scicos/tests/unit_tests/do_eval.dia.ref
new file mode 100644 (file)
index 0000000..a6bb974
--- /dev/null
@@ -0,0 +1,89 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2016 - Scilab Enterprises - Clement DAVID
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+loadXcosLibs();
+// check contained blocks interfaces
+o = CONST_m("define");
+assert_checkequal(o.graphics.pin, []);
+assert_checkequal(o.graphics.pout, 0);
+assert_checkequal(o.graphics.pein, []);
+assert_checkequal(o.graphics.peout, []);
+clear o
+o = TRASH_f("define");
+assert_checkequal(o.graphics.pin, 0);
+assert_checkequal(o.graphics.pout, []);
+assert_checkequal(o.graphics.pein, 0);
+assert_checkequal(o.graphics.peout, []);
+clear o
+o = CLOCK_f("define");
+assert_checkequal(o.graphics.pin, []);
+assert_checkequal(o.graphics.pout, []);
+assert_checkequal(o.graphics.pein, []);
+assert_checkequal(o.graphics.peout, 0);
+assert_checkequal(o.model.rpar.objs(1).graphics.pin, []);
+assert_checkequal(o.model.rpar.objs(1).graphics.pout, []);
+assert_checkequal(o.model.rpar.objs(1).graphics.pein, 5);
+assert_checkequal(o.model.rpar.objs(1).graphics.peout, []);
+assert_checkequal(o.model.rpar.objs(4).graphics.pin, []);
+assert_checkequal(o.model.rpar.objs(4).graphics.pout, []);
+assert_checkequal(o.model.rpar.objs(4).graphics.pein, 3);
+assert_checkequal(o.model.rpar.objs(4).graphics.peout, [5;6]);
+assert_checkequal(o.model.rpar.objs(2).graphics.pin, []);
+assert_checkequal(o.model.rpar.objs(2).graphics.pout, []);
+assert_checkequal(o.model.rpar.objs(2).graphics.pein, 6);
+assert_checkequal(o.model.rpar.objs(2).graphics.peout, 3);
+clear o
+// create a block and connect it
+function o = create_and_connect(fname, pin, pout, pein, peout)
+    o = fname("define");
+    if exists("pin","local") then o.graphics.pin = pin; end
+    if exists("pout","local") then o.graphics.pout = pout; end
+    if exists("pein","local") then o.graphics.pein = pein; end
+    if exists("peout","local") then o.graphics.peout = peout; end
+endfunction
+// create a valid diagram
+scs_m = scicos_diagram(objs=list( ..
+CONST_m("define"), ..
+TRASH_f("define"), ..
+CLOCK_c("define"), ..
+scicos_link(from=[1 1 0],to=[2 1 1]), ..
+scicos_link(from=[3 1 0],to=[2 1 1],ct=[5,-1])));
+assert_checkequal(scs_m.objs(1).graphics.pout, 4);
+assert_checkequal(scs_m.objs(2).graphics.pin, 4);
+assert_checkequal(scs_m.objs(2).graphics.pein, 5);
+assert_checkequal(scs_m.objs(3).graphics.peout, 5);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.pin, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.pout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.pein, 5);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.peout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.pin, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.pout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.pein, 3);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.peout, [5;6]);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.pin, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.pout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.pein, 6);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.peout, 3);
+needcompile = 4;
+[scs_m, %cpr, needcompile, ok] = do_eval(scs_m, list(),struct());
+assert_checkequal(scs_m.objs(1).graphics.pout, 4);
+assert_checkequal(scs_m.objs(2).graphics.pin, 4);
+assert_checkequal(scs_m.objs(2).graphics.pein, 5);
+assert_checkequal(scs_m.objs(3).graphics.peout, 5);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.pin, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.pout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.pein, 5);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.peout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.pin, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.pout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.pein, 3);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.peout, [5;6]);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.pin, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.pout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.pein, 6);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.peout, 3);
diff --git a/scilab/modules/scicos/tests/unit_tests/do_eval.tst b/scilab/modules/scicos/tests/unit_tests/do_eval.tst
new file mode 100644 (file)
index 0000000..2666901
--- /dev/null
@@ -0,0 +1,103 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2016 - Scilab Enterprises - Clement DAVID
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+
+loadXcosLibs();
+
+// check contained blocks interfaces
+o = CONST_m("define");
+assert_checkequal(o.graphics.pin, []);
+assert_checkequal(o.graphics.pout, 0);
+assert_checkequal(o.graphics.pein, []);
+assert_checkequal(o.graphics.peout, []);
+clear o
+
+o = TRASH_f("define");
+assert_checkequal(o.graphics.pin, 0);
+assert_checkequal(o.graphics.pout, []);
+assert_checkequal(o.graphics.pein, 0);
+assert_checkequal(o.graphics.peout, []);
+clear o
+
+o = CLOCK_f("define");
+assert_checkequal(o.graphics.pin, []);
+assert_checkequal(o.graphics.pout, []);
+assert_checkequal(o.graphics.pein, []);
+assert_checkequal(o.graphics.peout, 0);
+
+assert_checkequal(o.model.rpar.objs(1).graphics.pin, []);
+assert_checkequal(o.model.rpar.objs(1).graphics.pout, []);
+assert_checkequal(o.model.rpar.objs(1).graphics.pein, 5);
+assert_checkequal(o.model.rpar.objs(1).graphics.peout, []);
+assert_checkequal(o.model.rpar.objs(4).graphics.pin, []);
+assert_checkequal(o.model.rpar.objs(4).graphics.pout, []);
+assert_checkequal(o.model.rpar.objs(4).graphics.pein, 3);
+assert_checkequal(o.model.rpar.objs(4).graphics.peout, [5;6]);
+assert_checkequal(o.model.rpar.objs(2).graphics.pin, []);
+assert_checkequal(o.model.rpar.objs(2).graphics.pout, []);
+assert_checkequal(o.model.rpar.objs(2).graphics.pein, 6);
+assert_checkequal(o.model.rpar.objs(2).graphics.peout, 3);
+clear o
+
+// create a block and connect it
+function o = create_and_connect(fname, pin, pout, pein, peout)
+    o = fname("define");
+    if exists("pin","local") then o.graphics.pin = pin; end
+    if exists("pout","local") then o.graphics.pout = pout; end
+    if exists("pein","local") then o.graphics.pein = pein; end
+    if exists("peout","local") then o.graphics.peout = peout; end
+endfunction
+
+// create a valid diagram
+scs_m = scicos_diagram(objs=list( ..
+CONST_m("define"), ..
+TRASH_f("define"), ..
+CLOCK_c("define"), ..
+scicos_link(from=[1 1 0],to=[2 1 1]), ..
+scicos_link(from=[3 1 0],to=[2 1 1],ct=[5,-1])));
+
+assert_checkequal(scs_m.objs(1).graphics.pout, 4);
+assert_checkequal(scs_m.objs(2).graphics.pin, 4);
+assert_checkequal(scs_m.objs(2).graphics.pein, 5);
+assert_checkequal(scs_m.objs(3).graphics.peout, 5);
+
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.pin, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.pout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.pein, 5);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.peout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.pin, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.pout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.pein, 3);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.peout, [5;6]);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.pin, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.pout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.pein, 6);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.peout, 3);
+
+needcompile = 4;
+[scs_m, %cpr, needcompile, ok] = do_eval(scs_m, list(),struct());
+
+assert_checkequal(scs_m.objs(1).graphics.pout, 4);
+assert_checkequal(scs_m.objs(2).graphics.pin, 4);
+assert_checkequal(scs_m.objs(2).graphics.pein, 5);
+assert_checkequal(scs_m.objs(3).graphics.peout, 5);
+
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.pin, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.pout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.pein, 5);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(1).graphics.peout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.pin, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.pout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.pein, 3);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(4).graphics.peout, [5;6]);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.pin, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.pout, []);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.pein, 6);
+assert_checkequal(scs_m.objs(3).model.rpar.objs(2).graphics.peout, 3);
+
+
index fc96224..7fad281 100644 (file)
@@ -23,13 +23,13 @@ endfunction
 funcprot(p);
 // Allocate an Annotation
 o = TEXT_f("define")
-Xcos debug: objectCreated( 1 , ANNOTATION )
-Xcos trace: propertyUpdated( 1 , ANNOTATION , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , ANNOTATION , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , ANNOTATION , DESCRIPTION ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , ANNOTATION , FONT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , ANNOTATION , FONT_SIZE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , ANNOTATION , STYLE ) : NO_CHANGES
+Xcos info:    objectCreated( 1 , ANNOTATION )
+Xcos trace:   propertyUpdated( 1 , ANNOTATION , GEOMETRY ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , ANNOTATION , GEOMETRY ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , ANNOTATION , DESCRIPTION ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , ANNOTATION , FONT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , ANNOTATION , FONT_SIZE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , ANNOTATION , STYLE ) : NO_CHANGES
  o  = 
 GUI     : TEXT_f
 Graphics: 
@@ -54,23 +54,15 @@ o.gui
  TEXT_f
 // Modify it
 o = TEXT_f("set", o)
-Xcos debug: objectCreated( 2 , ANNOTATION )
-Xcos trace: propertyUpdated( 2 , ANNOTATION , DESCRIPTION ) : NO_CHANGES
-Xcos trace: propertyUpdated( 2 , ANNOTATION , FONT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 2 , ANNOTATION , FONT_SIZE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 2 , ANNOTATION , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 2 , ANNOTATION , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 2 , ANNOTATION , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 2 , ANNOTATION , PARENT_DIAGRAM ) : NO_CHANGES
-Xcos trace: propertyUpdated( 2 , ANNOTATION , PARENT_BLOCK ) : NO_CHANGES
-Xcos trace: propertyUpdated( 2 , ANNOTATION , RELATED_TO ) : FAIL
-Xcos trace: propertyUpdated( 2 , ANNOTATION , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 2 , ANNOTATION , GEOMETRY ) : SUCCESS
-Xcos trace: propertyUpdated( 2 , ANNOTATION , DESCRIPTION ) : SUCCESS
-Xcos trace: propertyUpdated( 2 , ANNOTATION , FONT ) : SUCCESS
-Xcos trace: propertyUpdated( 2 , ANNOTATION , FONT_SIZE ) : SUCCESS
-Xcos trace: propertyUpdated( 2 , ANNOTATION , STYLE ) : NO_CHANGES
-Xcos debug: objectDeleted( 1 , ANNOTATION )
+Xcos info:    objectCreated( 2 , ANNOTATION )
+Xcos info:    objectCloned( 1 , 2 , ANNOTATION )
+Xcos trace:   propertyUpdated( 2 , ANNOTATION , GEOMETRY ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 2 , ANNOTATION , GEOMETRY ) : SUCCESS
+Xcos debug:   propertyUpdated( 2 , ANNOTATION , DESCRIPTION ) : SUCCESS
+Xcos debug:   propertyUpdated( 2 , ANNOTATION , FONT ) : SUCCESS
+Xcos debug:   propertyUpdated( 2 , ANNOTATION , FONT_SIZE ) : SUCCESS
+Xcos trace:   propertyUpdated( 2 , ANNOTATION , STYLE ) : NO_CHANGES
+Xcos info:    objectDeleted( 1 , ANNOTATION )
  o  = 
 GUI     : TEXT_f
 Graphics: 
@@ -96,4 +88,4 @@ o.gui
  TEXT_f
 // Check that all the model items are freed
 clear
-Xcos debug: objectDeleted( 2 , ANNOTATION )
+Xcos info:    objectDeleted( 2 , ANNOTATION )
index 34a81c3..2af398a 100644 (file)
@@ -9,62 +9,62 @@ loadXcosLibs();
 scicos_log("TRACE");
 // Allocate a summation block
 o = BIGSOM_f("define")
-Xcos debug: objectCreated( 1 , BLOCK )
-Xcos debug: objectReferenced( 1 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 1 , BLOCK ) : 0
-Xcos debug: objectReferenced( 1 , BLOCK ) : 1
-Xcos trace: propertyUpdated( 1 , BLOCK , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , GEOMETRY ) : SUCCESS
-Xcos trace: propertyUpdated( 1 , BLOCK , EXPRS ) : SUCCESS
-Xcos debug: objectCreated( 2 , PORT )
-Xcos trace: propertyUpdated( 2 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 2 , PORT , PORT_KIND ) : SUCCESS
-Xcos debug: objectCreated( 3 , PORT )
-Xcos trace: propertyUpdated( 3 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 3 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 1 , BLOCK , INPUTS ) : SUCCESS
-Xcos debug: objectCreated( 4 , PORT )
-Xcos trace: propertyUpdated( 4 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 4 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 1 , BLOCK , OUTPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 1 , BLOCK , DESCRIPTION ) : NO_CHANGES
-Xcos trace: propertyUpdated( 2 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 3 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 4 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 2 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 3 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 4 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 2 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 3 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 4 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , STYLE ) : NO_CHANGES
-Xcos debug: objectUnreferenced( 1 , BLOCK ) : 0
-Xcos debug: objectReferenced( 1 , BLOCK ) : 1
-Xcos trace: propertyUpdated( 1 , BLOCK , SIM_FUNCTION_NAME ) : SUCCESS
-Xcos trace: propertyUpdated( 1 , BLOCK , SIM_FUNCTION_API ) : SUCCESS
-Xcos trace: propertyUpdated( 2 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 3 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 4 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 1 , BLOCK , STATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , DSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , ODSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , RPAR ) : SUCCESS
-Xcos trace: propertyUpdated( 1 , BLOCK , IPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , OPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , SIM_DEP_UT ) : SUCCESS
-Xcos trace: propertyUpdated( 1 , BLOCK , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , NZCROSS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , NMODE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , EQUATIONS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , UID ) : NO_CHANGES
-Xcos debug: objectUnreferenced( 1 , BLOCK ) : 0
-Xcos trace: propertyUpdated( 1 , BLOCK , INTERFACE_FUNCTION ) : SUCCESS
+Xcos info:    objectCreated( 1 , BLOCK )
+Xcos trace:   objectReferenced( 1 , BLOCK ) : 1
+Xcos trace:   propertyUpdated( 1 , BLOCK , GEOMETRY ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 1 , BLOCK , GEOMETRY ) : SUCCESS
+Xcos debug:   propertyUpdated( 1 , BLOCK , EXPRS ) : SUCCESS
+Xcos info:    objectCreated( 2 , PORT )
+Xcos debug:   propertyUpdated( 2 , PORT , SOURCE_BLOCK ) : SUCCESS
+Xcos debug:   propertyUpdated( 2 , PORT , PORT_KIND ) : SUCCESS
+Xcos info:    objectCreated( 3 , PORT )
+Xcos debug:   propertyUpdated( 3 , PORT , SOURCE_BLOCK ) : SUCCESS
+Xcos debug:   propertyUpdated( 3 , PORT , PORT_KIND ) : SUCCESS
+Xcos debug:   propertyUpdated( 1 , BLOCK , INPUTS ) : SUCCESS
+Xcos info:    objectCreated( 4 , PORT )
+Xcos debug:   propertyUpdated( 4 , PORT , SOURCE_BLOCK ) : SUCCESS
+Xcos debug:   propertyUpdated( 4 , PORT , PORT_KIND ) : SUCCESS
+Xcos debug:   propertyUpdated( 1 , BLOCK , OUTPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 1 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , DESCRIPTION ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 2 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 3 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 4 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 2 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 3 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 4 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 2 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 3 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 4 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , STYLE ) : NO_CHANGES
+Xcos trace:   objectUnreferenced( 1 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 1 , BLOCK ) : 1
+Xcos debug:   propertyUpdated( 1 , BLOCK , SIM_FUNCTION_NAME ) : SUCCESS
+Xcos debug:   propertyUpdated( 1 , BLOCK , SIM_FUNCTION_API ) : SUCCESS
+Xcos debug:   propertyUpdated( 2 , PORT , DATATYPE ) : SUCCESS
+Xcos debug:   propertyUpdated( 3 , PORT , DATATYPE ) : SUCCESS
+Xcos debug:   propertyUpdated( 4 , PORT , DATATYPE ) : SUCCESS
+Xcos trace:   propertyUpdated( 1 , BLOCK , STATE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , DSTATE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , ODSTATE ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 1 , BLOCK , RPAR ) : SUCCESS
+Xcos trace:   propertyUpdated( 1 , BLOCK , IPAR ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , OPAR ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 1 , BLOCK , SIM_DEP_UT ) : SUCCESS
+Xcos trace:   propertyUpdated( 1 , BLOCK , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , NZCROSS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , NMODE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , EQUATIONS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , UID ) : NO_CHANGES
+Xcos trace:   objectUnreferenced( 1 , BLOCK ) : 0
+Xcos debug:   propertyUpdated( 1 , BLOCK , INTERFACE_FUNCTION ) : SUCCESS
  o  = 
 GUI     : BIGSOM_f
 Graphics: 
-Xcos debug: objectReferenced( 1 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 1 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 1 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 1 , BLOCK ) : 0
           orig = [0,0]
           sz = [2,3]
           exprs = "[1;1]"
@@ -82,8 +82,8 @@ Xcos debug: objectUnreferenced( 1 , BLOCK ) : 0
           out_label = ""
           style = ""
 Model   : 
-Xcos debug: objectReferenced( 1 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 1 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 1 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 1 , BLOCK ) : 0
           sum type: 2
           in = [-1;-1]
           in2 = [1;1]
@@ -108,8 +108,8 @@ Xcos debug: objectUnreferenced( 1 , BLOCK ) : 0
           equations = list()
           uid = ""
 o.graphics
-Xcos debug: objectReferenced( 1 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 1 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 1 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 1 , BLOCK ) : 0
  ans  =
 orig = [0,0]
 sz = [2,3]
@@ -128,8 +128,8 @@ in_label = ["";""]
 out_label = ""
 style = ""
 o.model
-Xcos debug: objectReferenced( 1 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 1 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 1 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 1 , BLOCK ) : 0
  ans  =
 sum type: 2
 in = [-1;-1]
@@ -171,132 +171,85 @@ function [ok,sgn,exprs] = scicos_getvalue(title, field, Type, exprs)
 endfunction
 funcprot(p);
 o = BIGSOM_f("set", o)
-Xcos debug: objectReferenced( 1 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 1 , BLOCK ) : 0
-Xcos debug: objectReferenced( 1 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 1 , BLOCK ) : 0
-Xcos debug: objectCreated( 5 , BLOCK )
-Xcos trace: propertyUpdated( 5 , BLOCK , SIM_FUNCTION_API ) : SUCCESS
-Xcos trace: propertyUpdated( 5 , BLOCK , DESCRIPTION ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , INTERFACE_FUNCTION ) : SUCCESS
-Xcos trace: propertyUpdated( 5 , BLOCK , SIM_FUNCTION_NAME ) : SUCCESS
-Xcos trace: propertyUpdated( 5 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , GEOMETRY ) : SUCCESS
-Xcos trace: propertyUpdated( 5 , BLOCK , EXPRS ) : SUCCESS
-Xcos trace: propertyUpdated( 5 , BLOCK , STATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , DSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , ODSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , RPAR ) : SUCCESS
-Xcos trace: propertyUpdated( 5 , BLOCK , OPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , EQUATIONS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , SIM_DEP_UT ) : SUCCESS
-Xcos trace: propertyUpdated( 5 , BLOCK , NZCROSS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , NMODE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , IPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , COLOR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , CONTEXT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
-Xcos debug: objectCreated( 6 , PORT )
-Xcos trace: propertyUpdated( 6 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 6 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 6 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 6 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 6 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 6 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 6 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 6 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 6 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos debug: objectCreated( 7 , PORT )
-Xcos trace: propertyUpdated( 7 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 7 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 7 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 7 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 7 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 7 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 7 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 7 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 7 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , INPUTS ) : SUCCESS
-Xcos debug: objectCreated( 8 , PORT )
-Xcos trace: propertyUpdated( 8 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 8 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 8 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 8 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 8 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 8 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 8 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 8 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 8 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , OUTPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 5 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , PARENT_BLOCK ) : NO_CHANGES
-Xcos debug: objectReferenced( 5 , BLOCK ) : 1
-Xcos trace: propertyUpdated( 5 , BLOCK , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , EXPRS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , DESCRIPTION ) : NO_CHANGES
-Xcos trace: propertyUpdated( 6 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 7 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 8 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 6 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 7 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 8 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 6 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 7 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 8 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , STYLE ) : NO_CHANGES
-Xcos debug: objectUnreferenced( 5 , BLOCK ) : 0
-Xcos debug: objectReferenced( 5 , BLOCK ) : 1
-Xcos trace: propertyUpdated( 5 , BLOCK , SIM_FUNCTION_NAME ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , SIM_FUNCTION_API ) : NO_CHANGES
-Xcos trace: propertyUpdated( 6 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 7 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 6 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 7 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 6 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 7 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 8 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 8 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 8 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , STATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , DSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , ODSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , RPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , IPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , OPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , SIM_DEP_UT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , NZCROSS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , NMODE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , EQUATIONS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , UID ) : NO_CHANGES
-Xcos debug: objectUnreferenced( 5 , BLOCK ) : 0
-Xcos trace: propertyUpdated( 1 , BLOCK , INPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 1 , BLOCK , OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 2 , PORT )
-Xcos trace: propertyUpdated( 1 , BLOCK , INPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 1 , BLOCK , OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 3 , PORT )
-Xcos trace: propertyUpdated( 1 , BLOCK , INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , OUTPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 1 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 1 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 4 , PORT )
-Xcos debug: objectDeleted( 1 , BLOCK )
+Xcos trace:   objectReferenced( 1 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 1 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 1 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 1 , BLOCK ) : 0
+Xcos info:    objectCreated( 5 , BLOCK )
+Xcos info:    objectCloned( 1 , 5 , BLOCK )
+Xcos info:    objectCreated( 6 , PORT )
+Xcos info:    objectCloned( 2 , 6 , PORT )
+Xcos info:    objectCreated( 7 , PORT )
+Xcos info:    objectCloned( 3 , 7 , PORT )
+Xcos info:    objectCreated( 8 , PORT )
+Xcos info:    objectCloned( 4 , 8 , PORT )
+Xcos trace:   objectReferenced( 5 , BLOCK ) : 1
+Xcos trace:   propertyUpdated( 5 , BLOCK , GEOMETRY ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , GEOMETRY ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , EXPRS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , DESCRIPTION ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 6 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 7 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 8 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 6 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 7 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 8 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 6 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 7 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 8 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , STYLE ) : NO_CHANGES
+Xcos trace:   objectUnreferenced( 5 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 5 , BLOCK ) : 1
+Xcos trace:   propertyUpdated( 5 , BLOCK , SIM_FUNCTION_NAME ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , SIM_FUNCTION_API ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 6 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 7 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 6 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 7 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 6 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 7 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 8 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 8 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 8 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , STATE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , DSTATE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , ODSTATE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , RPAR ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , IPAR ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , OPAR ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , SIM_DEP_UT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , NZCROSS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , NMODE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , EQUATIONS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , UID ) : NO_CHANGES
+Xcos trace:   objectUnreferenced( 5 , BLOCK ) : 0
+Xcos debug:   propertyUpdated( 1 , BLOCK , INPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 1 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 2 , PORT )
+Xcos debug:   propertyUpdated( 1 , BLOCK , INPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 1 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 3 , PORT )
+Xcos trace:   propertyUpdated( 1 , BLOCK , INPUTS ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 1 , BLOCK , OUTPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 1 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 1 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 4 , PORT )
+Xcos info:    objectDeleted( 1 , BLOCK )
  o  = 
 GUI     : BIGSOM_f
 Graphics: 
-Xcos debug: objectReferenced( 5 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 5 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 5 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 5 , BLOCK ) : 0
           orig = [0,0]
           sz = [2,3]
           exprs = "[1;1]"
@@ -314,8 +267,8 @@ Xcos debug: objectUnreferenced( 5 , BLOCK ) : 0
           out_label = ""
           style = ""
 Model   : 
-Xcos debug: objectReferenced( 5 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 5 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 5 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 5 , BLOCK ) : 0
           sum type: 2
           in = [-1;-1]
           in2 = [1;1]
@@ -340,8 +293,8 @@ Xcos debug: objectUnreferenced( 5 , BLOCK ) : 0
           equations = list()
           uid = ""
 o.graphics
-Xcos debug: objectReferenced( 5 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 5 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 5 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 5 , BLOCK ) : 0
  ans  =
 orig = [0,0]
 sz = [2,3]
@@ -360,8 +313,8 @@ in_label = ["";""]
 out_label = ""
 style = ""
 o.model
-Xcos debug: objectReferenced( 5 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 5 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 5 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 5 , BLOCK ) : 0
  ans  =
 sum type: 2
 in = [-1;-1]
@@ -396,132 +349,85 @@ function [ok,sgn,exprs] = scicos_getvalue(title, field, Type, exprs)
 endfunction
 funcprot(p);
 o = BIGSOM_f("set", o)
-Xcos debug: objectReferenced( 5 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 5 , BLOCK ) : 0
-Xcos debug: objectReferenced( 5 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 5 , BLOCK ) : 0
-Xcos debug: objectCreated( 9 , BLOCK )
-Xcos trace: propertyUpdated( 9 , BLOCK , SIM_FUNCTION_API ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , DESCRIPTION ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , INTERFACE_FUNCTION ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , SIM_FUNCTION_NAME ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , GEOMETRY ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , EXPRS ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , STATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , DSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , ODSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , RPAR ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , OPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , EQUATIONS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , SIM_DEP_UT ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , NZCROSS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , NMODE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , IPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , COLOR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , CONTEXT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
-Xcos debug: objectCreated( 10 , PORT )
-Xcos trace: propertyUpdated( 10 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 10 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 10 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 10 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 10 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 10 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 10 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 10 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 10 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos debug: objectCreated( 11 , PORT )
-Xcos trace: propertyUpdated( 11 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 11 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 11 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 11 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 11 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 11 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 11 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 11 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 11 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , INPUTS ) : SUCCESS
-Xcos debug: objectCreated( 12 , PORT )
-Xcos trace: propertyUpdated( 12 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 12 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 12 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 12 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 12 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 12 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 12 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 12 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 12 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , OUTPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , PARENT_BLOCK ) : NO_CHANGES
-Xcos debug: objectReferenced( 9 , BLOCK ) : 1
-Xcos trace: propertyUpdated( 9 , BLOCK , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , EXPRS ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , DESCRIPTION ) : NO_CHANGES
-Xcos trace: propertyUpdated( 10 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 11 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 12 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 10 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 11 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 12 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 10 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 11 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 12 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , STYLE ) : NO_CHANGES
-Xcos debug: objectUnreferenced( 9 , BLOCK ) : 0
-Xcos debug: objectReferenced( 9 , BLOCK ) : 1
-Xcos trace: propertyUpdated( 9 , BLOCK , SIM_FUNCTION_NAME ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , SIM_FUNCTION_API ) : NO_CHANGES
-Xcos trace: propertyUpdated( 10 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 11 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 10 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 11 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 10 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 11 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 12 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 12 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 12 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , STATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , DSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , ODSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , RPAR ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , IPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , OPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , SIM_DEP_UT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , NZCROSS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , NMODE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , EQUATIONS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , UID ) : NO_CHANGES
-Xcos debug: objectUnreferenced( 9 , BLOCK ) : 0
-Xcos trace: propertyUpdated( 5 , BLOCK , INPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 5 , BLOCK , OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 6 , PORT )
-Xcos trace: propertyUpdated( 5 , BLOCK , INPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 5 , BLOCK , OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 7 , PORT )
-Xcos trace: propertyUpdated( 5 , BLOCK , INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , OUTPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 5 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 5 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 8 , PORT )
-Xcos debug: objectDeleted( 5 , BLOCK )
+Xcos trace:   objectReferenced( 5 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 5 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 5 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 5 , BLOCK ) : 0
+Xcos info:    objectCreated( 9 , BLOCK )
+Xcos info:    objectCloned( 5 , 9 , BLOCK )
+Xcos info:    objectCreated( 10 , PORT )
+Xcos info:    objectCloned( 6 , 10 , PORT )
+Xcos info:    objectCreated( 11 , PORT )
+Xcos info:    objectCloned( 7 , 11 , PORT )
+Xcos info:    objectCreated( 12 , PORT )
+Xcos info:    objectCloned( 8 , 12 , PORT )
+Xcos trace:   objectReferenced( 9 , BLOCK ) : 1
+Xcos trace:   propertyUpdated( 9 , BLOCK , GEOMETRY ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , GEOMETRY ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 9 , BLOCK , EXPRS ) : SUCCESS
+Xcos trace:   propertyUpdated( 9 , BLOCK , INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , DESCRIPTION ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 10 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 11 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 12 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 10 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 11 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 12 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 10 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 11 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 12 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , STYLE ) : NO_CHANGES
+Xcos trace:   objectUnreferenced( 9 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 9 , BLOCK ) : 1
+Xcos trace:   propertyUpdated( 9 , BLOCK , SIM_FUNCTION_NAME ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , SIM_FUNCTION_API ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 10 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 11 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 10 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 11 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 10 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 11 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 12 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 12 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 12 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , STATE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , DSTATE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , ODSTATE ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 9 , BLOCK , RPAR ) : SUCCESS
+Xcos trace:   propertyUpdated( 9 , BLOCK , IPAR ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , OPAR ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , SIM_DEP_UT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , NZCROSS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , NMODE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , EQUATIONS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , UID ) : NO_CHANGES
+Xcos trace:   objectUnreferenced( 9 , BLOCK ) : 0
+Xcos debug:   propertyUpdated( 5 , BLOCK , INPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 5 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 6 , PORT )
+Xcos debug:   propertyUpdated( 5 , BLOCK , INPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 5 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 7 , PORT )
+Xcos trace:   propertyUpdated( 5 , BLOCK , INPUTS ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 5 , BLOCK , OUTPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 5 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 5 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 8 , PORT )
+Xcos info:    objectDeleted( 5 , BLOCK )
  o  = 
 GUI     : BIGSOM_f
 Graphics: 
-Xcos debug: objectReferenced( 9 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 9 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 9 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 9 , BLOCK ) : 0
           orig = [0,0]
           sz = [2,3]
           exprs = "[-1;-1]"
@@ -539,8 +445,8 @@ Xcos debug: objectUnreferenced( 9 , BLOCK ) : 0
           out_label = ""
           style = ""
 Model   : 
-Xcos debug: objectReferenced( 9 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 9 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 9 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 9 , BLOCK ) : 0
           sum type: 2
           in = [-1;-1]
           in2 = [1;1]
@@ -565,8 +471,8 @@ Xcos debug: objectUnreferenced( 9 , BLOCK ) : 0
           equations = list()
           uid = ""
 o.graphics
-Xcos debug: objectReferenced( 9 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 9 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 9 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 9 , BLOCK ) : 0
  ans  =
 orig = [0,0]
 sz = [2,3]
@@ -585,8 +491,8 @@ in_label = ["";""]
 out_label = ""
 style = ""
 o.model
-Xcos debug: objectReferenced( 9 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 9 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 9 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 9 , BLOCK ) : 0
  ans  =
 sum type: 2
 in = [-1;-1]
@@ -621,136 +527,88 @@ function [ok,sgn,exprs] = scicos_getvalue(title, field, Type, exprs)
 endfunction
 funcprot(p);
 o = BIGSOM_f("set", o)
-Xcos debug: objectReferenced( 9 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 9 , BLOCK ) : 0
-Xcos debug: objectReferenced( 9 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 9 , BLOCK ) : 0
-Xcos debug: objectCreated( 13 , BLOCK )
-Xcos trace: propertyUpdated( 13 , BLOCK , SIM_FUNCTION_API ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , DESCRIPTION ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , INTERFACE_FUNCTION ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , SIM_FUNCTION_NAME ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , GEOMETRY ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , EXPRS ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , STATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , DSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , ODSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , RPAR ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , OPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , EQUATIONS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , SIM_DEP_UT ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , NZCROSS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , NMODE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , IPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , COLOR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , CONTEXT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
-Xcos debug: objectCreated( 14 , PORT )
-Xcos trace: propertyUpdated( 14 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 14 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 14 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 14 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 14 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 14 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 14 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 14 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 14 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos debug: objectCreated( 15 , PORT )
-Xcos trace: propertyUpdated( 15 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 15 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 15 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 15 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 15 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 15 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 15 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 15 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 15 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , INPUTS ) : SUCCESS
-Xcos debug: objectCreated( 16 , PORT )
-Xcos trace: propertyUpdated( 16 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 16 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 16 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 16 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 16 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 16 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 16 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 16 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 16 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , OUTPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , PARENT_BLOCK ) : NO_CHANGES
-Xcos debug: objectReferenced( 13 , BLOCK ) : 1
-Xcos trace: propertyUpdated( 13 , BLOCK , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , EXPRS ) : SUCCESS
-Xcos debug: objectCreated( 17 , PORT )
-Xcos trace: propertyUpdated( 17 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 17 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , INPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , DESCRIPTION ) : NO_CHANGES
-Xcos trace: propertyUpdated( 14 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 15 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 17 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 16 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 14 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 15 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 17 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 16 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 14 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 15 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 17 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 16 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , STYLE ) : NO_CHANGES
-Xcos debug: objectUnreferenced( 13 , BLOCK ) : 0
-Xcos debug: objectReferenced( 13 , BLOCK ) : 1
-Xcos trace: propertyUpdated( 13 , BLOCK , SIM_FUNCTION_NAME ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , SIM_FUNCTION_API ) : NO_CHANGES
-Xcos trace: propertyUpdated( 14 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 15 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 17 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 16 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 16 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 16 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , STATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , DSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , ODSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , RPAR ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , IPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , OPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , SIM_DEP_UT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , NZCROSS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , NMODE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , EQUATIONS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , UID ) : NO_CHANGES
-Xcos debug: objectUnreferenced( 13 , BLOCK ) : 0
-Xcos trace: propertyUpdated( 9 , BLOCK , INPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 10 , PORT )
-Xcos trace: propertyUpdated( 9 , BLOCK , INPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 11 , PORT )
-Xcos trace: propertyUpdated( 9 , BLOCK , INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , OUTPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 9 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 9 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 12 , PORT )
-Xcos debug: objectDeleted( 9 , BLOCK )
+Xcos trace:   objectReferenced( 9 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 9 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 9 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 9 , BLOCK ) : 0
+Xcos info:    objectCreated( 13 , BLOCK )
+Xcos info:    objectCloned( 9 , 13 , BLOCK )
+Xcos info:    objectCreated( 14 , PORT )
+Xcos info:    objectCloned( 10 , 14 , PORT )
+Xcos info:    objectCreated( 15 , PORT )
+Xcos info:    objectCloned( 11 , 15 , PORT )
+Xcos info:    objectCreated( 16 , PORT )
+Xcos info:    objectCloned( 12 , 16 , PORT )
+Xcos trace:   objectReferenced( 13 , BLOCK ) : 1
+Xcos trace:   propertyUpdated( 13 , BLOCK , GEOMETRY ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , GEOMETRY ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 13 , BLOCK , EXPRS ) : SUCCESS
+Xcos info:    objectCreated( 17 , PORT )
+Xcos debug:   propertyUpdated( 17 , PORT , SOURCE_BLOCK ) : SUCCESS
+Xcos debug:   propertyUpdated( 17 , PORT , PORT_KIND ) : SUCCESS
+Xcos debug:   propertyUpdated( 13 , BLOCK , INPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 13 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , DESCRIPTION ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 14 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 15 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 17 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 16 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 14 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 15 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 17 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 16 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 14 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 15 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 17 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 16 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , STYLE ) : NO_CHANGES
+Xcos trace:   objectUnreferenced( 13 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 13 , BLOCK ) : 1
+Xcos trace:   propertyUpdated( 13 , BLOCK , SIM_FUNCTION_NAME ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , SIM_FUNCTION_API ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 14 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 15 , PORT , DATATYPE ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 17 , PORT , DATATYPE ) : SUCCESS
+Xcos trace:   propertyUpdated( 16 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 16 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 16 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , STATE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , DSTATE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , ODSTATE ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 13 , BLOCK , RPAR ) : SUCCESS
+Xcos trace:   propertyUpdated( 13 , BLOCK , IPAR ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , OPAR ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , SIM_DEP_UT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , NZCROSS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , NMODE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , EQUATIONS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , UID ) : NO_CHANGES
+Xcos trace:   objectUnreferenced( 13 , BLOCK ) : 0
+Xcos debug:   propertyUpdated( 9 , BLOCK , INPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 9 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 10 , PORT )
+Xcos debug:   propertyUpdated( 9 , BLOCK , INPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 9 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 11 , PORT )
+Xcos trace:   propertyUpdated( 9 , BLOCK , INPUTS ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 9 , BLOCK , OUTPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 9 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 9 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 12 , PORT )
+Xcos info:    objectDeleted( 9 , BLOCK )
  o  = 
 GUI     : BIGSOM_f
 Graphics: 
-Xcos debug: objectReferenced( 13 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 13 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 13 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 13 , BLOCK ) : 0
           orig = [0,0]
           sz = [2,3]
           exprs = "[-1;1;1]"
@@ -768,8 +626,8 @@ Xcos debug: objectUnreferenced( 13 , BLOCK ) : 0
           out_label = ""
           style = ""
 Model   : 
-Xcos debug: objectReferenced( 13 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 13 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 13 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 13 , BLOCK ) : 0
           sum type: 2
           in = [-1;-1;-1]
           in2 = [1;1;1]
@@ -794,8 +652,8 @@ Xcos debug: objectUnreferenced( 13 , BLOCK ) : 0
           equations = list()
           uid = ""
 o.graphics
-Xcos debug: objectReferenced( 13 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 13 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 13 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 13 , BLOCK ) : 0
  ans  =
 orig = [0,0]
 sz = [2,3]
@@ -814,8 +672,8 @@ in_label = ["";"";""]
 out_label = ""
 style = ""
 o.model
-Xcos debug: objectReferenced( 13 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 13 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 13 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 13 , BLOCK ) : 0
  ans  =
 sum type: 2
 in = [-1;-1;-1]
@@ -850,149 +708,93 @@ function [ok,sgn,exprs] = scicos_getvalue(title, field, Type, exprs)
 endfunction
 funcprot(p);
 o = BIGSOM_f("set", o)
-Xcos debug: objectReferenced( 13 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 13 , BLOCK ) : 0
-Xcos debug: objectReferenced( 13 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 13 , BLOCK ) : 0
-Xcos debug: objectCreated( 18 , BLOCK )
-Xcos trace: propertyUpdated( 18 , BLOCK , SIM_FUNCTION_API ) : SUCCESS
-Xcos trace: propertyUpdated( 18 , BLOCK , DESCRIPTION ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , INTERFACE_FUNCTION ) : SUCCESS
-Xcos trace: propertyUpdated( 18 , BLOCK , SIM_FUNCTION_NAME ) : SUCCESS
-Xcos trace: propertyUpdated( 18 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , GEOMETRY ) : SUCCESS
-Xcos trace: propertyUpdated( 18 , BLOCK , EXPRS ) : SUCCESS
-Xcos trace: propertyUpdated( 18 , BLOCK , STATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , DSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , ODSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , RPAR ) : SUCCESS
-Xcos trace: propertyUpdated( 18 , BLOCK , OPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , EQUATIONS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , SIM_DEP_UT ) : SUCCESS
-Xcos trace: propertyUpdated( 18 , BLOCK , NZCROSS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , NMODE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , IPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , COLOR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , CONTEXT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , PARENT_DIAGRAM ) : NO_CHANGES
-Xcos debug: objectCreated( 19 , PORT )
-Xcos trace: propertyUpdated( 19 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 19 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 19 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 19 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 19 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 19 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 19 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 19 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 19 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos debug: objectCreated( 20 , PORT )
-Xcos trace: propertyUpdated( 20 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 20 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 20 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 20 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 20 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 20 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 20 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 20 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 20 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos debug: objectCreated( 21 , PORT )
-Xcos trace: propertyUpdated( 21 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 21 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 21 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 21 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 21 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 21 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 21 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 21 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 21 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , INPUTS ) : SUCCESS
-Xcos debug: objectCreated( 22 , PORT )
-Xcos trace: propertyUpdated( 22 , PORT , FIRING ) : NO_CHANGES
-Xcos trace: propertyUpdated( 22 , PORT , PORT_KIND ) : SUCCESS
-Xcos trace: propertyUpdated( 22 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 22 , PORT , UID ) : NO_CHANGES
-Xcos trace: propertyUpdated( 22 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 22 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 22 , PORT , DATATYPE ) : SUCCESS
-Xcos trace: propertyUpdated( 22 , PORT , SOURCE_BLOCK ) : SUCCESS
-Xcos trace: propertyUpdated( 22 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , OUTPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 18 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , PARENT_BLOCK ) : NO_CHANGES
-Xcos debug: objectReferenced( 18 , BLOCK ) : 1
-Xcos trace: propertyUpdated( 18 , BLOCK , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , GEOMETRY ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , EXPRS ) : SUCCESS
-Xcos trace: propertyUpdated( 18 , BLOCK , INPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 18 , BLOCK , INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 21 , PORT )
-Xcos trace: propertyUpdated( 18 , BLOCK , DESCRIPTION ) : NO_CHANGES
-Xcos trace: propertyUpdated( 19 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 20 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 22 , PORT , IMPLICIT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 19 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 20 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 22 , PORT , STYLE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 19 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 20 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 22 , PORT , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , STYLE ) : NO_CHANGES
-Xcos debug: objectUnreferenced( 18 , BLOCK ) : 0
-Xcos debug: objectReferenced( 18 , BLOCK ) : 1
-Xcos trace: propertyUpdated( 18 , BLOCK , SIM_FUNCTION_NAME ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , SIM_FUNCTION_API ) : NO_CHANGES
-Xcos trace: propertyUpdated( 19 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 20 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 22 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 22 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 22 , PORT , DATATYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , STATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , DSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , ODSTATE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , RPAR ) : SUCCESS
-Xcos trace: propertyUpdated( 18 , BLOCK , IPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , OPAR ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , SIM_DEP_UT ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , LABEL ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , NZCROSS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , NMODE ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , EQUATIONS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 18 , BLOCK , UID ) : NO_CHANGES
-Xcos debug: objectUnreferenced( 18 , BLOCK ) : 0
-Xcos trace: propertyUpdated( 13 , BLOCK , INPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 14 , PORT )
-Xcos trace: propertyUpdated( 13 , BLOCK , INPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 15 , PORT )
-Xcos trace: propertyUpdated( 13 , BLOCK , INPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , OUTPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 17 , PORT )
-Xcos trace: propertyUpdated( 13 , BLOCK , INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , OUTPUTS ) : SUCCESS
-Xcos trace: propertyUpdated( 13 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
-Xcos trace: propertyUpdated( 13 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
-Xcos debug: objectDeleted( 16 , PORT )
-Xcos debug: objectDeleted( 13 , BLOCK )
+Xcos trace:   objectReferenced( 13 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 13 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 13 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 13 , BLOCK ) : 0
+Xcos info:    objectCreated( 18 , BLOCK )
+Xcos info:    objectCloned( 13 , 18 , BLOCK )
+Xcos info:    objectCreated( 19 , PORT )
+Xcos info:    objectCloned( 14 , 19 , PORT )
+Xcos info:    objectCreated( 20 , PORT )
+Xcos info:    objectCloned( 15 , 20 , PORT )
+Xcos info:    objectCreated( 21 , PORT )
+Xcos info:    objectCloned( 17 , 21 , PORT )
+Xcos info:    objectCreated( 22 , PORT )
+Xcos info:    objectCloned( 16 , 22 , PORT )
+Xcos trace:   objectReferenced( 18 , BLOCK ) : 1
+Xcos trace:   propertyUpdated( 18 , BLOCK , GEOMETRY ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , GEOMETRY ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 18 , BLOCK , EXPRS ) : SUCCESS
+Xcos debug:   propertyUpdated( 18 , BLOCK , INPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 18 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 21 , PORT )
+Xcos trace:   propertyUpdated( 18 , BLOCK , INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , DESCRIPTION ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 19 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 20 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 22 , PORT , IMPLICIT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 19 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 20 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 22 , PORT , STYLE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 19 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 20 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 22 , PORT , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , STYLE ) : NO_CHANGES
+Xcos trace:   objectUnreferenced( 18 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 18 , BLOCK ) : 1
+Xcos trace:   propertyUpdated( 18 , BLOCK , SIM_FUNCTION_NAME ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , SIM_FUNCTION_API ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 19 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 20 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 22 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 22 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 22 , PORT , DATATYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , STATE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , DSTATE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , ODSTATE ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 18 , BLOCK , RPAR ) : SUCCESS
+Xcos trace:   propertyUpdated( 18 , BLOCK , IPAR ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , OPAR ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , SIM_DEP_UT ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , LABEL ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , NZCROSS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , NMODE ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , EQUATIONS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 18 , BLOCK , UID ) : NO_CHANGES
+Xcos trace:   objectUnreferenced( 18 , BLOCK ) : 0
+Xcos debug:   propertyUpdated( 13 , BLOCK , INPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 13 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 14 , PORT )
+Xcos debug:   propertyUpdated( 13 , BLOCK , INPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 13 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 15 , PORT )
+Xcos debug:   propertyUpdated( 13 , BLOCK , INPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 13 , BLOCK , OUTPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 17 , PORT )
+Xcos trace:   propertyUpdated( 13 , BLOCK , INPUTS ) : NO_CHANGES
+Xcos debug:   propertyUpdated( 13 , BLOCK , OUTPUTS ) : SUCCESS
+Xcos trace:   propertyUpdated( 13 , BLOCK , EVENT_INPUTS ) : NO_CHANGES
+Xcos trace:   propertyUpdated( 13 , BLOCK , EVENT_OUTPUTS ) : NO_CHANGES
+Xcos info:    objectDeleted( 16 , PORT )
+Xcos info:    objectDeleted( 13 , BLOCK )
  o  = 
 GUI     : BIGSOM_f
 Graphics: 
-Xcos debug: objectReferenced( 18 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 18 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 18 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 18 , BLOCK ) : 0
           orig = [0,0]
           sz = [2,3]
           exprs = "[1;1]"
@@ -1010,8 +812,8 @@ Xcos debug: objectUnreferenced( 18 , BLOCK ) : 0
           out_label = ""
           style = ""
 Model   : 
-Xcos debug: objectReferenced( 18 , BLOCK ) : 1
-Xcos debug: objectUnreferenced( 18 , BLOCK ) : 0
+Xcos trace:   objectReferenced( 18 , BLOCK ) : 1
+Xcos trace:   objectUnreferenced( 18 , BLOCK ) : 0
           sum type: 2
       &n