2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
28 #include "Controller.hxx"
29 #include "Adapters.hxx"
30 #include "ModelAdapter.hxx"
31 #include "DiagramAdapter.hxx"
32 #include "ports_management.hxx"
33 #include "utilities.hxx"
35 #include "var2vec.hxx"
36 #include "vec2var.hxx"
39 #include "sci_malloc.h"
40 #include "charEncoding.h"
43 namespace org_scilab_modules_scicos
50 const std::string input ("input");
51 const std::string output ("output");
52 const std::string inimpl ("inimpl");
53 const std::string outimpl ("outimpl");
55 const std::wstring modelica (L"modelica");
56 const std::wstring model (L"model");
57 const std::wstring inputs (L"inputs");
58 const std::wstring outputs (L"outputs");
59 const std::wstring parameters (L"parameters");
64 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
66 ScicosID adaptee = adaptor.getAdaptee()->id();
68 // First, extract the function Name
70 controller.getObjectProperty(adaptee, BLOCK, SIM_FUNCTION_NAME, name);
71 types::String* Name = new types::String(1, 1);
72 Name->set(0, name.data());
74 // Then the Api. If it is zero, then just return the Name. Otherwise, return a list containing both.
76 controller.getObjectProperty(adaptee, BLOCK, SIM_FUNCTION_API, api);
84 types::Double* Api = new types::Double(static_cast<double>(api));
85 types::List* o = new types::List();
92 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
94 ScicosID adaptee = adaptor.getAdaptee()->id();
96 if (v->getType() == types::InternalType::ScilabString)
98 types::String* current = v->getAs<types::String>();
99 if (current->getSize() != 1)
104 char* c_str = wide_string_to_UTF8(current->get(0));
105 std::string name(c_str);
108 // If the input is a scalar string, then the functionApi is 0.
111 controller.setObjectProperty(adaptee, BLOCK, SIM_FUNCTION_NAME, name);
112 controller.setObjectProperty(adaptee, BLOCK, SIM_FUNCTION_API, api);
114 else if (v->getType() == types::InternalType::ScilabList)
116 // If the input is a 2-sized list, then it must be string and positive integer.
117 types::List* current = v->getAs<types::List>();
118 if (current->getSize() != 2)
122 if (current->get(0)->getType() != types::InternalType::ScilabString || current->get(1)->getType() != types::InternalType::ScilabDouble)
127 types::String* Name = current->get(0)->getAs<types::String>();
128 if (Name->getSize() != 1)
132 char* c_str = wide_string_to_UTF8(Name->get(0));
133 std::string name(c_str);
136 types::Double* Api = current->get(1)->getAs<types::Double>();
137 if (Api->getSize() != 1)
141 double api = Api->get(0);
142 if (floor(api) != api)
146 int api_int = static_cast<int>(api);
148 controller.setObjectProperty(adaptee, BLOCK, SIM_FUNCTION_NAME, name);
149 controller.setObjectProperty(adaptee, BLOCK, SIM_FUNCTION_API, api_int);
162 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
164 return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, INPUTS, controller);
167 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
169 return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, INPUTS, controller, v);
176 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
178 return get_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, INPUTS, controller);
181 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
183 return set_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, INPUTS, controller, v);
190 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
192 return get_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, INPUTS, controller);
195 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
197 return set_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, INPUTS, controller, v);
204 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
206 return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, OUTPUTS, controller);
209 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
211 return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, OUTPUTS, controller, v);
218 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
220 return get_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, OUTPUTS, controller);
223 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
225 return set_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, OUTPUTS, controller, v);
232 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
234 return get_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, OUTPUTS, controller);
237 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
239 return set_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, OUTPUTS, controller, v);
246 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
248 return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_INPUTS, controller);
251 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
253 return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_INPUTS, controller, v);
260 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
262 return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_OUTPUTS, controller);
265 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
267 return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_OUTPUTS, controller, v);
274 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
276 ScicosID adaptee = adaptor.getAdaptee()->id();
278 std::vector<double> state;
279 controller.getObjectProperty(adaptee, BLOCK, STATE, state);
282 types::Double* o = new types::Double((int)state.size(), 1, &data);
285 std::copy(state.begin(), state.end(), stdext::checked_array_iterator<double*>(data, state.size()));
287 std::copy(state.begin(), state.end(), data);
292 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
295 if (v->getType() != types::InternalType::ScilabDouble)
300 types::Double* current = v->getAs<types::Double>();
301 // Only allow vectors and empty matrices
302 if (!current->isVector() && current->getSize() != 0)
307 ScicosID adaptee = adaptor.getAdaptee()->id();
309 std::vector<double> state (current->getSize());
310 std::copy(current->getReal(), current->getReal() + current->getSize(), state.begin());
312 controller.setObjectProperty(adaptee, BLOCK, STATE, state);
320 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
322 ScicosID adaptee = adaptor.getAdaptee()->id();
324 std::vector<double> dstate;
325 controller.getObjectProperty(adaptee, BLOCK, DSTATE, dstate);
328 types::Double* o = new types::Double((int)dstate.size(), 1, &data);
331 std::copy(dstate.begin(), dstate.end(), stdext::checked_array_iterator<double*>(data, dstate.size()));
333 std::copy(dstate.begin(), dstate.end(), data);
338 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
340 ScicosID adaptee = adaptor.getAdaptee()->id();
342 if (v->getType() == types::InternalType::ScilabString)
344 types::String* current = v->getAs<types::String>();
345 if (current->getSize() != 1)
350 std::vector<double> dstate;
351 controller.setObjectProperty(adaptee, BLOCK, DSTATE, dstate);
355 if (v->getType() != types::InternalType::ScilabDouble)
359 types::Double* current = v->getAs<types::Double>();
360 // Only allow vectors and empty matrices
361 if (!current->isVector() && current->getSize() != 0)
366 std::vector<double> dstate (current->getSize());
367 std::copy(current->getReal(), current->getReal() + current->getSize(), dstate.begin());
369 controller.setObjectProperty(adaptee, BLOCK, DSTATE, dstate);
377 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
379 ScicosID adaptee = adaptor.getAdaptee()->id();
381 std::vector<double> prop_content;
382 controller.getObjectProperty(adaptee, BLOCK, ODSTATE, prop_content);
384 // Corner-case, the empty content is an empty double
385 if (prop_content.empty())
387 return types::Double::Empty();
390 // The returned value is a list
391 types::InternalType* res;
392 if (!vec2var(prop_content, res))
400 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
402 ScicosID adaptee = adaptor.getAdaptee()->id();
404 // corner-case the empty content is an empty-double
405 if (v->getType() == types::InternalType::ScilabDouble)
407 types::Double* current = v->getAs<types::Double>();
408 if (current->getSize() != 0)
413 // prop_content is empty
414 std::vector<double> prop_content;
415 controller.setObjectProperty(adaptee, BLOCK, ODSTATE, prop_content);
419 std::vector<double> prop_content;
420 if (!var2vec(v, prop_content))
425 controller.setObjectProperty(adaptee, BLOCK, ODSTATE, prop_content);
431 * When setting a diagram in 'rpar', the Superblock's ports must be consistent with the "port blocks" inside it.
432 * By "port blocks", we mean IN_f, OUT_f, CLKIN_f, CLKOUT_f, CLKINV_f, CLKOUTV_f, INIMPL_f and OUTIMPL_f.
434 bool setInnerBlocksRefs(ModelAdapter& adaptor, const std::vector<ScicosID>& children, Controller& controller)
436 ScicosID adaptee = adaptor.getAdaptee()->id();
438 for (std::vector<ScicosID>::const_iterator it = children.begin(); it != children.end(); ++it)
440 if (controller.getObject(*it)->kind() == BLOCK) // Rule out Annotations and Links
443 controller.getObjectProperty(*it, BLOCK, SIM_FUNCTION_NAME, name);
445 // Find the "port blocks"
446 if (name == input || name == inimpl || name == output || name == outimpl)
448 std::vector<int> ipar;
449 controller.getObjectProperty(*it, BLOCK, IPAR, ipar);
450 if (ipar.size() != 1)
454 int portIndex = ipar[0];
456 // "name" is not enough to tell the event and data ports apart, so check the block's port.
457 object_properties_t kind;
458 std::vector<ScicosID> innerPort;
459 if (name == input || name == inimpl)
461 controller.getObjectProperty(*it, BLOCK, OUTPUTS, innerPort);
462 if (!innerPort.empty())
473 controller.getObjectProperty(*it, BLOCK, INPUTS, innerPort);
474 if (!innerPort.empty())
480 kind = EVENT_OUTPUTS;
484 std::vector<ScicosID> superPorts;
485 controller.getObjectProperty(adaptee, BLOCK, kind, superPorts);
486 if (static_cast<int>(superPorts.size()) < portIndex)
491 ScicosID port = superPorts[portIndex - 1];
493 // Check consistency of the implicitness between the inner and outer ports
495 controller.getObjectProperty(port, PORT, IMPLICIT, isImplicit);
496 if (name == input || name == output)
511 controller.setObjectProperty(*it, BLOCK, PORT_REFERENCE, port);
521 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
523 ScicosID adaptee = adaptor.getAdaptee()->id();
525 std::vector<ScicosID> diagramChildren;
526 controller.getObjectProperty(adaptee, BLOCK, CHILDREN, diagramChildren);
528 if (diagramChildren.empty())
530 std::vector<double> rpar;
531 controller.getObjectProperty(adaptee, BLOCK, RPAR, rpar);
534 types::Double* o = new types::Double((int)rpar.size(), 1, &data);
536 std::copy(rpar.begin(), rpar.end(), stdext::checked_array_iterator<double*>(data, rpar.size()));
538 std::copy(rpar.begin(), rpar.end(), data);
542 else // SuperBlock, return the contained diagram (allocating it on demand)
544 DiagramAdapter* diagram = adaptor.getDiagram();
547 * FIXME: Sync all diagram children as the blocks might be modified by xcos
554 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
556 ScicosID adaptee = adaptor.getAdaptee()->id();
558 if (v->getType() == types::InternalType::ScilabDouble)
560 types::Double* current = v->getAs<types::Double>();
562 std::vector<double> rpar (current->getSize());
563 for (int i = 0; i < current->getSize(); ++i)
565 rpar[i] = current->get(i);
568 controller.setObjectProperty(adaptee, BLOCK, RPAR, rpar);
571 else if (v->getType() == types::InternalType::ScilabString)
573 // Allow Text blocks to define strings in rpar
576 else if (v->getType() == types::InternalType::ScilabUserType)
578 // Make sure the input describes a Diagram
579 const Adapters::adapters_index_t adapter_index = Adapters::instance().lookup_by_typename(v->getShortTypeStr());
580 if (adapter_index != Adapters::DIAGRAM_ADAPTER)
585 // Translate 'v' to an DiagramAdapter ; copy if needed
586 DiagramAdapter* diagram;
589 diagram = v->clone()->getAs<DiagramAdapter>();
593 diagram = v->getAs<DiagramAdapter>();
595 adaptor.setDiagram(diagram);
597 // set the diagram children as block children ; referencing them
598 std::vector<ScicosID> diagramChildren;
599 controller.getObjectProperty(diagram->getAdaptee()->id(), DIAGRAM, CHILDREN, diagramChildren);
600 std::vector<ScicosID> oldDiagramChildren;
601 controller.getObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, oldDiagramChildren);
603 controller.setObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, diagramChildren);
605 std::sort(oldDiagramChildren.begin(), oldDiagramChildren.end());
606 for (const ScicosID id : diagramChildren)
608 if (id != 0 && !std::binary_search(oldDiagramChildren.begin(), oldDiagramChildren.end(), id))
610 auto o = controller.getObject(id);
611 controller.setObjectProperty(o->id(), o->kind(), PARENT_BLOCK, adaptor.getAdaptee()->id());
613 controller.referenceObject(id);
617 std::sort(diagramChildren.begin(), diagramChildren.end());
618 for (const ScicosID id : oldDiagramChildren)
620 if (id != 0 && !std::binary_search(diagramChildren.begin(), diagramChildren.end(), id))
622 auto o = controller.getObject(id);
623 controller.setObjectProperty(o->id(), o->kind(), PARENT_BLOCK, ScicosID());
625 controller.deleteObject(id);
630 // Link the Superblock ports to their inner "port blocks"
631 return setInnerBlocksRefs(adaptor, diagramChildren, controller);
640 double toDouble(const int a)
642 return static_cast<double>(a);
648 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
650 ScicosID adaptee = adaptor.getAdaptee()->id();
652 std::vector<int> ipar;
653 controller.getObjectProperty(adaptee, BLOCK, IPAR, ipar);
656 types::Double* o = new types::Double((int)ipar.size(), 1, &data);
659 std::transform(ipar.begin(), ipar.end(), stdext::checked_array_iterator<double*>(data, ipar.size()), toDouble);
661 std::transform(ipar.begin(), ipar.end(), data, toDouble);
666 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
668 ScicosID adaptee = adaptor.getAdaptee()->id();
670 if (v->getType() == types::InternalType::ScilabList)
672 std::vector<int> ipar;
673 controller.setObjectProperty(adaptee, BLOCK, IPAR, ipar);
677 if (v->getType() != types::InternalType::ScilabDouble)
682 types::Double* current = v->getAs<types::Double>();
683 if (current->getCols() != 0 && current->getCols() != 1)
688 std::vector<int> ipar (current->getSize());
689 for (int i = 0; i < current->getSize(); ++i)
691 if (floor(current->get(i)) != current->get(i))
695 ipar[i] = static_cast<int>(current->get(i));
698 controller.setObjectProperty(adaptee, BLOCK, IPAR, ipar);
706 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
708 ScicosID adaptee = adaptor.getAdaptee()->id();
710 std::vector<double> prop_content;
711 controller.getObjectProperty(adaptee, BLOCK, OPAR, prop_content);
713 // Corner-case, the empty content is an empty double
714 if (prop_content.empty())
716 return types::Double::Empty();
719 // The returned value is a list
720 types::InternalType* res;
721 if (!vec2var(prop_content, res))
729 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
731 ScicosID adaptee = adaptor.getAdaptee()->id();
733 // corner-case the empty content is an empty-double
734 if (v->getType() == types::InternalType::ScilabDouble)
736 types::Double* current = v->getAs<types::Double>();
737 if (current->getSize() != 0)
742 // prop_content should be empty
743 std::vector<double> prop_content;
744 controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content);
748 std::vector<double> prop_content;
749 if (!var2vec(v, prop_content))
754 controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content);
762 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
764 ScicosID adaptee = adaptor.getAdaptee()->id();
767 controller.getObjectProperty(adaptee, BLOCK, SIM_BLOCKTYPE, type);
769 types::String* o = new types::String(type.c_str());
773 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
775 ScicosID adaptee = adaptor.getAdaptee()->id();
777 if (v->getType() != types::InternalType::ScilabString)
782 types::String* current = v->getAs<types::String>();
783 if (current->getSize() != 1)
788 char* c_str = wide_string_to_UTF8(current->get(0));
789 std::string type (c_str);
792 // the value validation is performed on the model
793 return controller.setObjectProperty(adaptee, BLOCK, SIM_BLOCKTYPE, type) != FAIL;
800 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
802 return get_ports_property<ModelAdapter, FIRING>(adaptor, EVENT_OUTPUTS, controller);
805 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
807 return set_ports_property<ModelAdapter, FIRING>(adaptor, EVENT_OUTPUTS, controller, v);
814 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
816 ScicosID adaptee = adaptor.getAdaptee()->id();
818 std::vector<int> dep_ut;
819 controller.getObjectProperty(adaptee, BLOCK, SIM_DEP_UT, dep_ut);
822 types::Bool* o = new types::Bool(1, 2, &dep);
830 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
832 ScicosID adaptee = adaptor.getAdaptee()->id();
834 if (v->getType() != types::InternalType::ScilabBool)
839 types::Bool* current = v->getAs<types::Bool>();
840 if (current->getRows() != 1 || current->getCols() != 2)
845 std::vector<int> dep_ut (2);
846 dep_ut[0] = current->get(0);
847 dep_ut[1] = current->get(1);
849 controller.setObjectProperty(adaptee, BLOCK, SIM_DEP_UT, dep_ut);
857 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
859 ScicosID adaptee = adaptor.getAdaptee()->id();
862 controller.getObjectProperty(adaptee, BLOCK, LABEL, label);
864 types::String* o = new types::String(1, 1);
865 o->set(0, label.data());
870 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
872 if (v->getType() != types::InternalType::ScilabString)
877 types::String* current = v->getAs<types::String>();
878 if (current->getSize() != 1)
883 ScicosID adaptee = adaptor.getAdaptee()->id();
885 char* c_str = wide_string_to_UTF8(current->get(0));
886 std::string label(c_str);
889 controller.setObjectProperty(adaptee, BLOCK, LABEL, label);
897 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
899 ScicosID adaptee = adaptor.getAdaptee()->id();
901 std::vector<int> nzcross;
902 controller.getObjectProperty(adaptee, BLOCK, NZCROSS, nzcross);
905 types::Double* o = new types::Double((int)nzcross.size(), 1, &data);
908 std::transform(nzcross.begin(), nzcross.end(), stdext::checked_array_iterator<double*>(data, nzcross.size()), toDouble);
910 std::transform(nzcross.begin(), nzcross.end(), data, toDouble);
915 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
917 ScicosID adaptee = adaptor.getAdaptee()->id();
919 if (v->getType() != types::InternalType::ScilabDouble)
924 types::Double* current = v->getAs<types::Double>();
925 // Only allow vectors and empty matrices
926 if (!current->isVector() && current->getSize() != 0)
931 std::vector<int> nzcross (current->getSize());
932 for (int i = 0; i < current->getSize(); ++i)
934 if (floor(current->get(i)) != current->get(i))
938 nzcross[i] = static_cast<int>(current->get(i));
941 controller.setObjectProperty(adaptee, BLOCK, NZCROSS, nzcross);
949 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
951 ScicosID adaptee = adaptor.getAdaptee()->id();
953 std::vector<int> nmode;
954 controller.getObjectProperty(adaptee, BLOCK, NMODE, nmode);
957 types::Double* o = new types::Double((int)nmode.size(), 1, &data);
960 std::transform(nmode.begin(), nmode.end(), stdext::checked_array_iterator<double*>(data, nmode.size()), toDouble);
962 std::transform(nmode.begin(), nmode.end(), data, toDouble);
967 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
969 ScicosID adaptee = adaptor.getAdaptee()->id();
971 if (v->getType() != types::InternalType::ScilabDouble)
976 types::Double* current = v->getAs<types::Double>();
977 // Only allow vectors and empty matrices
978 if (!current->isVector() && current->getSize() != 0)
983 std::vector<int> nmode (current->getSize());
984 for (int i = 0; i < current->getSize(); ++i)
986 if (floor(current->get(i)) != current->get(i))
990 nmode[i] = static_cast<int>(current->get(i));
993 controller.setObjectProperty(adaptee, BLOCK, NMODE, nmode);
1001 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1003 ScicosID adaptee = adaptor.getAdaptee()->id();
1005 std::vector<std::string> equations;
1006 controller.getObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1008 if (equations.size() == 0)
1010 return new types::List();
1013 types::TList* o = new types::TList();
1015 // Header, starting with "modelica"
1016 types::String* header = new types::String(1, 5);
1017 header->set(0, modelica.c_str());
1018 header->set(1, model.c_str());
1019 header->set(2, inputs.c_str());
1020 header->set(3, outputs.c_str());
1021 header->set(4, parameters.c_str());
1025 if (equations[0].c_str() == std::string())
1027 o->set(1, types::Double::Empty());
1031 types::String* modelField = new types::String(1, 1);
1032 modelField->set(0, equations[0].c_str());
1033 o->set(1, modelField);
1037 std::istringstream inputsSizeStr (equations[1]);
1039 inputsSizeStr >> inputsSize;
1040 if (inputsSize == 0)
1042 types::Double* inputsField = types::Double::Empty();
1043 o->set(2, inputsField);
1047 types::String* inputsField = new types::String(inputsSize, 1);
1048 for (int i = 0; i < inputsSize; ++i)
1050 inputsField->set(i, equations[i + 2].c_str());
1052 o->set(2, inputsField);
1056 std::istringstream outputsSizeStr (equations[2 + inputsSize]);
1058 outputsSizeStr >> outputsSize;
1059 if (outputsSize == 0)
1061 types::Double* outputsField = types::Double::Empty();
1062 o->set(3, outputsField);
1066 types::String* outputsField = new types::String(outputsSize, 1);
1067 for (int i = 0; i < outputsSize; ++i)
1069 outputsField->set(i, equations[i + 3 + inputsSize].c_str());
1071 o->set(3, outputsField);
1075 types::List* parametersField = new types::List();
1077 // 'parameters' names
1078 std::istringstream parametersSizeStr (equations[3 + inputsSize + outputsSize]);
1080 parametersSizeStr >> parametersSize;
1081 if (parametersSize == 0)
1083 types::Double* parametersNames = types::Double::Empty();
1084 parametersField->set(0, parametersNames);
1088 types::String* parametersNames = new types::String(parametersSize, 1);
1089 for (int i = 0; i < parametersSize; ++i)
1091 parametersNames->set(i, equations[i + 4 + inputsSize + outputsSize].c_str());
1093 parametersField->set(0, parametersNames);
1096 // 'parameters' values
1097 types::List* parametersValues = new types::List();
1098 for (int i = 0; i < parametersSize; ++i)
1100 std::istringstream parametersValueStr (equations[i + 4 + inputsSize + outputsSize + parametersSize]);
1101 double parametersVal;
1102 parametersValueStr >> parametersVal;
1103 types::Double* parametersValue = new types::Double(parametersVal);
1104 parametersValues->set(i, parametersValue);
1106 parametersField->set(1, parametersValues);
1108 // 'parameters' states (optional, only check its presence if at least one parameter is present)
1109 if (parametersSize != 0)
1111 std::string parametersStatesBool (equations[4 + inputsSize + outputsSize + 2 * parametersSize]);
1112 if (strcmp(parametersStatesBool.c_str(), "T") == 0) // Check the presence of the "states" field
1114 types::Double* parametersStates = new types::Double(parametersSize, 1);
1115 for (int i = 0; i < parametersSize; ++i)
1117 std::istringstream parametersStateStr (equations[i + 5 + inputsSize + outputsSize + 2 * parametersSize]);
1118 double parametersState;
1119 parametersStateStr >> parametersState;
1120 parametersStates->set(i, parametersState);
1122 parametersField->set(2, parametersStates);
1126 o->set(4, parametersField);
1131 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1133 ScicosID adaptee = adaptor.getAdaptee()->id();
1135 if (v->getType() == types::InternalType::ScilabList)
1137 types::List* current = v->getAs<types::List>();
1138 if (current->getSize() != 0)
1145 if (v->getType() != types::InternalType::ScilabTList)
1150 types::TList* current = v->getAs<types::TList>();
1153 types::String* header = current->getFieldNames();
1154 if (header->getSize() != 5)
1158 if (header->get(0) != modelica)
1162 if (header->get(1) != model)
1166 if (header->get(2) != inputs)
1170 if (header->get(3) != outputs)
1174 if (header->get(4) != parameters)
1179 char* c_str; // Temporary buffer used for conversions
1182 std::vector<std::string> equations;
1183 if (current->get(1)->getType() == types::InternalType::ScilabString)
1185 types::String* modelField = current->get(1)->getAs<types::String>();
1186 if (modelField->getSize() != 1)
1191 c_str = wide_string_to_UTF8(modelField->get(0));
1192 std::string modelFieldStored(c_str);
1194 equations.push_back(modelFieldStored);
1196 else if (current->get(1)->getType() == types::InternalType::ScilabDouble)
1198 types::Double* modelFieldDouble = current->get(1)->getAs<types::Double>();
1199 if (modelFieldDouble->getSize() != 0)
1204 // An empty matrix stores an empty string, which will later be translated back to an empty matrix
1205 equations.push_back(std::string());
1214 if (current->get(2)->getType() == types::InternalType::ScilabDouble)
1216 types::Double* inputsField = current->get(2)->getAs<types::Double>();
1217 if (inputsField->getSize() != 0)
1223 std::ostringstream strInputs;
1224 strInputs << inputsSize;
1225 std::string inputsSizeStr = strInputs.str();
1226 equations.push_back(inputsSizeStr); // When 'inputs'=[], just insert "0" in 'equations'
1230 if (current->get(2)->getType() != types::InternalType::ScilabString)
1235 types::String* inputsField = current->get(2)->getAs<types::String>();
1236 inputsSize = inputsField->getSize();
1237 equations.resize(equations.size() + 1 + inputsSize);
1238 std::ostringstream strInputs;
1239 strInputs << inputsSize;
1240 std::string inputsSizeStr = strInputs.str();
1241 equations[1] = inputsSizeStr; // Saving the size of the 'inputs' field'
1242 for (size_t i = 0; i < inputsSize; ++i)
1244 c_str = wide_string_to_UTF8(inputsField->get(static_cast<int>(i)));
1245 std::string inputsFieldStored(c_str);
1247 equations[i + 2] = inputsFieldStored;
1253 if (current->get(3)->getType() == types::InternalType::ScilabDouble)
1255 types::Double* outputsField = current->get(3)->getAs<types::Double>();
1256 if (outputsField->getSize() != 0)
1262 std::ostringstream strOutputs;
1263 strOutputs << outputsSize;
1264 std::string outputsSizeStr = strOutputs.str();
1265 equations.push_back(outputsSizeStr); // When 'outputs'=[], just insert "0" in 'equations'
1269 if (current->get(3)->getType() != types::InternalType::ScilabString)
1274 types::String* outputsField = current->get(3)->getAs<types::String>();
1275 outputsSize = outputsField->getSize();
1276 equations.resize(equations.size() + 1 + outputsSize);
1277 std::ostringstream strOutputs;
1278 strOutputs << outputsSize;
1279 std::string outputsSizeStr = strOutputs.str();
1280 equations[2 + inputsSize] = outputsSizeStr; // Saving the size of the 'outputs' field'
1281 for (size_t i = 0; i < outputsSize; ++i)
1283 c_str = wide_string_to_UTF8(outputsField->get(static_cast<int>(i)));
1284 std::string outputsFieldStored(c_str);
1286 equations[i + 3 + inputsSize] = outputsFieldStored;
1291 int parametersIndex = 4;
1292 if (current->get(parametersIndex)->getType() == types::InternalType::ScilabDouble)
1294 // For backward compatibility sake, allow the presence of an empty matrix here
1295 types::Double* emptyMatrix = current->get(parametersIndex)->getAs<types::Double>();
1296 if (emptyMatrix->getSize() != 0)
1304 if (current->get(parametersIndex)->getType() != types::InternalType::ScilabList)
1309 types::List* list = current->get(parametersIndex)->getAs<types::List>();
1310 if (list->getSize() != 2 && list->getSize() != 3)
1315 // 'parameters' names
1316 size_t parametersSize;
1317 if (list->get(0)->getType() == types::InternalType::ScilabDouble)
1319 types::Double* parametersNames = list->get(0)->getAs<types::Double>();
1320 if (parametersNames->getSize() != 0)
1325 // When 'parameters(1)'=[], just insert "0" in 'equations', set in the model and return
1327 std::ostringstream strParameters;
1328 strParameters << parametersSize;
1329 std::string parametersSizeStr = strParameters.str();
1330 equations.push_back(parametersSizeStr);
1332 controller.setObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1337 if (list->get(0)->getType() != types::InternalType::ScilabString)
1342 types::String* parametersNames = list->get(0)->getAs<types::String>();
1343 parametersSize = parametersNames->getSize();
1344 equations.resize(equations.size() + 1 + parametersSize);
1345 std::ostringstream strParameters;
1346 strParameters << parametersSize;
1347 std::string parametersSizeStr = strParameters.str();
1348 equations[3 + inputsSize + outputsSize] = parametersSizeStr; // Saving the size of the 'parameters' field'
1349 for (size_t i = 0; i < parametersSize; ++i)
1351 c_str = wide_string_to_UTF8(parametersNames->get(static_cast<int>(i)));
1352 std::string parametersName(c_str);
1354 equations[i + 4 + inputsSize + outputsSize] = parametersName;
1358 // 'parameters' values
1359 if (list->get(1)->getType() == types::InternalType::ScilabDouble)
1361 types::Double* parameterVal = list->get(1)->getAs<types::Double>();
1362 if (parameterVal->getSize() != static_cast<int>(parametersSize))
1367 for (size_t i = 0; i < parametersSize; ++i)
1369 std::ostringstream strParameterVal;
1370 strParameterVal << parameterVal->get(static_cast<int>(i));
1371 std::string parameterValStr = strParameterVal.str();
1372 equations.push_back(parameterValStr);
1377 if (list->get(1)->getType() != types::InternalType::ScilabList)
1382 types::List* list2 = list->get(1)->getAs<types::List>();
1383 if (list2->getSize() != static_cast<int>(parametersSize))
1388 equations.resize(equations.size() + parametersSize);
1389 for (size_t i = 0; i < parametersSize; ++i)
1391 if (list2->get(static_cast<int>(i))->getType() != types::InternalType::ScilabDouble)
1396 types::Double* parametersVal = list2->get(static_cast<int>(i))->getAs<types::Double>();
1397 if (parametersVal->getSize() != 1)
1402 std::ostringstream strParametersVal;
1403 strParametersVal << parametersVal->get(0);
1404 std::string parametersValStr = strParametersVal.str();
1405 equations[i + 4 + inputsSize + outputsSize + parametersSize] = parametersValStr;
1409 // 'parameters' states (optional)
1410 equations.push_back("F"); // String boolean to indicate the presence, or not, of a "states" field
1411 if (list->getSize() == 3)
1413 equations.back() = "T";
1414 if (list->get(2)->getType() != types::InternalType::ScilabDouble)
1419 types::Double* parameterStates = list->get(2)->getAs<types::Double>();
1420 if (parameterStates->getSize() != static_cast<int>(parametersSize))
1425 for (size_t i = 0; i < parametersSize; ++i)
1427 std::ostringstream strParameterStates;
1428 strParameterStates << parameterStates->get(static_cast<int>(i));
1429 std::string parameterStatesStr = strParameterStates.str();
1430 equations.push_back(parameterStatesStr);
1434 controller.setObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1442 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1444 ScicosID adaptee = adaptor.getAdaptee()->id();
1447 controller.getObjectProperty(adaptee, BLOCK, UID, uid);
1449 types::String* o = new types::String(1, 1);
1450 o->set(0, uid.data());
1455 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1457 if (v->getType() != types::InternalType::ScilabString)
1462 types::String* current = v->getAs<types::String>();
1463 if (current->getSize() != 1)
1468 ScicosID adaptee = adaptor.getAdaptee()->id();
1470 char* c_str = wide_string_to_UTF8(current->get(0));
1471 std::string uid(c_str);
1474 controller.setObjectProperty(adaptee, BLOCK, UID, uid);
1481 template<> property<ModelAdapter>::props_t property<ModelAdapter>::fields = property<ModelAdapter>::props_t();
1482 static void initialize_fields()
1484 if (property<ModelAdapter>::properties_have_not_been_set())
1486 property<ModelAdapter>::fields.reserve(23);
1487 property<ModelAdapter>::add_property(L"sim", &sim::get, &sim::set);
1488 property<ModelAdapter>::add_property(L"in", &in::get, &in::set);
1489 property<ModelAdapter>::add_property(L"in2", &in2::get, &in2::set);
1490 property<ModelAdapter>::add_property(L"intyp", &intyp::get, &intyp::set);
1491 property<ModelAdapter>::add_property(L"out", &out::get, &out::set);
1492 property<ModelAdapter>::add_property(L"out2", &out2::get, &out2::set);
1493 property<ModelAdapter>::add_property(L"outtyp", &outtyp::get, &outtyp::set);
1494 property<ModelAdapter>::add_property(L"evtin", &evtin::get, &evtin::set);
1495 property<ModelAdapter>::add_property(L"evtout", &evtout::get, &evtout::set);
1496 property<ModelAdapter>::add_property(L"state", &state::get, &state::set);
1497 property<ModelAdapter>::add_property(L"dstate", &dstate::get, &dstate::set);
1498 property<ModelAdapter>::add_property(L"odstate", &odstate::get, &odstate::set);
1499 property<ModelAdapter>::add_property(L"rpar", &rpar::get, &rpar::set);
1500 property<ModelAdapter>::add_property(L"ipar", &ipar::get, &ipar::set);
1501 property<ModelAdapter>::add_property(L"opar", &opar::get, &opar::set);
1502 property<ModelAdapter>::add_property(L"blocktype", &blocktype::get, &blocktype::set);
1503 property<ModelAdapter>::add_property(L"firing", &firing::get, &firing::set);
1504 property<ModelAdapter>::add_property(L"dep_ut", &dep_ut::get, &dep_ut::set);
1505 property<ModelAdapter>::add_property(L"label", &label::get, &label::set);
1506 property<ModelAdapter>::add_property(L"nzcross", &nzcross::get, &nzcross::set);
1507 property<ModelAdapter>::add_property(L"nmode", &nmode::get, &nmode::set);
1508 property<ModelAdapter>::add_property(L"equations", &equations::get, &equations::set);
1509 property<ModelAdapter>::add_property(L"uid", &uid::get, &uid::set);
1513 ModelAdapter::ModelAdapter() :
1514 BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(),
1515 m_diagramAdapter(nullptr)
1517 initialize_fields();
1519 ModelAdapter::ModelAdapter(const Controller& c, model::Block* adaptee, DiagramAdapter* diagramAdapter) :
1520 BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(c, adaptee),
1521 m_diagramAdapter(diagramAdapter)
1523 initialize_fields();
1526 ModelAdapter::~ModelAdapter()
1530 std::wstring ModelAdapter::getTypeStr()
1532 return getSharedTypeStr();
1535 std::wstring ModelAdapter::getShortTypeStr()
1537 return getSharedTypeStr();
1540 DiagramAdapter* ModelAdapter::getDiagram() const
1542 return m_diagramAdapter;
1545 void ModelAdapter::setDiagram(DiagramAdapter* diagramAdapter)
1547 // does not increment reference as this adapter does not own the DiagramAdapter
1548 m_diagramAdapter = diagramAdapter;
1551 } /* namespace view_scilab */
1552 } /* namespace org_scilab_modules_scicos */