Scicos: enable Structs for var2var and vec2var 39/16339/5
Paul Bignier [Wed, 8 Apr 2015 11:46:39 +0000 (13:46 +0200)]
 * Also enable them in the models (ModelAdapter.cpp)

Change-Id: I3f8180c0d575499c60487f99e3e87b3b28124873

scilab/modules/scicos/src/cpp/var2vec.cpp
scilab/modules/scicos/src/cpp/var2vec.hxx
scilab/modules/scicos/src/cpp/vec2var.cpp
scilab/modules/scicos/src/cpp/vec2var.hxx
scilab/modules/scicos/src/cpp/view_scilab/ModelAdapter.cpp
scilab/modules/scicos/tests/unit_tests/model/Block.dia.ref
scilab/modules/scicos/tests/unit_tests/model/Block.tst
scilab/modules/scicos/tests/unit_tests/var2vec.dia.ref
scilab/modules/scicos/tests/unit_tests/var2vec.tst

index daa3aa6..9219902 100644 (file)
@@ -26,6 +26,7 @@
 #include "list.hxx"
 #include "tlist.hxx"
 #include "mlist.hxx"
+#include "struct.hxx"
 
 extern "C"
 {
@@ -209,11 +210,50 @@ static void encode(types::List* input, std::vector<double> &ret)
     // An empty list input will return [22; 0], a tlist [23; 0] and an mlist [24; 0]
 }
 
+static void encode(types::Struct* input, std::vector<double> &ret)
+{
+    int iElements = 0;
+    types::String* fields;
+    if (input->getSize() > 0)
+    {
+        fields = input->get(0)->getFieldNames();
+        iElements = fields->getSize();
+    }
+    int totalSize = 2;
+
+    std::vector<std::vector<double>> fieldsContent (1 + iElements);
+    if (input->getSize() > 0)
+    {
+        // Call var2vec on the struct's fields to extract a header
+        var2vec(fields, fieldsContent[0]);
+        totalSize += static_cast<int>(fieldsContent[0].size());
+        // Now extract the fields' content
+        for (int i = 1; i < iElements + 1; ++i)
+        {
+            // Recursively call var2vec on each element and extract the obtained results
+            var2vec(input->get(0)->get(fields->get(i - 1)), fieldsContent[i]);
+            totalSize += static_cast<int>(fieldsContent[i].size());
+        }
+    }
+    // Allocation for type + fields names + fields content
+    ret.resize(totalSize);
+
+    ret[0] = input->getType();
+    ret[1] = iElements;
+    int offset = 0;
+    for (int i = 0; i < iElements + 1; ++i)
+    {
+        memcpy(&ret[2 + offset], &fieldsContent[i][0], fieldsContent[i].size() * sizeof(double));
+        offset += static_cast<int>(fieldsContent[i].size());
+    }
+    // An empty struct input will return [26; 0]
+}
+
 bool var2vec(types::InternalType* in, std::vector<double> &out)
 {
     switch (in->getType())
     {
-        // Reuse scicos model encoding for 'model.opar' and 'model.odstate' fields
+            // Reuse scicos model encoding for 'model.opar' and 'model.odstate' fields
         case types::InternalType::ScilabDouble :
             encode(in->getAs<types::Double>(), out);
             break;
@@ -260,8 +300,12 @@ bool var2vec(types::InternalType* in, std::vector<double> &out)
             encode(in->getAs<types::List>(), out);
             break;
 
+        case types::InternalType::ScilabStruct :
+            encode(in->getAs<types::Struct>(), out);
+            break;
+
         default :
-            Scierror(999, _("%s: Wrong type for input argument #%d: %s, %s, %s, %s or %s type.\n"), var2vecName.c_str(), 1, "Double", "Integer", "Boolean", "String", "List");
+            Scierror(999, _("%s: Wrong type for input argument #%d: %s, %s, %s, %s, %s or %s type.\n"), var2vecName.c_str(), 1, "Double", "Integer", "Boolean", "String", "List", "Struct");
             return false;
     }
 
index 207e19a..48ac040 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "types.hxx"
 #include "internal.hxx"
-#include "double.hxx"
 
 bool var2vec(types::InternalType* in, std::vector<double> &out);
 
index 2c22299..710d62a 100644 (file)
 #include "list.hxx"
 #include "tlist.hxx"
 #include "mlist.hxx"
+#include "struct.hxx"
+
+extern "C"
+{
+#include "Scierror.h"
+#include "localization.h"
+}
 
 static const std::string vec2varName = "vec2var";
 
@@ -410,6 +417,64 @@ static bool readElement(const double* const input, const int iType, const int iD
             break;
         }
 
+        case types::InternalType::ScilabStruct :
+        {
+            if (inputRows < 2)
+            {
+                Scierror(999, _("%s: Wrong size for input argument #%d: At least %dx%d expected.\n"), vec2varName.c_str(), 1, offset + 2, 1);
+                return false;
+            }
+
+            if (iDims <= 0)
+            {
+                res = new types::Struct();
+                offset += 2;
+                break;
+            }
+
+            types::Struct* pStruct = new types::Struct(1, 1);
+
+            offset += 2;
+            // Read the header...
+            int elementType = static_cast<int>(*(input + offset));
+            if (elementType != types::InternalType::ScilabString)
+            {
+                Scierror(999, _("%s: Wrong value for input argument #%d: %d (String) expected.\n"), vec2varName.c_str(), 1, 11);
+                return false;
+            }
+            int elementDims = static_cast<int>(*(input + offset + 1));
+            types::InternalType* element;
+            if (!readElement(input + offset, elementType, elementDims, inputRows - offset, offset, element))
+            {
+                return false;
+            }
+            types::String* header = element->getAs<types::String>();
+            // ... and copy it in 'pStruct'
+            for (int i = 0; i < header->getSize(); ++i)
+            {
+                pStruct->get(0)->addField(header->get(i));
+            }
+
+            for (int i = 1; i < iDims + 1; ++i)
+            {
+                if (inputRows < 2 + offset)
+                {
+                    Scierror(999, _("%s: Wrong size for input argument #%d: At least %dx%d expected.\n"), vec2varName.c_str(), 1, offset + 2, 1);
+                    return false;
+                }
+                // Extract the fields content infos and recursively call readElement
+                elementType = static_cast<int>(*(input + offset));
+                elementDims = static_cast<int>(*(input + offset + 1));
+                if (!readElement(input + offset, elementType, elementDims, inputRows - offset, offset, element))
+                {
+                    return false;
+                }
+                pStruct->get(0)->set(header->get(i - 1), element);
+            }
+            res = pStruct;
+            break;
+        }
+
         default :
             Scierror(999, _("%s: Wrong value for element #%d of input argument #%d: Unknown type.\n"), vec2varName.c_str(), offset + 1, 1);
             return false;
index 1b45297..1c8f036 100644 (file)
 #include "types.hxx"
 #include "internal.hxx"
 
-extern "C"
-{
-#include "Scierror.h"
-#include "localization.h"
-}
-
 bool vec2var(const std::vector<double> in, types::InternalType* &out);
 
 #endif /* VEC2VAR_HXX_ */
index 6d697eb..1c4123d 100644 (file)
@@ -414,13 +414,8 @@ struct odstate
             return true;
         }
 
-        if (v->getType() != types::InternalType::ScilabList)
-        {
-            return false;
-        }
-
         std::vector<double> prop_content;
-        if (!var2vec(v->getAs<types::List>(), prop_content))
+        if (!var2vec(v, prop_content))
         {
             return false;
         }
@@ -748,13 +743,8 @@ struct opar
             return true;
         }
 
-        if (v->getType() != types::InternalType::ScilabList)
-        {
-            return false;
-        }
-
         std::vector<double> prop_content;
-        if (!var2vec(v->getAs<types::List>(), prop_content))
+        if (!var2vec(v, prop_content))
         {
             return false;
         }
index cb227b1..066ec31 100644 (file)
@@ -1738,6 +1738,62 @@ propertyUpdated( 29 , BLOCK , NZCROSS ) : NO_CHANGES
 propertyUpdated( 29 , BLOCK , NMODE ) : NO_CHANGES
 propertyUpdated( 29 , BLOCK , UID ) : NO_CHANGES
 assert_checkequal(o.model.opar, listRef);
+// With tlist
+tlistRef = tlist(["tl" "f1" "f2" "f3"], [], testHM, []);
+o.model.opar = tlistRef;
+propertyUpdated( 29 , BLOCK , SIM_FUNCTION_NAME ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , SIM_FUNCTION_API ) : NO_CHANGES
+propertyUpdated( 30 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 31 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 30 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 31 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 30 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 31 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 32 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 32 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 32 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 33 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , STATE ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , DSTATE ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , ODSTATE ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , RPAR ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , IPAR ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , OPAR ) : SUCCESS
+propertyUpdated( 29 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , SIM_DEP_UT ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , LABEL ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , NZCROSS ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , NMODE ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , UID ) : NO_CHANGES
+assert_checkequal(o.model.opar, tlistRef);
+// With struct
+structRef = struct("f1", [], "f2", testHM, "f3", []);
+o.model.opar = structRef;
+propertyUpdated( 29 , BLOCK , SIM_FUNCTION_NAME ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , SIM_FUNCTION_API ) : NO_CHANGES
+propertyUpdated( 30 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 31 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 30 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 31 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 30 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 31 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 32 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 32 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 32 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 33 , PORT , DATATYPE ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , STATE ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , DSTATE ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , ODSTATE ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , RPAR ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , IPAR ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , OPAR ) : SUCCESS
+propertyUpdated( 29 , BLOCK , SIM_BLOCKTYPE ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , SIM_DEP_UT ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , LABEL ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , NZCROSS ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , NMODE ) : NO_CHANGES
+propertyUpdated( 29 , BLOCK , UID ) : NO_CHANGES
+assert_checkequal(o.model.opar, structRef);
 // Test 'equations'
 o = VsourceAC("define")
 objectCreated( 34 , BLOCK )
index 531c8e1..3027baa 100644 (file)
@@ -152,6 +152,15 @@ listRef = list([], testHM > 3, []);
 o.model.opar = listRef;
 assert_checkequal(o.model.opar, listRef);
 
+// With tlist
+tlistRef = tlist(["tl" "f1" "f2" "f3"], [], testHM, []);
+o.model.opar = tlistRef;
+assert_checkequal(o.model.opar, tlistRef);
+// With struct
+structRef = struct("f1", [], "f2", testHM, "f3", []);
+o.model.opar = structRef;
+assert_checkequal(o.model.opar, structRef);
+
 // Test 'equations'
 o = VsourceAC("define")
 o.model.equations
index 734576f..656733c 100644 (file)
@@ -99,3 +99,8 @@ mlEmpties = mlist(["Type" "f1" "f2" "f3" "f4" "f5", "f6"]);
 assert_checkequal(vec2var(var2vec(mlEmpties)), mlEmpties);
 mlMixed = mlist(["Type" "f1" "f2" "f3" "f4" "f5", "f6"], [], Mat, HyperMat, int32(Mat), string(Mat), Mat>15);
 assert_checkequal(vec2var(var2vec(mlMixed)), mlMixed);
+// Struct
+st = struct();
+assert_checkequal(vec2var(var2vec(st)), st);
+stFull = struct("f1", [], "f2", Mat, "f3", HyperMat, "f4", int32(Mat), "f5", string(Mat), "f6", Mat>15);
+assert_checkequal(vec2var(var2vec(stFull)), stFull);
index 86b6483..c2c8656 100644 (file)
@@ -108,3 +108,9 @@ mlEmpties = mlist(["Type" "f1" "f2" "f3" "f4" "f5", "f6"]);
 assert_checkequal(vec2var(var2vec(mlEmpties)), mlEmpties);
 mlMixed = mlist(["Type" "f1" "f2" "f3" "f4" "f5", "f6"], [], Mat, HyperMat, int32(Mat), string(Mat), Mat>15);
 assert_checkequal(vec2var(var2vec(mlMixed)), mlMixed);
+
+// Struct
+st = struct();
+assert_checkequal(vec2var(var2vec(st)), st);
+stFull = struct("f1", [], "f2", Mat, "f3", HyperMat, "f4", int32(Mat), "f5", string(Mat), "f6", Mat>15);
+assert_checkequal(vec2var(var2vec(stFull)), stFull);