Xcos MVC: implement from / to 19/15019/5
Paul Bignier [Mon, 11 Aug 2014 06:42:02 +0000 (08:42 +0200)]
Also, fixed 'interface_function' and 'datatype' properties.

Matched default parameters with macros.

Change-Id: I6887ed9bc17efd6bf545302d90c65eb8aa3ae5de

scilab/modules/scicos/includes/utilities.hxx
scilab/modules/scicos/macros/scicos_scicos/%s_i_Link.sci [new file with mode: 0644]
scilab/modules/scicos/src/cpp/LoggerView.cpp
scilab/modules/scicos/src/cpp/Model_getObjectProperties.cpp
scilab/modules/scicos/src/cpp/Model_setObjectProperties.cpp
scilab/modules/scicos/src/cpp/model/BaseObject.hxx
scilab/modules/scicos/src/cpp/model/Block.hxx
scilab/modules/scicos/src/cpp/model/Link.hxx
scilab/modules/scicos/src/cpp/model/Port.hxx
scilab/modules/scicos/src/cpp/view_scilab/LinkAdapter.cpp
scilab/modules/scicos/src/cpp/view_scilab/ports_management.hxx

index 544633b..69c54a0 100644 (file)
@@ -90,6 +90,8 @@ enum object_properties_t
     THICK,              //!< model::Link::thick value
     COLOR,              //!< model::Link::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
diff --git a/scilab/modules/scicos/macros/scicos_scicos/%s_i_Link.sci b/scilab/modules/scicos/macros/scicos_scicos/%s_i_Link.sci
new file mode 100644 (file)
index 0000000..acf81ad
--- /dev/null
@@ -0,0 +1,24 @@
+//  Scicos
+//
+//  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// See the file ../license.txt
+//
+
+function m=%s_i_Link(i,b,L)
+    setfield(i,b,L)
+endfunction
index a625cf8..8a2c07d 100644 (file)
@@ -187,6 +187,12 @@ 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;
index 0ac6221..d41b0cb 100644 (file)
@@ -142,6 +142,9 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, int
         model::Port* o = static_cast<model::Port*>(getObject(uid));
         switch (p)
         {
+            case PORT_KIND:
+                o->getKind(v);
+                return true;
             default:
                 break;
         }
@@ -220,6 +223,9 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, std
         model::Block* o = static_cast<model::Block*>(getObject(uid));
         switch (p)
         {
+            case INTERFACE_FUNCTION:
+                o->getInterfaceFunction(v);
+                return true;
             case SIM_FUNCTION_NAME:
                 o->getSimFunctionName(v);
                 return true;
@@ -319,10 +325,10 @@ bool Model::getObjectProperty(ScicosID uid, kind_t k, object_properties_t p, Sci
                 v = o->getParentDiagram();
                 return true;
             case SOURCE_PORT:
-                v = o->getSourcePort();
+                o->getSourcePort(v);
                 return true;
             case DESTINATION_PORT:
-                v = o->getDestinationPort();
+                o->getDestinationPort(v);
                 return true;
             default:
                 break;
index d30e4d8..d91e23a 100644 (file)
@@ -135,6 +135,8 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
         model::Port* o = static_cast<model::Port*>(getObject(uid));
         switch (p)
         {
+            case PORT_KIND:
+                return o->setKind(v);
             default:
                 break;
         }
@@ -231,6 +233,10 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
         model::Link* o = static_cast<model::Link*>(getObject(uid));
         switch (p)
         {
+            case SOURCE_PORT:
+                return o->setSourcePort(v);
+            case DESTINATION_PORT:
+                return o->setDestinationPort(v);
             default:
                 break;
         }
@@ -242,6 +248,8 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
         {
             case SOURCE_BLOCK:
                 return o->setSourceBlock(v);
+            case CONNECTED_SIGNALS:
+                return o->setConnectedSignals(std::vector<ScicosID> (1, v));
             default:
                 break;
         }
@@ -267,6 +275,8 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
         model::Block* o = static_cast<model::Block*>(getObject(uid));
         switch (p)
         {
+            case INTERFACE_FUNCTION:
+                return o->setInterfaceFunction(v);
             case SIM_FUNCTION_NAME:
                 return o->setSimFunctionName(v);
             case STYLE:
@@ -544,6 +554,8 @@ update_status_t Model::setObjectProperty(ScicosID uid, kind_t k, object_properti
         model::Port* o = static_cast<model::Port*>(getObject(uid));
         switch (p)
         {
+            case CONNECTED_SIGNALS:
+                return o->setConnectedSignals(v);
             default:
                 break;
         }
index f64325c..801e2f4 100644 (file)
@@ -83,7 +83,7 @@ struct Geometry
     double width;
     double height;
 
-    Geometry() : x(0), y(0), width(0), height(0) {};
+    Geometry() : x(0), y(0), width(20), height(20) {};
     Geometry(const Geometry& g) : x(g.x), y(g.y), width(g.width), height(g.height) {};
     Geometry(const std::vector<double>& v) : x(v[0]), y(v[1]), width(v[2]), height(v[3]) {};
 
@@ -110,7 +110,7 @@ struct Datatype
 {
 public:
     Datatype(const std::vector<int>& v) :
-        refCount(0), datatype_id(v[0]), rows(v[1]), columns(v[2])
+        refCount(0), datatype_id(v[2]), rows(v[0]), columns(v[1])
     {
     }
 
index ff68b26..b536409 100644 (file)
@@ -95,7 +95,7 @@ struct Angle
     bool flip;
     double theta;
 
-    Angle() : flip(0), theta(0) {};
+    Angle() : flip(true), theta(0) {};
     Angle(const Angle& a) : flip(a.flip), theta(a.theta) {};
     Angle(const std::vector<double>& a) : flip((a[0] == 0) ? false : true), theta(a[1]) {};
 
@@ -223,18 +223,25 @@ private:
         {
             return NO_CHANGES;
         }
+
         this->in = in;
         return SUCCESS;
     }
 
-    const std::string& getInterfaceFunction() const
+    void getInterfaceFunction(std::string& fun) const
     {
-        return interfaceFunction;
+        fun = interfaceFunction;
     }
 
-    void setInterfaceFunction(const std::string& interfaceFunction)
+    update_status_t setInterfaceFunction(const std::string& fun)
     {
+        if (fun == this->interfaceFunction)
+        {
+            return NO_CHANGES;
+        }
+
         this->interfaceFunction = interfaceFunction;
+        return SUCCESS;
     }
 
     void getOut(std::vector<ScicosID>& v) const
@@ -248,6 +255,7 @@ private:
         {
             return NO_CHANGES;
         }
+
         this->out = out;
         return SUCCESS;
     }
@@ -263,6 +271,7 @@ private:
         {
             return NO_CHANGES;
         }
+
         this->ein = ein;
         return SUCCESS;
     }
@@ -278,6 +287,7 @@ private:
         {
             return NO_CHANGES;
         }
+
         this->eout = eout;
         return SUCCESS;
     }
index d2d47ba..83d7b9d 100644 (file)
@@ -40,7 +40,7 @@ class Link: public BaseObject
 
 private:
     Link() : BaseObject(LINK), parentDiagram(0), sourcePort(0), destinationPort(0), controlPoints(),
-        label(), thick(), color(1), linkKind(regular) {};
+        label(), thick(std::vector<double>(2)), color(1), linkKind(regular) {};
     Link(const Link& o) : BaseObject(LINK), parentDiagram(o.parentDiagram), sourcePort(o.sourcePort), destinationPort(o.destinationPort),
         controlPoints(o.controlPoints), label(o.label), thick(o.thick), color(o.color), linkKind(o.linkKind) {};
     ~Link() {}
@@ -154,24 +154,36 @@ private:
         return SUCCESS;
     }
 
-    ScicosID getDestinationPort() const
+    void getSourcePort(ScicosID& sp) const
     {
-        return destinationPort;
+        sp = sourcePort;
     }
 
-    void setDestinationPort(ScicosID destinationPort)
+    update_status_t setSourcePort(const ScicosID sp)
     {
-        this->destinationPort = destinationPort;
+        if (sp == sourcePort)
+        {
+            return NO_CHANGES;
+        }
+
+        sourcePort = sp;
+        return SUCCESS;
     }
 
-    ScicosID getSourcePort() const
+    void getDestinationPort(ScicosID& dp) const
     {
-        return sourcePort;
+        dp = destinationPort;
     }
 
-    void setSourcePort(ScicosID sourcePort)
+    update_status_t setDestinationPort(const ScicosID dp)
     {
-        this->sourcePort = sourcePort;
+        if (dp == destinationPort)
+        {
+            return NO_CHANGES;
+        }
+
+        destinationPort = dp;
+        return SUCCESS;
     }
 
 private:
index bea267a..b907a55 100644 (file)
@@ -35,7 +35,7 @@ class Port: public BaseObject
 
 private:
     Port() : BaseObject(PORT), dataType(0), sourceBlock(0), kind(UNDEF), implicit(false),
-        style(), label(), connectedSignals() {};
+        style(), label(), connectedSignals(std::vector<ScicosID> (1, 0)) {};
     Port(const Port& o) : BaseObject(PORT), dataType(o.dataType), sourceBlock(o.sourceBlock), kind(o.kind), implicit(o.implicit),
         style(o.style), label(o.label), connectedSignals(o.connectedSignals) {};
     ~Port() {};
@@ -56,7 +56,7 @@ private:
         return SUCCESS;
     }
 
-    void getDataType(std::vector<int> v) const
+    void getDataType(std::vector<int>& v) const
     {
         if (dataType == 0)
         {
@@ -67,7 +67,7 @@ private:
             v.resize(3);
             v[0] = dataType->rows;
             v[1] = dataType->columns;
-            v[3] = dataType->datatype_id;
+            v[2] = dataType->datatype_id;
         }
     }
 
@@ -88,14 +88,25 @@ private:
         return SUCCESS;
     }
 
-    portKind getKind() const
+    void getKind(int& k) const
     {
-        return kind;
+        k = kind;
     }
 
-    void setKind(portKind kind)
+    update_status_t setKind(int k)
     {
-        this->kind = kind;
+        if (k < UNDEF || k > EOUT)
+        {
+            return FAIL;
+        }
+
+        if (k == kind)
+        {
+            return NO_CHANGES;
+        }
+
+        kind = static_cast<portKind>(k);
+        return SUCCESS;
     }
 
     void getSourceBlock(ScicosID& sb) const
index 4240ccb..e2d5cab 100644 (file)
@@ -247,6 +247,173 @@ struct ct
     }
 };
 
+static types::Double* getLinkEnd(const LinkAdapter& adaptor, const Controller& controller, object_properties_t end)
+{
+    model::Link* adaptee = adaptor.getAdaptee();
+
+    double* data;
+    types::Double* o = new types::Double(1, 3, &data);
+    data[0] = 0;
+    data[1] = 0;
+    data[2] = 0;
+
+    ScicosID endID;
+    controller.getObjectProperty(adaptee->id(), adaptee->kind(), end, endID);
+    if (endID != 0)
+    {
+        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);
+    }
+    // Default case, the property was initialized at [].
+    return o;
+}
+
+static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_properties_t end, types::InternalType* v)
+{
+    model::Link* adaptee = adaptor.getAdaptee();
+
+    if (v->getType() != types::InternalType::ScilabDouble)
+    {
+        return false;
+    }
+
+    types::Double* current = v->getAs<types::Double>();
+
+    if ((current->getRows() != 1 || current->getCols() != 3) && current->getSize() != 0)
+    {
+        return false; // Must be [] or [x y z]
+    }
+
+    ScicosID from;
+    controller.getObjectProperty(adaptee->id(), adaptee->kind(), SOURCE_PORT, from);
+    ScicosID to;
+    controller.getObjectProperty(adaptee->id(), adaptee->kind(), DESTINATION_PORT, to);
+    ScicosID concernedPort;
+    object_properties_t otherEnd;
+    object_properties_t portType;
+    switch (end)
+    {
+        case SOURCE_PORT:
+            concernedPort = from;
+            otherEnd = DESTINATION_PORT;
+            portType = OUTPUTS;
+            break;
+        case DESTINATION_PORT:
+            concernedPort = to;
+            otherEnd = SOURCE_PORT;
+            portType = INPUTS;
+            break;
+        default:
+            return false;
+    }
+    ScicosID unconnected = 0;
+
+    if (current->getSize() == 0 || (current->get(0) == 0 || current->get(1) == 0))
+    {
+        // We want to set an empty link
+        if (concernedPort == 0)
+        {
+            // In this case, the link was already empty, do a dummy call to display the console status.
+            controller.setObjectProperty(adaptee->id(), adaptee->kind(), end, concernedPort);
+        }
+        else
+        {
+            // Untie the old link on both ends and set the 2 concerned ports as unconnected
+            controller.setObjectProperty(from, PORT, CONNECTED_SIGNALS, unconnected);
+            controller.setObjectProperty(to, PORT, CONNECTED_SIGNALS, unconnected);
+
+            controller.setObjectProperty(adaptee->id(), adaptee->kind(), SOURCE_PORT, unconnected);
+            controller.setObjectProperty(adaptee->id(), adaptee->kind(), DESTINATION_PORT, unconnected);
+        }
+        return true;
+    }
+
+    if (current->get(2) != 0 && current->get(2) != 1)
+    {
+        return false; // "From" port must be output type or implicit.
+    }
+
+    if (floor(current->get(0)) != current->get(0) || floor(current->get(1)) != current->get(1))
+    {
+        return false; // Must be an integer value
+    }
+
+    // Disconnect the old port if it was connected
+    if (from != 0)
+    {
+        controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, unconnected);
+    }
+
+    // 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));
+    std::vector<ScicosID> sourceBlockPorts;
+    controller.getObjectProperty(blk, BLOCK, portType, sourceBlockPorts);
+    int nBlockPorts = sourceBlockPorts.size();
+    // Create as many ports as necessary
+    while (nBlockPorts < port)
+    {
+        ScicosID createdPort = controller.createObject(PORT);
+        controller.setObjectProperty(createdPort, PORT, SOURCE_BLOCK, blk);
+        controller.setObjectProperty(createdPort, PORT, CONNECTED_SIGNALS, unconnected);
+        nBlockPorts++;
+    }
+    controller.getObjectProperty(blk, BLOCK, portType, sourceBlockPorts);
+    ScicosID newPort = sourceBlockPorts[port - 1];
+    ScicosID oldLink;
+    controller.getObjectProperty(newPort, PORT, CONNECTED_SIGNALS, oldLink);
+    if (oldLink != 0)
+    {
+        // Disconnect the old other end port and delete the old link
+        ScicosID oldPort;
+        controller.getObjectProperty(oldLink, LINK, otherEnd, oldPort);
+        controller.setObjectProperty(oldPort, PORT, CONNECTED_SIGNALS, unconnected);
+        controller.deleteObject(oldLink);
+    }
+
+    // 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);
+    return true;
+}
+
+struct from
+{
+
+    static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
+    {
+        return getLinkEnd(adaptor, controller, SOURCE_PORT);
+    }
+
+    static bool set(LinkAdapter& adaptor, types::InternalType* v, Controller& controller)
+    {
+        return setLinkEnd(adaptor, controller, SOURCE_PORT, v);
+    }
+};
+
+struct to
+{
+
+    static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
+    {
+        return getLinkEnd(adaptor, controller, DESTINATION_PORT);
+    }
+
+    static bool set(LinkAdapter& adaptor, types::InternalType* v, Controller& controller)
+    {
+        return setLinkEnd(adaptor, controller, DESTINATION_PORT, v);
+    }
+};
+
 } /* namespace */
 
 template<> property<LinkAdapter>::props_t property<LinkAdapter>::fields = property<LinkAdapter>::props_t();
@@ -259,12 +426,14 @@ LinkAdapter::LinkAdapter(org_scilab_modules_scicos::model::Link* o) :
 {
     if (property<LinkAdapter>::properties_has_not_been_set())
     {
-        property<LinkAdapter>::fields.reserve(5);
+        property<LinkAdapter>::fields.reserve(7);
         property<LinkAdapter>::add_property(L"xx", &xx::get, &xx::set);
         property<LinkAdapter>::add_property(L"yy", &yy::get, &yy::set);
         property<LinkAdapter>::add_property(L"id", &id::get, &id::set);
         property<LinkAdapter>::add_property(L"thick", &thick::get, &thick::set);
         property<LinkAdapter>::add_property(L"ct", &ct::get, &ct::set);
+        property<LinkAdapter>::add_property(L"from", &from::get, &from::set);
+        property<LinkAdapter>::add_property(L"to", &to::get, &to::set);
     }
 }
 
index c21af92..039e0cf 100644 (file)
@@ -43,7 +43,7 @@ types::InternalType* get_ports_property(const Adaptor& adaptor, object_propertie
 
     // Translate identifiers: shared variables
     int i = 0;
-    size_t datatypeIndex = 0;
+    size_t datatypeIndex = -1;
     // Translate identifiers to return values
     switch (p)
     {
@@ -59,22 +59,22 @@ types::InternalType* get_ports_property(const Adaptor& adaptor, object_propertie
             }
             return o;
         }
-        case DATATYPE_ROWS:
-            datatypeIndex = 0;
+        case DATATYPE_TYPE:
+            datatypeIndex++;
             // no break
         case DATATYPE_COLS:
-            datatypeIndex = 1;
+            datatypeIndex++;
             // no break
-        case DATATYPE_TYPE:
+        case DATATYPE_ROWS:
         {
-            datatypeIndex = 2;
-
-            types::Double* o = new types::Double(ids.size(), 1);
+            datatypeIndex++;
+            double* data;
+            types::Double* o = new types::Double(ids.size(), 1, &data);
             for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
             {
                 std::vector<int> v;
                 controller.getObjectProperty(*it, PORT, DATATYPE, v);
-                o[i] = v[datatypeIndex];
+                data[i] = v[datatypeIndex];
             }
             return o;
         }
@@ -174,8 +174,8 @@ bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, C
             }
             case IMPLICIT:
             {
-                static const wchar_t E[] = L"E";
-                static const wchar_t I[] = L"I";
+                static const std::wstring E = L"E";
+                static const std::wstring I = L"I";
 
                 for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
                 {
@@ -214,7 +214,7 @@ bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, C
 
         // Translate identifiers: shared variables
         int i = 0;
-        size_t datatypeIndex = 0;
+        size_t datatypeIndex = -1;
         // Translate identifiers from values
         switch (p)
         {
@@ -231,15 +231,15 @@ bool set_ports_property(const Adaptor& adaptor, object_properties_t port_kind, C
                 // Do nothing, because if the sizes match, then there are already zero concerned ports, so no ports to update
                 return true;
 
-            case DATATYPE_ROWS:
-                datatypeIndex = 0;
+            case DATATYPE_TYPE:
+                datatypeIndex++;
                 // no break
             case DATATYPE_COLS:
-                datatypeIndex = 1;
+                datatypeIndex++;
                 // no break
-            case DATATYPE_TYPE:
+            case DATATYPE_ROWS:
             {
-                datatypeIndex = 2;
+                datatypeIndex++;
 
                 for (std::vector<ScicosID>::iterator it = ids.begin(); it != ids.end(); ++it, ++i)
                 {
@@ -323,7 +323,25 @@ void updateNewPort(ScicosID oldPort, int newPort, Controller& controller,
     else
     {
         // update the p property, using newPort as a value
-        controller.setObjectProperty(oldPort, PORT, p, newPort);
+        int datatypeIndex = -1;
+        switch (p)
+        {
+            case DATATYPE_TYPE:
+                datatypeIndex++;
+            case DATATYPE_COLS:
+                datatypeIndex++;
+            case DATATYPE_ROWS:
+            {
+                datatypeIndex++;
+                std::vector<int> datatype;
+                controller.getObjectProperty(oldPort, PORT, DATATYPE, datatype);
+                datatype[datatypeIndex] = newPort;
+                controller.setObjectProperty(oldPort, PORT, DATATYPE, datatype);
+                return;
+            }
+            default:
+                controller.setObjectProperty(oldPort, PORT, p, newPort);
+        }
     }
 }
 
@@ -343,27 +361,19 @@ bool addNewPort(ScicosID newPortID, int newPort, const std::vector<ScicosID>& ch
     else
     {
         // set the requested property, using newPort as a value
+        int datatypeIndex = -1;
         switch (p)
         {
-            case DATATYPE_ROWS:
-            {
-                std::vector<int> datatype (3);
-                controller.getObjectProperty(newPortID, PORT, DATATYPE, datatype);
-                datatype[0] = newPort;
-                return controller.setObjectProperty(newPortID, PORT, DATATYPE, datatype);
-            }
-            case DATATYPE_COLS:
-            {
-                std::vector<int> datatype (3);
-                controller.getObjectProperty(newPortID, PORT, DATATYPE, datatype);
-                datatype[1] = newPort;
-                return controller.setObjectProperty(newPortID, PORT, DATATYPE, datatype);
-            }
             case DATATYPE_TYPE:
+                datatypeIndex++;
+            case DATATYPE_COLS:
+                datatypeIndex++;
+            case DATATYPE_ROWS:
             {
-                std::vector<int> datatype (3);
+                datatypeIndex++;
+                std::vector<int> datatype;
                 controller.getObjectProperty(newPortID, PORT, DATATYPE, datatype);
-                datatype[2] = newPort;
+                datatype[datatypeIndex] = newPort;
                 return controller.setObjectProperty(newPortID, PORT, DATATYPE, datatype);
             }
             default: