Xcos MVC: fix LinkAdapter to with IDs instead of indexes 92/15192/10
Paul Bignier [Wed, 10 Sep 2014 08:08:11 +0000 (10:08 +0200)]
 * fixed the from setter and getter to mind the third input element.
 * complicated the test by using two different blocks and controlling their
   properties.

Change-Id: I0dac595ab05c2f48d65d01e9c765025046ace004

scilab/modules/scicos/macros/scicos_scicos/%s_i_Link.sci
scilab/modules/scicos/src/cpp/Model_getObjectProperties.cpp
scilab/modules/scicos/src/cpp/view_scilab/LinkAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/ports_management.hxx
scilab/modules/scicos/tests/unit_tests/model/Block.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Diagram.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Diagram.tst

index e9b2d31..5a8472d 100644 (file)
@@ -19,6 +19,6 @@
 // See the file ../license.txt
 //
 
-function m=%s_i_Link(i,b,L)
+function L=%s_i_Link(i,b,L)
     scicos_setfield(i,b,L)
 endfunction
index 91b2360..c92fc09 100644 (file)
@@ -346,6 +346,9 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, Sci
         model::Port* o = static_cast<model::Port*>(getObject(uid));
         switch (p)
         {
+            case SOURCE_BLOCK:
+                o->getSourceBlock(v);
+                return true;
             case CONNECTED_SIGNALS:
                 v = o->getConnectedSignals().front();
                 return true;
index f639337..e70884b 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <string>
 #include <vector>
+#include <iterator>
 #include <algorithm>
 
 #include "internal.hxx"
@@ -22,6 +23,8 @@
 
 #include "Controller.hxx"
 #include "LinkAdapter.hxx"
+#include "model/Port.hxx"
+#include "model/Link.hxx"
 
 extern "C" {
 #include "sci_malloc.h"
@@ -278,17 +281,55 @@ static types::Double* getLinkEnd(const LinkAdapter& adaptor, const Controller& c
     {
         ScicosID sourceBlock;
         controller.getObjectProperty(endID, PORT, SOURCE_BLOCK, sourceBlock);
-        int kind;
-        controller.getObjectProperty(endID, PORT, PORT_KIND, kind);
 
-        data[0] = static_cast<double>(sourceBlock);
-        data[1] = static_cast<double>(endID);
-        data[2] = static_cast<double>(kind);
+        // Looking for the block number among the block IDs
+        ScicosID parentDiagram;
+        controller.getObjectProperty(adaptee->id(), BLOCK, PARENT_DIAGRAM, parentDiagram);
+        std::vector<ScicosID> children;
+        if (parentDiagram == 0)
+        {
+            return o;
+        }
+        controller.getObjectProperty(parentDiagram, DIAGRAM, CHILDREN, children);
+        data[0] = static_cast<double>(std::distance(children.begin(), std::find(children.begin(), children.end(), sourceBlock)) + 1);
+
+        std::vector<ScicosID> sourceBlockPorts;
+        switch (end)
+        {
+            case SOURCE_PORT:
+                controller.getObjectProperty(sourceBlock, BLOCK, OUTPUTS, sourceBlockPorts);
+                break;
+            case DESTINATION_PORT:
+                controller.getObjectProperty(sourceBlock, BLOCK, INPUTS, sourceBlockPorts);
+                break;
+            default:
+                return 0;
+        }
+        data[1] = static_cast<double>(std::distance(sourceBlockPorts.begin(), std::find(sourceBlockPorts.begin(), sourceBlockPorts.end(), endID)) + 1);
+
+        bool isImplicit;
+        controller.getObjectProperty(endID, PORT, IMPLICIT, isImplicit);
+
+        if (isImplicit == false)
+        {
+            int kind;
+            controller.getObjectProperty(endID, PORT, PORT_KIND, kind);
+            if (kind == model::IN || kind == model::EIN)
+            {
+                data[2] = 1;
+            }
+        }
     }
     // Default case, the property was initialized at [].
     return o;
 }
 
+enum startOrEnd
+{
+    Start = 0,
+    End = 1
+};
+
 static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_properties_t end, types::InternalType* v)
 {
     model::Link* adaptee = adaptor.getAdaptee();
@@ -310,19 +351,19 @@ static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_prop
     ScicosID to;
     controller.getObjectProperty(adaptee->id(), adaptee->kind(), DESTINATION_PORT, to);
     ScicosID concernedPort;
+    ScicosID otherPort;
     object_properties_t otherEnd;
-    object_properties_t portType;
     switch (end)
     {
         case SOURCE_PORT:
             concernedPort = from;
+            otherPort = to;
             otherEnd = DESTINATION_PORT;
-            portType = OUTPUTS;
             break;
         case DESTINATION_PORT:
             concernedPort = to;
+            otherPort = from;
             otherEnd = SOURCE_PORT;
-            portType = INPUTS;
             break;
         default:
             return false;
@@ -351,7 +392,7 @@ static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_prop
 
     if (current->get(2) != 0 && current->get(2) != 1)
     {
-        return false; // "From" port must be output type or implicit.
+        return false;
     }
 
     if (floor(current->get(0)) != current->get(0) || floor(current->get(1)) != current->get(1))
@@ -360,30 +401,207 @@ static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_prop
     }
 
     // Disconnect the old port if it was connected
-    if (from != 0)
+    if (concernedPort != 0)
     {
         controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, unconnected);
     }
 
+    ScicosID parentDiagram;
+    controller.getObjectProperty(adaptee->id(), BLOCK, PARENT_DIAGRAM, parentDiagram);
+    std::vector<ScicosID> children;
+    if (parentDiagram != 0)
+    {
+        controller.getObjectProperty(parentDiagram, DIAGRAM, CHILDREN, children);
+    }
+
     // Connect the new one
     int blk  = static_cast<int>(current->get(0));
     int port = static_cast<int>(current->get(1));
     int kind = static_cast<int>(current->get(2));
+    if (kind != Start && kind != End)
+    {
+        return false;
+    }
+    // kind == 0: trying to set the start of the link (output port)
+    // kind == 1: trying to set the end of the link (input port)
+
+    if (blk < 0 || blk > static_cast<int>(children.size()))
+    {
+        return false; // Trying to link to a non-existing block
+    }
+    ScicosID blkID = children[blk - 1];
+
     std::vector<ScicosID> sourceBlockPorts;
-    controller.getObjectProperty(blk, BLOCK, portType, sourceBlockPorts);
-    int nBlockPorts = (int)sourceBlockPorts.size();
-    // Create as many ports as necessary
-    while (nBlockPorts < port)
+    int nBlockPorts;
+    bool newPortIsImplicit = false;
+    int newPortKind = static_cast<int>(model::UNDEF);
+    int linkType;
+    controller.getObjectProperty(adaptee->id(), adaptee->kind(), KIND, linkType);
+    if (linkType == model::activation)
+    {
+        std::vector<ScicosID> evtin;
+        std::vector<ScicosID> evtout;
+        controller.getObjectProperty(blkID, BLOCK, EVENT_INPUTS, evtin);
+        controller.getObjectProperty(blkID, BLOCK, EVENT_OUTPUTS, evtout);
+
+        if (kind == Start)
+        {
+            if (otherPort != 0)
+            {
+                // The other end must be an input
+                int otherPortKind;
+                controller.getObjectProperty(otherPort, PORT, PORT_KIND, otherPortKind);
+                if (otherPortKind != model::EIN)
+                {
+                    return false;
+                }
+            }
+            newPortKind = static_cast<int>(model::EOUT);
+            sourceBlockPorts = evtout;
+        }
+        else
+        {
+            if (otherPort != 0)
+            {
+                // The other end must be an output
+                int otherPortKind;
+                controller.getObjectProperty(otherPort, PORT, PORT_KIND, otherPortKind);
+                if (otherPortKind != model::EOUT)
+                {
+                    return false;
+                }
+            }
+            newPortKind = static_cast<int>(model::EIN);
+            sourceBlockPorts = evtin;
+        }
+
+    }
+    else if (linkType == model::regular || linkType == model::implicit)
+    {
+        std::vector<ScicosID> in;
+        std::vector<ScicosID> out;
+        controller.getObjectProperty(blkID, BLOCK, INPUTS, in);
+        controller.getObjectProperty(blkID, BLOCK, OUTPUTS, out);
+
+        if (linkType == model::regular)
+        {
+            if (kind == Start)
+            {
+                if (otherPort != 0)
+                {
+                    // The other end must be an input
+                    int otherPortKind;
+                    controller.getObjectProperty(otherPort, PORT, PORT_KIND, otherPortKind);
+                    if (otherPortKind != model::IN)
+                    {
+                        return false;
+                    }
+                }
+                newPortKind = static_cast<int>(model::OUT);
+                sourceBlockPorts = out;
+            }
+            else
+            {
+                if (otherPort != 0)
+                {
+                    // The other end must be an output
+                    int otherPortKind = 1;
+                    controller.getObjectProperty(otherPort, PORT, PORT_KIND, otherPortKind);
+                    if (otherPortKind != model::OUT)
+                    {
+                        return false;
+                    }
+                }
+                newPortKind = static_cast<int>(model::IN);
+                sourceBlockPorts = in;
+            }
+
+            // Rule out the implicit ports
+            for (std::vector<ScicosID>::iterator it = sourceBlockPorts.begin(); it != sourceBlockPorts.end(); ++it)
+            {
+                bool isImplicit;
+                controller.getObjectProperty(*it, PORT, IMPLICIT, isImplicit);
+                if (isImplicit == true)
+                {
+                    sourceBlockPorts.erase(it);
+                }
+            }
+        }
+        else // model::implicit
+        {
+            newPortIsImplicit = true;
+            sourceBlockPorts.insert(sourceBlockPorts.begin(), in.begin(), in.end());
+            sourceBlockPorts.insert(sourceBlockPorts.begin(), out.begin(), out.end());
+
+            // Rule out the explicit ports
+            for (std::vector<ScicosID>::iterator it = sourceBlockPorts.begin(); it != sourceBlockPorts.end(); ++it)
+            {
+                bool isImplicit;
+                controller.getObjectProperty(*it, PORT, IMPLICIT, isImplicit);
+                if (isImplicit == false)
+                {
+                    sourceBlockPorts.erase(it);
+                }
+            }
+        }
+    }
+
+    nBlockPorts = static_cast<int>(sourceBlockPorts.size());
+    if (nBlockPorts >= port)
+    {
+        concernedPort = sourceBlockPorts[port - 1];
+    }
+    else
     {
-        ScicosID createdPort = controller.createObject(PORT);
-        controller.setObjectProperty(createdPort, PORT, SOURCE_BLOCK, blk);
-        controller.setObjectProperty(createdPort, PORT, CONNECTED_SIGNALS, unconnected);
-        nBlockPorts++;
+        while (nBlockPorts < port) // Create as many ports as necessary
+        {
+            concernedPort = controller.createObject(PORT);
+            controller.setObjectProperty(concernedPort, PORT, IMPLICIT, newPortIsImplicit);
+            controller.setObjectProperty(concernedPort, PORT, PORT_KIND, newPortKind);
+            controller.setObjectProperty(concernedPort, PORT, SOURCE_BLOCK, blkID);
+            controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, unconnected);
+            std::vector<int> dataType;
+            controller.getObjectProperty(concernedPort, PORT, DATATYPE, dataType);
+            dataType[0] = -1; // Default number of rows for new ports
+            controller.setObjectProperty(concernedPort, PORT, DATATYPE, dataType);
+
+            std::vector<ScicosID> concernedPorts;
+            if (linkType == model::activation)
+            {
+                if (kind == Start)
+                {
+                    controller.getObjectProperty(blkID, BLOCK, EVENT_OUTPUTS, concernedPorts);
+                    concernedPorts.push_back(concernedPort);
+                    controller.setObjectProperty(blkID, BLOCK, EVENT_OUTPUTS, concernedPorts);
+                }
+                else
+                {
+                    controller.getObjectProperty(blkID, BLOCK, EVENT_INPUTS, concernedPorts);
+                    concernedPorts.push_back(concernedPort);
+                    controller.setObjectProperty(blkID, BLOCK, EVENT_INPUTS, concernedPorts);
+                }
+            }
+            else // model::regular || model::implicit
+            {
+                if (kind == Start)
+                {
+                    controller.getObjectProperty(blkID, BLOCK, OUTPUTS, concernedPorts);
+                    concernedPorts.push_back(concernedPort);
+                    controller.setObjectProperty(blkID, BLOCK, OUTPUTS, concernedPorts);
+                }
+                else
+                {
+                    controller.getObjectProperty(blkID, BLOCK, INPUTS, concernedPorts);
+                    concernedPorts.push_back(concernedPort);
+                    controller.setObjectProperty(blkID, BLOCK, INPUTS, concernedPorts);
+                }
+            }
+
+            nBlockPorts++;
+        }
     }
-    controller.getObjectProperty(blk, BLOCK, portType, sourceBlockPorts);
-    ScicosID newPort = sourceBlockPorts[port - 1];
     ScicosID oldLink;
-    controller.getObjectProperty(newPort, PORT, CONNECTED_SIGNALS, oldLink);
+    controller.getObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, oldLink);
     if (oldLink != 0)
     {
         // Disconnect the old other end port and delete the old link
@@ -394,10 +612,8 @@ static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_prop
     }
 
     // Connect the new source and destination ports together
-    controller.setObjectProperty(newPort, PORT, PORT_KIND, kind);
-    controller.setObjectProperty(newPort, PORT, CONNECTED_SIGNALS, adaptee->id());
     controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, adaptee->id());
-    controller.setObjectProperty(adaptee->id(), adaptee->kind(), end, newPort);
+    controller.setObjectProperty(adaptee->id(), adaptee->kind(), end, concernedPort);
     return true;
 }
 
index 3fc0dcf..610f8d5 100644 (file)
@@ -23,6 +23,7 @@
 #include "string.hxx"
 
 #include "Controller.hxx"
+#include "model/Port.hxx"
 
 extern "C" {
 #include "sci_malloc.h"
@@ -127,7 +128,7 @@ types::InternalType* get_ports_property(const Adaptor& adaptor, object_propertie
 
                 if (found != children.end())
                 {
-                    v[i] = (double)std::distance(found, children.begin());
+                    v[i] = (double)std::distance(children.begin(), found) + 1;
                 }
                 else
                 {
@@ -547,6 +548,23 @@ bool update_ports_property(const Adaptor& adaptor, object_properties_t port_kind
 
             ScicosID id = controller.createObject(PORT);
             controller.setObjectProperty(id, PORT, SOURCE_BLOCK, adaptee->id());
+            switch (port_kind)
+            {
+                case INPUTS:
+                    controller.setObjectProperty(id, PORT, PORT_KIND, model::IN);
+                    break;
+                case OUTPUTS:
+                    controller.setObjectProperty(id, PORT, PORT_KIND, model::OUT);
+                    break;
+                case EVENT_INPUTS:
+                    controller.setObjectProperty(id, PORT, PORT_KIND, model::EIN);
+                    break;
+                case EVENT_OUTPUTS:
+                    controller.setObjectProperty(id, PORT, PORT_KIND, model::EOUT);
+                    break;
+                default:
+                    return false;
+            }
             addNewPort<Adaptor, p>(id, newPort, children, controller);
             previousPorts.push_back(id);
         }
index 78d3d08..eb7135f 100644 (file)
@@ -15,11 +15,14 @@ propertyUpdated( 1 , BLOCK , ANGLE ) : NO_CHANGES
 propertyUpdated( 1 , BLOCK , EXPRS ) : SUCCESS
 objectCreated( 2 , PORT )
 propertyUpdated( 2 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 2 , PORT , PORT_KIND ) : SUCCESS
 objectCreated( 3 , PORT )
 propertyUpdated( 3 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 3 , PORT , PORT_KIND ) : SUCCESS
 propertyUpdated( 1 , BLOCK , INPUTS ) : SUCCESS
 objectCreated( 4 , PORT )
 propertyUpdated( 4 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 4 , PORT , PORT_KIND ) : SUCCESS
 propertyUpdated( 1 , BLOCK , OUTPUTS ) : SUCCESS
 propertyUpdated( 1 , BLOCK , LABEL ) : NO_CHANGES
 propertyUpdated( 2 , PORT , IMPLICIT ) : NO_CHANGES
@@ -313,6 +316,7 @@ propertyUpdated( 1 , BLOCK , ANGLE ) : NO_CHANGES
 propertyUpdated( 1 , BLOCK , EXPRS ) : SUCCESS
 objectCreated( 5 , PORT )
 propertyUpdated( 5 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 5 , PORT , PORT_KIND ) : SUCCESS
 propertyUpdated( 1 , BLOCK , INPUTS ) : SUCCESS
 propertyUpdated( 1 , BLOCK , LABEL ) : NO_CHANGES
 propertyUpdated( 2 , PORT , IMPLICIT ) : NO_CHANGES
index 50104f2..10252cb 100644 (file)
@@ -43,7 +43,7 @@ scs_m.contrib
  ans  =
 ()
 // Create a diagram containing 2 summation blocks and an empty link
-blk  = BIGSOM_f("define");
+Sum   = BIGSOM_f("define");
 objectCreated( 2 , BLOCK )
 propertyUpdated( 2 , BLOCK , GEOMETRY ) : NO_CHANGES
 propertyUpdated( 2 , BLOCK , GEOMETRY ) : SUCCESS
@@ -52,11 +52,14 @@ propertyUpdated( 2 , BLOCK , ANGLE ) : NO_CHANGES
 propertyUpdated( 2 , BLOCK , EXPRS ) : SUCCESS
 objectCreated( 3 , PORT )
 propertyUpdated( 3 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 3 , PORT , PORT_KIND ) : SUCCESS
 objectCreated( 4 , PORT )
 propertyUpdated( 4 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 4 , PORT , PORT_KIND ) : SUCCESS
 propertyUpdated( 2 , BLOCK , INPUTS ) : SUCCESS
 objectCreated( 5 , PORT )
 propertyUpdated( 5 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 5 , PORT , PORT_KIND ) : SUCCESS
 propertyUpdated( 2 , BLOCK , OUTPUTS ) : SUCCESS
 propertyUpdated( 2 , BLOCK , LABEL ) : NO_CHANGES
 propertyUpdated( 3 , PORT , IMPLICIT ) : NO_CHANGES
@@ -85,7 +88,7 @@ propertyUpdated( 2 , BLOCK , NZCROSS ) : NO_CHANGES
 propertyUpdated( 2 , BLOCK , NMODE ) : NO_CHANGES
 propertyUpdated( 2 , BLOCK , UID ) : NO_CHANGES
 propertyUpdated( 2 , BLOCK , INTERFACE_FUNCTION ) : SUCCESS
-blk2 = BIGSOM_f("define");
+Scope = CSCOPE("define");
 objectCreated( 6 , BLOCK )
 propertyUpdated( 6 , BLOCK , GEOMETRY ) : NO_CHANGES
 propertyUpdated( 6 , BLOCK , GEOMETRY ) : SUCCESS
@@ -94,32 +97,26 @@ propertyUpdated( 6 , BLOCK , ANGLE ) : NO_CHANGES
 propertyUpdated( 6 , BLOCK , EXPRS ) : SUCCESS
 objectCreated( 7 , PORT )
 propertyUpdated( 7 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 7 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 6 , BLOCK , INPUTS ) : SUCCESS
 objectCreated( 8 , PORT )
 propertyUpdated( 8 , PORT , SOURCE_BLOCK ) : SUCCESS
-propertyUpdated( 6 , BLOCK , INPUTS ) : SUCCESS
-objectCreated( 9 , PORT )
-propertyUpdated( 9 , PORT , SOURCE_BLOCK ) : SUCCESS
-propertyUpdated( 6 , BLOCK , OUTPUTS ) : SUCCESS
+propertyUpdated( 8 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 6 , BLOCK , EVENT_INPUTS ) : SUCCESS
 propertyUpdated( 6 , BLOCK , LABEL ) : NO_CHANGES
 propertyUpdated( 7 , PORT , IMPLICIT ) : NO_CHANGES
-propertyUpdated( 8 , PORT , IMPLICIT ) : NO_CHANGES
-propertyUpdated( 9 , PORT , IMPLICIT ) : NO_CHANGES
 propertyUpdated( 7 , PORT , STYLE ) : NO_CHANGES
-propertyUpdated( 8 , PORT , STYLE ) : NO_CHANGES
-propertyUpdated( 9 , PORT , STYLE ) : NO_CHANGES
 propertyUpdated( 7 , PORT , LABEL ) : NO_CHANGES
-propertyUpdated( 8 , PORT , LABEL ) : NO_CHANGES
-propertyUpdated( 9 , PORT , LABEL ) : NO_CHANGES
 propertyUpdated( 6 , BLOCK , STYLE ) : NO_CHANGES
 propertyUpdated( 6 , BLOCK , SIM_FUNCTION_NAME ) : SUCCESS
 propertyUpdated( 6 , BLOCK , SIM_FUNCTION_API ) : SUCCESS
-propertyUpdated( 8 , PORT , DATATYPE ) : SUCCESS
 propertyUpdated( 7 , PORT , DATATYPE ) : SUCCESS
-propertyUpdated( 9 , PORT , DATATYPE ) : SUCCESS
+propertyUpdated( 7 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 8 , PORT , DATATYPE ) : SUCCESS
 propertyUpdated( 6 , BLOCK , STATE ) : NO_CHANGES
 propertyUpdated( 6 , BLOCK , DSTATE ) : NO_CHANGES
 propertyUpdated( 6 , BLOCK , RPAR ) : SUCCESS
-propertyUpdated( 6 , BLOCK , IPAR ) : NO_CHANGES
+propertyUpdated( 6 , BLOCK , IPAR ) : SUCCESS
 propertyUpdated( 6 , BLOCK , SIM_BLOCKTYPE ) : SUCCESS
 propertyUpdated( 6 , BLOCK , SIM_DEP_UT ) : SUCCESS
 propertyUpdated( 6 , BLOCK , LABEL ) : NO_CHANGES
@@ -127,28 +124,28 @@ propertyUpdated( 6 , BLOCK , NZCROSS ) : NO_CHANGES
 propertyUpdated( 6 , BLOCK , NMODE ) : NO_CHANGES
 propertyUpdated( 6 , BLOCK , UID ) : NO_CHANGES
 propertyUpdated( 6 , BLOCK , INTERFACE_FUNCTION ) : SUCCESS
-lnk  = scicos_link();
-objectCreated( 10 , LINK )
-propertyUpdated( 10 , LINK , CONTROL_POINTS ) : NO_CHANGES
-propertyUpdated( 10 , LINK , CONTROL_POINTS ) : NO_CHANGES
-propertyUpdated( 10 , LINK , LABEL ) : NO_CHANGES
-propertyUpdated( 10 , LINK , THICK ) : NO_CHANGES
-propertyUpdated( 10 , LINK , COLOR ) : NO_CHANGES
-propertyUpdated( 10 , LINK , KIND ) : NO_CHANGES
-propertyUpdated( 10 , LINK , SOURCE_PORT ) : NO_CHANGES
-propertyUpdated( 10 , LINK , DESTINATION_PORT ) : NO_CHANGES
-scs_m = scicos_diagram( objs=list(blk,blk2,lnk) )
-objectCreated( 11 , DIAGRAM )
-propertyUpdated( 11 , DIAGRAM , TITLE ) : NO_CHANGES
-propertyUpdated( 11 , DIAGRAM , PATH ) : NO_CHANGES
-propertyUpdated( 11 , DIAGRAM , PROPERTIES ) : NO_CHANGES
-propertyUpdated( 11 , DIAGRAM , PROPERTIES ) : NO_CHANGES
-propertyUpdated( 11 , DIAGRAM , CONTEXT ) : NO_CHANGES
+lnk   = scicos_link();
+objectCreated( 9 , LINK )
+propertyUpdated( 9 , LINK , CONTROL_POINTS ) : NO_CHANGES
+propertyUpdated( 9 , LINK , CONTROL_POINTS ) : NO_CHANGES
+propertyUpdated( 9 , LINK , LABEL ) : NO_CHANGES
+propertyUpdated( 9 , LINK , THICK ) : NO_CHANGES
+propertyUpdated( 9 , LINK , COLOR ) : NO_CHANGES
+propertyUpdated( 9 , LINK , KIND ) : NO_CHANGES
+propertyUpdated( 9 , LINK , SOURCE_PORT ) : NO_CHANGES
+propertyUpdated( 9 , LINK , DESTINATION_PORT ) : NO_CHANGES
+scs_m = scicos_diagram( objs=list(Sum,Scope,lnk) )
+objectCreated( 10 , DIAGRAM )
+propertyUpdated( 10 , DIAGRAM , TITLE ) : NO_CHANGES
+propertyUpdated( 10 , DIAGRAM , PATH ) : NO_CHANGES
+propertyUpdated( 10 , DIAGRAM , PROPERTIES ) : NO_CHANGES
+propertyUpdated( 10 , DIAGRAM , PROPERTIES ) : NO_CHANGES
+propertyUpdated( 10 , DIAGRAM , CONTEXT ) : NO_CHANGES
 propertyUpdated( 2 , BLOCK , PARENT_DIAGRAM ) : SUCCESS
 propertyUpdated( 6 , BLOCK , PARENT_DIAGRAM ) : SUCCESS
-propertyUpdated( 10 , LINK , PARENT_DIAGRAM ) : SUCCESS
-propertyUpdated( 11 , DIAGRAM , CHILDREN ) : SUCCESS
-propertyUpdated( 11 , DIAGRAM , VERSION_NUMBER ) : NO_CHANGES
+propertyUpdated( 9 , LINK , PARENT_DIAGRAM ) : SUCCESS
+propertyUpdated( 10 , DIAGRAM , CHILDREN ) : SUCCESS
+propertyUpdated( 10 , DIAGRAM , VERSION_NUMBER ) : NO_CHANGES
 scs_m  = 
 scicos_diagram type :
   props
@@ -178,3 +175,75 @@ scicos_Link type :
   ct
   from
   to
+// Link output port #1 of block #1 (ID #5 in this example) with input port #1 of block #2 (ID #7)
+// The link ID is #10
+l = scs_m.objs;
+l(3).from = [1 1 0]; // Link block #1
+propertyUpdated( 5 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 9 , LINK , SOURCE_PORT ) : SUCCESS
+l(1).graphics.pout   // Check that block #1 is connected to the link
+ ans  =
+    3.
+l(1).model.out       // "
+ ans  =
+  - 1.
+l(3).to = [2 1 1];   // Link block #2
+propertyUpdated( 7 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 9 , LINK , DESTINATION_PORT ) : SUCCESS
+l(3).from
+ ans  =
+    1.    1.    0.
+l(3).to
+ ans  =
+    2.    1.    1.
+l(2).graphics.pin    // Check that block #2 is connected to the link
+ ans  =
+    3.
+l(2).model.in        // "
+ ans  =
+  - 1.
+// Change the end of the link to input port #2 of block #2 (ID #8)
+l(3).to = [2 2 1];
+propertyUpdated( 7 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+objectCreated( 11 , PORT )
+propertyUpdated( 11 , PORT , IMPLICIT ) : NO_CHANGES
+propertyUpdated( 11 , PORT , PORT_KIND ) : SUCCESS
+propertyUpdated( 11 , PORT , SOURCE_BLOCK ) : SUCCESS
+propertyUpdated( 11 , PORT , CONNECTED_SIGNALS ) : NO_CHANGES
+propertyUpdated( 11 , PORT , DATATYPE ) : SUCCESS
+propertyUpdated( 6 , BLOCK , INPUTS ) : SUCCESS
+propertyUpdated( 11 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 9 , LINK , DESTINATION_PORT ) : SUCCESS
+l(3).from
+ ans  =
+    1.    1.    0.
+l(3).to
+ ans  =
+    2.    2.    1.
+l(2).graphics.pin  // Check that block #2 is connected to the link
+ ans  =
+    0.
+    3.
+l(2).model.in      // "
+ ans  =
+  - 1.
+  - 1.
+// Disconnect the source, the destination is also disconnected
+l(3).from = [0 0 0];
+propertyUpdated( 5 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 11 , PORT , CONNECTED_SIGNALS ) : SUCCESS
+propertyUpdated( 9 , LINK , SOURCE_PORT ) : SUCCESS
+propertyUpdated( 9 , LINK , DESTINATION_PORT ) : SUCCESS
+l(3).from
+ ans  =
+    0.    0.    0.
+l(3).to
+ ans  =
+    0.    0.    0.
+l(1).graphics.pout // Check that both blocks are unconnected
+ ans  =
+    0.
+l(2).graphics.pin  // "
+ ans  =
+    0.
+    0.
index 079269b..543ac07 100644 (file)
@@ -15,9 +15,35 @@ scs_m.version
 scs_m.contrib
 
 // Create a diagram containing 2 summation blocks and an empty link
-blk  = BIGSOM_f("define");
-blk2 = BIGSOM_f("define");
-lnk  = scicos_link();
+Sum   = BIGSOM_f("define");
+Scope = CSCOPE("define");
+lnk   = scicos_link();
 
-scs_m = scicos_diagram( objs=list(blk,blk2,lnk) )
+scs_m = scicos_diagram( objs=list(Sum,Scope,lnk) )
 scs_m.objs
+
+// Link output port #1 of block #1 (ID #5 in this example) with input port #1 of block #2 (ID #7)
+// The link ID is #10
+l = scs_m.objs;
+l(3).from = [1 1 0]; // Link block #1
+l(1).graphics.pout   // Check that block #1 is connected to the link
+l(1).model.out       // "
+l(3).to = [2 1 1];   // Link block #2
+l(3).from
+l(3).to
+l(2).graphics.pin    // Check that block #2 is connected to the link
+l(2).model.in        // "
+
+// Change the end of the link to input port #2 of block #2 (ID #8)
+l(3).to = [2 2 1];
+l(3).from
+l(3).to
+l(2).graphics.pin  // Check that block #2 is connected to the link
+l(2).model.in      // "
+
+// Disconnect the source, the destination is also disconnected
+l(3).from = [0 0 0];
+l(3).from
+l(3).to
+l(1).graphics.pout // Check that both blocks are unconnected
+l(2).graphics.pin  // "