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)
442 continue; // Rule out mlists (Deleted or Annotations)
445 if (controller.getObject(*it)->kind() == BLOCK) // Rule out Annotations and Links
448 controller.getObjectProperty(*it, BLOCK, SIM_FUNCTION_NAME, name);
450 // Find the "port blocks"
451 if (name == input || name == inimpl || name == output || name == outimpl)
453 std::vector<int> ipar;
454 controller.getObjectProperty(*it, BLOCK, IPAR, ipar);
455 if (ipar.size() != 1)
459 int portIndex = ipar[0];
461 // "name" is not enough to tell the event and data ports apart, so check the block's port.
462 object_properties_t kind;
463 std::vector<ScicosID> innerPort;
464 if (name == input || name == inimpl)
466 controller.getObjectProperty(*it, BLOCK, OUTPUTS, innerPort);
467 if (!innerPort.empty())
478 controller.getObjectProperty(*it, BLOCK, INPUTS, innerPort);
479 if (!innerPort.empty())
485 kind = EVENT_OUTPUTS;
489 std::vector<ScicosID> superPorts;
490 controller.getObjectProperty(adaptee, BLOCK, kind, superPorts);
491 if (static_cast<int>(superPorts.size()) < portIndex)
496 ScicosID port = superPorts[portIndex - 1];
498 // Check consistency of the implicitness between the inner and outer ports
500 controller.getObjectProperty(port, PORT, IMPLICIT, isImplicit);
501 if (name == input || name == output)
516 controller.setObjectProperty(*it, BLOCK, PORT_REFERENCE, port);
526 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
528 ScicosID adaptee = adaptor.getAdaptee()->id();
530 std::vector<ScicosID> diagramChildren;
531 controller.getObjectProperty(adaptee, BLOCK, CHILDREN, diagramChildren);
533 if (diagramChildren.empty())
535 std::vector<double> rpar;
536 controller.getObjectProperty(adaptee, BLOCK, RPAR, rpar);
539 types::Double* o = new types::Double((int)rpar.size(), 1, &data);
541 std::copy(rpar.begin(), rpar.end(), stdext::checked_array_iterator<double*>(data, rpar.size()));
543 std::copy(rpar.begin(), rpar.end(), data);
547 else // SuperBlock, return the contained diagram (allocating it on demand)
549 DiagramAdapter* diagram = adaptor.getDiagram();
552 * FIXME: Sync all diagram children as the blocks might be modified by xcos
559 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
561 ScicosID adaptee = adaptor.getAdaptee()->id();
563 if (v->getType() == types::InternalType::ScilabDouble)
565 types::Double* current = v->getAs<types::Double>();
567 std::vector<double> rpar (current->getSize());
568 for (int i = 0; i < current->getSize(); ++i)
570 rpar[i] = current->get(i);
573 controller.setObjectProperty(adaptee, BLOCK, RPAR, rpar);
576 else if (v->getType() == types::InternalType::ScilabString)
578 // Allow Text blocks to define strings in rpar
581 else if (v->getType() == types::InternalType::ScilabUserType)
583 // Make sure the input describes a Diagram
584 const Adapters::adapters_index_t adapter_index = Adapters::instance().lookup_by_typename(v->getShortTypeStr());
585 if (adapter_index != Adapters::DIAGRAM_ADAPTER)
590 // Translate 'v' to an DiagramAdapter ; copy if needed
591 DiagramAdapter* diagram;
594 diagram = v->clone()->getAs<DiagramAdapter>();
598 diagram = v->getAs<DiagramAdapter>();
600 adaptor.setDiagram(diagram);
602 // set the diagram children as block children ; referencing them
603 std::vector<ScicosID> diagramChildren;
604 controller.getObjectProperty(diagram->getAdaptee()->id(), DIAGRAM, CHILDREN, diagramChildren);
605 std::vector<ScicosID> oldDiagramChildren;
606 controller.getObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, oldDiagramChildren);
608 controller.setObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, diagramChildren);
610 std::sort(oldDiagramChildren.begin(), oldDiagramChildren.end());
611 for (const ScicosID id : diagramChildren)
613 if (id != 0 && !std::binary_search(oldDiagramChildren.begin(), oldDiagramChildren.end(), id))
615 auto o = controller.getObject(id);
616 controller.setObjectProperty(o->id(), o->kind(), PARENT_BLOCK, adaptor.getAdaptee()->id());
618 controller.referenceObject(id);
622 std::sort(diagramChildren.begin(), diagramChildren.end());
623 for (const ScicosID id : oldDiagramChildren)
625 if (id != 0 && !std::binary_search(diagramChildren.begin(), diagramChildren.end(), id))
627 auto o = controller.getObject(id);
628 controller.setObjectProperty(o->id(), o->kind(), PARENT_BLOCK, ScicosID());
630 controller.deleteObject(id);
635 // Link the Superblock ports to their inner "port blocks"
636 return setInnerBlocksRefs(adaptor, diagramChildren, controller);
645 double toDouble(const int a)
647 return static_cast<double>(a);
653 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
655 ScicosID adaptee = adaptor.getAdaptee()->id();
657 std::vector<int> ipar;
658 controller.getObjectProperty(adaptee, BLOCK, IPAR, ipar);
661 types::Double* o = new types::Double((int)ipar.size(), 1, &data);
664 std::transform(ipar.begin(), ipar.end(), stdext::checked_array_iterator<double*>(data, ipar.size()), toDouble);
666 std::transform(ipar.begin(), ipar.end(), data, toDouble);
671 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
673 ScicosID adaptee = adaptor.getAdaptee()->id();
675 if (v->getType() == types::InternalType::ScilabList)
677 std::vector<int> ipar;
678 controller.setObjectProperty(adaptee, BLOCK, IPAR, ipar);
682 if (v->getType() != types::InternalType::ScilabDouble)
687 types::Double* current = v->getAs<types::Double>();
688 if (current->getCols() != 0 && current->getCols() != 1)
693 std::vector<int> ipar (current->getSize());
694 for (int i = 0; i < current->getSize(); ++i)
696 if (floor(current->get(i)) != current->get(i))
700 ipar[i] = static_cast<int>(current->get(i));
703 controller.setObjectProperty(adaptee, BLOCK, IPAR, ipar);
711 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
713 ScicosID adaptee = adaptor.getAdaptee()->id();
715 std::vector<double> prop_content;
716 controller.getObjectProperty(adaptee, BLOCK, OPAR, prop_content);
718 // Corner-case, the empty content is an empty double
719 if (prop_content.empty())
721 return types::Double::Empty();
724 // The returned value is a list
725 types::InternalType* res;
726 if (!vec2var(prop_content, res))
734 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
736 ScicosID adaptee = adaptor.getAdaptee()->id();
738 // corner-case the empty content is an empty-double
739 if (v->getType() == types::InternalType::ScilabDouble)
741 types::Double* current = v->getAs<types::Double>();
742 if (current->getSize() != 0)
747 // prop_content should be empty
748 std::vector<double> prop_content;
749 controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content);
753 std::vector<double> prop_content;
754 if (!var2vec(v, prop_content))
759 controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content);
767 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
769 ScicosID adaptee = adaptor.getAdaptee()->id();
772 controller.getObjectProperty(adaptee, BLOCK, SIM_BLOCKTYPE, type);
774 types::String* o = new types::String(type.c_str());
778 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
780 ScicosID adaptee = adaptor.getAdaptee()->id();
782 if (v->getType() != types::InternalType::ScilabString)
787 types::String* current = v->getAs<types::String>();
788 if (current->getSize() != 1)
793 char* c_str = wide_string_to_UTF8(current->get(0));
794 std::string type (c_str);
797 // the value validation is performed on the model
798 return controller.setObjectProperty(adaptee, BLOCK, SIM_BLOCKTYPE, type) != FAIL;
805 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
807 return get_ports_property<ModelAdapter, FIRING>(adaptor, EVENT_OUTPUTS, controller);
810 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
812 return set_ports_property<ModelAdapter, FIRING>(adaptor, EVENT_OUTPUTS, controller, v);
819 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
821 ScicosID adaptee = adaptor.getAdaptee()->id();
823 std::vector<int> dep_ut;
824 controller.getObjectProperty(adaptee, BLOCK, SIM_DEP_UT, dep_ut);
827 types::Bool* o = new types::Bool(1, 2, &dep);
835 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
837 ScicosID adaptee = adaptor.getAdaptee()->id();
839 if (v->getType() != types::InternalType::ScilabBool)
844 types::Bool* current = v->getAs<types::Bool>();
845 if (current->getRows() != 1 || current->getCols() != 2)
850 std::vector<int> dep_ut (2);
851 dep_ut[0] = current->get(0);
852 dep_ut[1] = current->get(1);
854 controller.setObjectProperty(adaptee, BLOCK, SIM_DEP_UT, dep_ut);
862 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
864 ScicosID adaptee = adaptor.getAdaptee()->id();
867 controller.getObjectProperty(adaptee, BLOCK, LABEL, label);
869 types::String* o = new types::String(1, 1);
870 o->set(0, label.data());
875 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
877 if (v->getType() != types::InternalType::ScilabString)
882 types::String* current = v->getAs<types::String>();
883 if (current->getSize() != 1)
888 ScicosID adaptee = adaptor.getAdaptee()->id();
890 char* c_str = wide_string_to_UTF8(current->get(0));
891 std::string label(c_str);
894 controller.setObjectProperty(adaptee, BLOCK, LABEL, label);
902 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
904 ScicosID adaptee = adaptor.getAdaptee()->id();
906 std::vector<int> nzcross;
907 controller.getObjectProperty(adaptee, BLOCK, NZCROSS, nzcross);
910 types::Double* o = new types::Double((int)nzcross.size(), 1, &data);
913 std::transform(nzcross.begin(), nzcross.end(), stdext::checked_array_iterator<double*>(data, nzcross.size()), toDouble);
915 std::transform(nzcross.begin(), nzcross.end(), data, toDouble);
920 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
922 ScicosID adaptee = adaptor.getAdaptee()->id();
924 if (v->getType() != types::InternalType::ScilabDouble)
929 types::Double* current = v->getAs<types::Double>();
930 // Only allow vectors and empty matrices
931 if (!current->isVector() && current->getSize() != 0)
936 std::vector<int> nzcross (current->getSize());
937 for (int i = 0; i < current->getSize(); ++i)
939 if (floor(current->get(i)) != current->get(i))
943 nzcross[i] = static_cast<int>(current->get(i));
946 controller.setObjectProperty(adaptee, BLOCK, NZCROSS, nzcross);
954 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
956 ScicosID adaptee = adaptor.getAdaptee()->id();
958 std::vector<int> nmode;
959 controller.getObjectProperty(adaptee, BLOCK, NMODE, nmode);
962 types::Double* o = new types::Double((int)nmode.size(), 1, &data);
965 std::transform(nmode.begin(), nmode.end(), stdext::checked_array_iterator<double*>(data, nmode.size()), toDouble);
967 std::transform(nmode.begin(), nmode.end(), data, toDouble);
972 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
974 ScicosID adaptee = adaptor.getAdaptee()->id();
976 if (v->getType() != types::InternalType::ScilabDouble)
981 types::Double* current = v->getAs<types::Double>();
982 // Only allow vectors and empty matrices
983 if (!current->isVector() && current->getSize() != 0)
988 std::vector<int> nmode (current->getSize());
989 for (int i = 0; i < current->getSize(); ++i)
991 if (floor(current->get(i)) != current->get(i))
995 nmode[i] = static_cast<int>(current->get(i));
998 controller.setObjectProperty(adaptee, BLOCK, NMODE, nmode);
1006 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1008 ScicosID adaptee = adaptor.getAdaptee()->id();
1010 std::vector<std::string> equations;
1011 controller.getObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1013 if (equations.size() == 0)
1015 return new types::List();
1018 types::TList* o = new types::TList();
1020 // Header, starting with "modelica"
1021 types::String* header = new types::String(1, 5);
1022 header->set(0, modelica.c_str());
1023 header->set(1, model.c_str());
1024 header->set(2, inputs.c_str());
1025 header->set(3, outputs.c_str());
1026 header->set(4, parameters.c_str());
1030 if (equations[0].c_str() == std::string())
1032 o->set(1, types::Double::Empty());
1036 types::String* modelField = new types::String(1, 1);
1037 modelField->set(0, equations[0].c_str());
1038 o->set(1, modelField);
1042 std::istringstream inputsSizeStr (equations[1]);
1044 inputsSizeStr >> inputsSize;
1045 if (inputsSize == 0)
1047 types::Double* inputsField = types::Double::Empty();
1048 o->set(2, inputsField);
1052 types::String* inputsField = new types::String(inputsSize, 1);
1053 for (int i = 0; i < inputsSize; ++i)
1055 inputsField->set(i, equations[i + 2].c_str());
1057 o->set(2, inputsField);
1061 std::istringstream outputsSizeStr (equations[2 + inputsSize]);
1063 outputsSizeStr >> outputsSize;
1064 if (outputsSize == 0)
1066 types::Double* outputsField = types::Double::Empty();
1067 o->set(3, outputsField);
1071 types::String* outputsField = new types::String(outputsSize, 1);
1072 for (int i = 0; i < outputsSize; ++i)
1074 outputsField->set(i, equations[i + 3 + inputsSize].c_str());
1076 o->set(3, outputsField);
1080 types::List* parametersField = new types::List();
1082 // 'parameters' names
1083 std::istringstream parametersSizeStr (equations[3 + inputsSize + outputsSize]);
1085 parametersSizeStr >> parametersSize;
1086 if (parametersSize == 0)
1088 types::Double* parametersNames = types::Double::Empty();
1089 parametersField->set(0, parametersNames);
1093 types::String* parametersNames = new types::String(parametersSize, 1);
1094 for (int i = 0; i < parametersSize; ++i)
1096 parametersNames->set(i, equations[i + 4 + inputsSize + outputsSize].c_str());
1098 parametersField->set(0, parametersNames);
1101 // 'parameters' values
1102 types::List* parametersValues = new types::List();
1103 for (int i = 0; i < parametersSize; ++i)
1105 std::istringstream parametersValueStr (equations[i + 4 + inputsSize + outputsSize + parametersSize]);
1106 double parametersVal;
1107 parametersValueStr >> parametersVal;
1108 types::Double* parametersValue = new types::Double(parametersVal);
1109 parametersValues->set(i, parametersValue);
1111 parametersField->set(1, parametersValues);
1113 // 'parameters' states (optional, only check its presence if at least one parameter is present)
1114 if (parametersSize != 0)
1116 std::string parametersStatesBool (equations[4 + inputsSize + outputsSize + 2 * parametersSize]);
1117 if (strcmp(parametersStatesBool.c_str(), "T") == 0) // Check the presence of the "states" field
1119 types::Double* parametersStates = new types::Double(parametersSize, 1);
1120 for (int i = 0; i < parametersSize; ++i)
1122 std::istringstream parametersStateStr (equations[i + 5 + inputsSize + outputsSize + 2 * parametersSize]);
1123 double parametersState;
1124 parametersStateStr >> parametersState;
1125 parametersStates->set(i, parametersState);
1127 parametersField->set(2, parametersStates);
1131 o->set(4, parametersField);
1136 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1138 ScicosID adaptee = adaptor.getAdaptee()->id();
1140 if (v->getType() == types::InternalType::ScilabList)
1142 types::List* current = v->getAs<types::List>();
1143 if (current->getSize() != 0)
1150 if (v->getType() != types::InternalType::ScilabTList)
1155 types::TList* current = v->getAs<types::TList>();
1158 types::String* header = current->getFieldNames();
1159 if (header->getSize() != 5)
1163 if (header->get(0) != modelica)
1167 if (header->get(1) != model)
1171 if (header->get(2) != inputs)
1175 if (header->get(3) != outputs)
1179 if (header->get(4) != parameters)
1184 char* c_str; // Temporary buffer used for conversions
1187 std::vector<std::string> equations;
1188 if (current->get(1)->getType() == types::InternalType::ScilabString)
1190 types::String* modelField = current->get(1)->getAs<types::String>();
1191 if (modelField->getSize() != 1)
1196 c_str = wide_string_to_UTF8(modelField->get(0));
1197 std::string modelFieldStored(c_str);
1199 equations.push_back(modelFieldStored);
1201 else if (current->get(1)->getType() == types::InternalType::ScilabDouble)
1203 types::Double* modelFieldDouble = current->get(1)->getAs<types::Double>();
1204 if (modelFieldDouble->getSize() != 0)
1209 // An empty matrix stores an empty string, which will later be translated back to an empty matrix
1210 equations.push_back(std::string());
1219 if (current->get(2)->getType() == types::InternalType::ScilabDouble)
1221 types::Double* inputsField = current->get(2)->getAs<types::Double>();
1222 if (inputsField->getSize() != 0)
1228 std::ostringstream strInputs;
1229 strInputs << inputsSize;
1230 std::string inputsSizeStr = strInputs.str();
1231 equations.push_back(inputsSizeStr); // When 'inputs'=[], just insert "0" in 'equations'
1235 if (current->get(2)->getType() != types::InternalType::ScilabString)
1240 types::String* inputsField = current->get(2)->getAs<types::String>();
1241 inputsSize = inputsField->getSize();
1242 equations.resize(equations.size() + 1 + inputsSize);
1243 std::ostringstream strInputs;
1244 strInputs << inputsSize;
1245 std::string inputsSizeStr = strInputs.str();
1246 equations[1] = inputsSizeStr; // Saving the size of the 'inputs' field'
1247 for (size_t i = 0; i < inputsSize; ++i)
1249 c_str = wide_string_to_UTF8(inputsField->get(static_cast<int>(i)));
1250 std::string inputsFieldStored(c_str);
1252 equations[i + 2] = inputsFieldStored;
1258 if (current->get(3)->getType() == types::InternalType::ScilabDouble)
1260 types::Double* outputsField = current->get(3)->getAs<types::Double>();
1261 if (outputsField->getSize() != 0)
1267 std::ostringstream strOutputs;
1268 strOutputs << outputsSize;
1269 std::string outputsSizeStr = strOutputs.str();
1270 equations.push_back(outputsSizeStr); // When 'outputs'=[], just insert "0" in 'equations'
1274 if (current->get(3)->getType() != types::InternalType::ScilabString)
1279 types::String* outputsField = current->get(3)->getAs<types::String>();
1280 outputsSize = outputsField->getSize();
1281 equations.resize(equations.size() + 1 + outputsSize);
1282 std::ostringstream strOutputs;
1283 strOutputs << outputsSize;
1284 std::string outputsSizeStr = strOutputs.str();
1285 equations[2 + inputsSize] = outputsSizeStr; // Saving the size of the 'outputs' field'
1286 for (size_t i = 0; i < outputsSize; ++i)
1288 c_str = wide_string_to_UTF8(outputsField->get(static_cast<int>(i)));
1289 std::string outputsFieldStored(c_str);
1291 equations[i + 3 + inputsSize] = outputsFieldStored;
1296 int parametersIndex = 4;
1297 if (current->get(parametersIndex)->getType() == types::InternalType::ScilabDouble)
1299 // For backward compatibility sake, allow the presence of an empty matrix here
1300 types::Double* emptyMatrix = current->get(parametersIndex)->getAs<types::Double>();
1301 if (emptyMatrix->getSize() != 0)
1309 if (current->get(parametersIndex)->getType() != types::InternalType::ScilabList)
1314 types::List* list = current->get(parametersIndex)->getAs<types::List>();
1315 if (list->getSize() != 2 && list->getSize() != 3)
1320 // 'parameters' names
1321 size_t parametersSize;
1322 if (list->get(0)->getType() == types::InternalType::ScilabDouble)
1324 types::Double* parametersNames = list->get(0)->getAs<types::Double>();
1325 if (parametersNames->getSize() != 0)
1330 // When 'parameters(1)'=[], just insert "0" in 'equations', set in the model and return
1332 std::ostringstream strParameters;
1333 strParameters << parametersSize;
1334 std::string parametersSizeStr = strParameters.str();
1335 equations.push_back(parametersSizeStr);
1337 controller.setObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1342 if (list->get(0)->getType() != types::InternalType::ScilabString)
1347 types::String* parametersNames = list->get(0)->getAs<types::String>();
1348 parametersSize = parametersNames->getSize();
1349 equations.resize(equations.size() + 1 + parametersSize);
1350 std::ostringstream strParameters;
1351 strParameters << parametersSize;
1352 std::string parametersSizeStr = strParameters.str();
1353 equations[3 + inputsSize + outputsSize] = parametersSizeStr; // Saving the size of the 'parameters' field'
1354 for (size_t i = 0; i < parametersSize; ++i)
1356 c_str = wide_string_to_UTF8(parametersNames->get(static_cast<int>(i)));
1357 std::string parametersName(c_str);
1359 equations[i + 4 + inputsSize + outputsSize] = parametersName;
1363 // 'parameters' values
1364 if (list->get(1)->getType() == types::InternalType::ScilabDouble)
1366 types::Double* parameterVal = list->get(1)->getAs<types::Double>();
1367 if (parameterVal->getSize() != static_cast<int>(parametersSize))
1372 for (size_t i = 0; i < parametersSize; ++i)
1374 std::ostringstream strParameterVal;
1375 strParameterVal << parameterVal->get(static_cast<int>(i));
1376 std::string parameterValStr = strParameterVal.str();
1377 equations.push_back(parameterValStr);
1382 if (list->get(1)->getType() != types::InternalType::ScilabList)
1387 types::List* list2 = list->get(1)->getAs<types::List>();
1388 if (list2->getSize() != static_cast<int>(parametersSize))
1393 equations.resize(equations.size() + parametersSize);
1394 for (size_t i = 0; i < parametersSize; ++i)
1396 if (list2->get(static_cast<int>(i))->getType() != types::InternalType::ScilabDouble)
1401 types::Double* parametersVal = list2->get(static_cast<int>(i))->getAs<types::Double>();
1402 if (parametersVal->getSize() != 1)
1407 std::ostringstream strParametersVal;
1408 strParametersVal << parametersVal->get(0);
1409 std::string parametersValStr = strParametersVal.str();
1410 equations[i + 4 + inputsSize + outputsSize + parametersSize] = parametersValStr;
1414 // 'parameters' states (optional)
1415 equations.push_back("F"); // String boolean to indicate the presence, or not, of a "states" field
1416 if (list->getSize() == 3)
1418 equations.back() = "T";
1419 if (list->get(2)->getType() != types::InternalType::ScilabDouble)
1424 types::Double* parameterStates = list->get(2)->getAs<types::Double>();
1425 if (parameterStates->getSize() != static_cast<int>(parametersSize))
1430 for (size_t i = 0; i < parametersSize; ++i)
1432 std::ostringstream strParameterStates;
1433 strParameterStates << parameterStates->get(static_cast<int>(i));
1434 std::string parameterStatesStr = strParameterStates.str();
1435 equations.push_back(parameterStatesStr);
1439 controller.setObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1447 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1449 ScicosID adaptee = adaptor.getAdaptee()->id();
1452 controller.getObjectProperty(adaptee, BLOCK, UID, uid);
1454 types::String* o = new types::String(1, 1);
1455 o->set(0, uid.data());
1460 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1462 if (v->getType() != types::InternalType::ScilabString)
1467 types::String* current = v->getAs<types::String>();
1468 if (current->getSize() != 1)
1473 ScicosID adaptee = adaptor.getAdaptee()->id();
1475 char* c_str = wide_string_to_UTF8(current->get(0));
1476 std::string uid(c_str);
1479 controller.setObjectProperty(adaptee, BLOCK, UID, uid);
1486 template<> property<ModelAdapter>::props_t property<ModelAdapter>::fields = property<ModelAdapter>::props_t();
1487 static void initialize_fields()
1489 if (property<ModelAdapter>::properties_have_not_been_set())
1491 property<ModelAdapter>::fields.reserve(23);
1492 property<ModelAdapter>::add_property(L"sim", &sim::get, &sim::set);
1493 property<ModelAdapter>::add_property(L"in", &in::get, &in::set);
1494 property<ModelAdapter>::add_property(L"in2", &in2::get, &in2::set);
1495 property<ModelAdapter>::add_property(L"intyp", &intyp::get, &intyp::set);
1496 property<ModelAdapter>::add_property(L"out", &out::get, &out::set);
1497 property<ModelAdapter>::add_property(L"out2", &out2::get, &out2::set);
1498 property<ModelAdapter>::add_property(L"outtyp", &outtyp::get, &outtyp::set);
1499 property<ModelAdapter>::add_property(L"evtin", &evtin::get, &evtin::set);
1500 property<ModelAdapter>::add_property(L"evtout", &evtout::get, &evtout::set);
1501 property<ModelAdapter>::add_property(L"state", &state::get, &state::set);
1502 property<ModelAdapter>::add_property(L"dstate", &dstate::get, &dstate::set);
1503 property<ModelAdapter>::add_property(L"odstate", &odstate::get, &odstate::set);
1504 property<ModelAdapter>::add_property(L"rpar", &rpar::get, &rpar::set);
1505 property<ModelAdapter>::add_property(L"ipar", &ipar::get, &ipar::set);
1506 property<ModelAdapter>::add_property(L"opar", &opar::get, &opar::set);
1507 property<ModelAdapter>::add_property(L"blocktype", &blocktype::get, &blocktype::set);
1508 property<ModelAdapter>::add_property(L"firing", &firing::get, &firing::set);
1509 property<ModelAdapter>::add_property(L"dep_ut", &dep_ut::get, &dep_ut::set);
1510 property<ModelAdapter>::add_property(L"label", &label::get, &label::set);
1511 property<ModelAdapter>::add_property(L"nzcross", &nzcross::get, &nzcross::set);
1512 property<ModelAdapter>::add_property(L"nmode", &nmode::get, &nmode::set);
1513 property<ModelAdapter>::add_property(L"equations", &equations::get, &equations::set);
1514 property<ModelAdapter>::add_property(L"uid", &uid::get, &uid::set);
1518 ModelAdapter::ModelAdapter() :
1519 BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(),
1520 m_diagramAdapter(nullptr)
1522 initialize_fields();
1524 ModelAdapter::ModelAdapter(const Controller& c, model::Block* adaptee, DiagramAdapter* diagramAdapter) :
1525 BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(c, adaptee),
1526 m_diagramAdapter(diagramAdapter)
1528 initialize_fields();
1531 ModelAdapter::~ModelAdapter()
1535 std::wstring ModelAdapter::getTypeStr()
1537 return getSharedTypeStr();
1540 std::wstring ModelAdapter::getShortTypeStr()
1542 return getSharedTypeStr();
1545 DiagramAdapter* ModelAdapter::getDiagram() const
1547 return m_diagramAdapter;
1550 void ModelAdapter::setDiagram(DiagramAdapter* diagramAdapter)
1552 // does not increment reference as this adapter does not own the DiagramAdapter
1553 m_diagramAdapter = diagramAdapter;
1556 } /* namespace view_scilab */
1557 } /* namespace org_scilab_modules_scicos */