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
30 #include "Controller.hxx"
31 #include "Adapters.hxx"
32 #include "ModelAdapter.hxx"
33 #include "DiagramAdapter.hxx"
34 #include "ports_management.hxx"
35 #include "utilities.hxx"
38 #include "sci_malloc.h"
39 #include "charEncoding.h"
42 namespace org_scilab_modules_scicos
49 const std::string input ("input");
50 const std::string output ("output");
51 const std::string inimpl ("inimpl");
52 const std::string outimpl ("outimpl");
54 const std::wstring modelica (L"modelica");
55 const std::wstring model (L"model");
56 const std::wstring inputs (L"inputs");
57 const std::wstring outputs (L"outputs");
58 const std::wstring parameters (L"parameters");
63 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
65 ScicosID adaptee = adaptor.getAdaptee()->id();
67 // First, extract the function Name
69 controller.getObjectProperty(adaptee, BLOCK, SIM_FUNCTION_NAME, name);
70 types::String* Name = new types::String(1, 1);
71 Name->set(0, name.data());
73 // Then the Api. If it is zero, then just return the Name. Otherwise, return a list containing both.
75 controller.getObjectProperty(adaptee, BLOCK, SIM_FUNCTION_API, api);
83 types::Double* Api = new types::Double(static_cast<double>(api));
84 types::List* o = new types::List();
91 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
93 ScicosID adaptee = adaptor.getAdaptee()->id();
95 if (v->getType() == types::InternalType::ScilabString)
97 types::String* current = v->getAs<types::String>();
98 if (current->getSize() != 1)
103 char* c_str = wide_string_to_UTF8(current->get(0));
104 std::string name(c_str);
107 // If the input is a scalar string, then the functionApi is 0.
110 controller.setObjectProperty(adaptee, BLOCK, SIM_FUNCTION_NAME, name);
111 controller.setObjectProperty(adaptee, BLOCK, SIM_FUNCTION_API, api);
113 else if (v->getType() == types::InternalType::ScilabList)
115 // If the input is a 2-sized list, then it must be string and positive integer.
116 types::List* current = v->getAs<types::List>();
117 if (current->getSize() != 2)
121 if (current->get(0)->getType() != types::InternalType::ScilabString || current->get(1)->getType() != types::InternalType::ScilabDouble)
126 types::String* Name = current->get(0)->getAs<types::String>();
127 if (Name->getSize() != 1)
131 char* c_str = wide_string_to_UTF8(Name->get(0));
132 std::string name(c_str);
135 types::Double* Api = current->get(1)->getAs<types::Double>();
136 if (Api->getSize() != 1)
140 double api = Api->get(0);
141 if (floor(api) != api)
145 int api_int = static_cast<int>(api);
147 controller.setObjectProperty(adaptee, BLOCK, SIM_FUNCTION_NAME, name);
148 controller.setObjectProperty(adaptee, BLOCK, SIM_FUNCTION_API, api_int);
161 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
163 return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, INPUTS, controller);
166 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
168 return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, INPUTS, controller, v);
175 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
177 return get_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, INPUTS, controller);
180 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
182 return set_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, INPUTS, controller, v);
189 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
191 return get_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, INPUTS, controller);
194 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
196 return set_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, INPUTS, controller, v);
203 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
205 return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, OUTPUTS, controller);
208 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
210 return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, OUTPUTS, controller, v);
217 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
219 return get_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, OUTPUTS, controller);
222 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
224 return set_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, OUTPUTS, controller, v);
231 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
233 return get_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, OUTPUTS, controller);
236 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
238 return set_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, OUTPUTS, controller, v);
245 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
247 return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_INPUTS, controller);
250 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
252 return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_INPUTS, controller, v);
259 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
261 return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_OUTPUTS, controller);
264 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
266 return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_OUTPUTS, controller, v);
273 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
275 ScicosID adaptee = adaptor.getAdaptee()->id();
277 std::vector<double> state;
278 controller.getObjectProperty(adaptee, BLOCK, STATE, state);
281 types::Double* o = new types::Double((int)state.size(), 1, &data);
284 std::copy(state.begin(), state.end(), stdext::checked_array_iterator<double*>(data, state.size()));
286 std::copy(state.begin(), state.end(), data);
291 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
294 if (v->getType() != types::InternalType::ScilabDouble)
299 types::Double* current = v->getAs<types::Double>();
300 if (current->getCols() != 0 && current->getCols() != 1)
305 ScicosID adaptee = adaptor.getAdaptee()->id();
307 std::vector<double> state (current->getSize());
308 std::copy(current->getReal(), current->getReal() + current->getSize(), state.begin());
310 controller.setObjectProperty(adaptee, BLOCK, STATE, state);
318 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
320 ScicosID adaptee = adaptor.getAdaptee()->id();
322 std::vector<double> dstate;
323 controller.getObjectProperty(adaptee, BLOCK, DSTATE, dstate);
326 types::Double* o = new types::Double((int)dstate.size(), 1, &data);
329 std::copy(dstate.begin(), dstate.end(), stdext::checked_array_iterator<double*>(data, dstate.size()));
331 std::copy(dstate.begin(), dstate.end(), data);
336 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
338 ScicosID adaptee = adaptor.getAdaptee()->id();
340 if (v->getType() == types::InternalType::ScilabString)
342 types::String* current = v->getAs<types::String>();
343 if (current->getSize() != 1)
348 std::vector<double> dstate;
349 controller.setObjectProperty(adaptee, BLOCK, DSTATE, dstate);
353 if (v->getType() != types::InternalType::ScilabDouble)
357 types::Double* current = v->getAs<types::Double>();
358 if (current->getCols() != 0 && current->getCols() != 1)
363 std::vector<double> dstate (current->getSize());
364 std::copy(current->getReal(), current->getReal() + current->getSize(), dstate.begin());
366 controller.setObjectProperty(adaptee, BLOCK, DSTATE, dstate);
371 void decodeDims(std::vector<int>::iterator& prop_it, std::vector<int>& dims)
373 const int iDims = *prop_it++;
376 memcpy(&dims[0], &(*prop_it), iDims * sizeof(int));
380 void encodeDims(std::vector<int>& prop_content, types::GenericType* v)
382 const int iDims = v->getDims();
383 prop_content.push_back(iDims);
385 const int index = prop_content.size();
386 prop_content.resize(index + iDims);
388 memcpy(&prop_content[index], v->getDimsArray(), iDims * sizeof(int));
392 * Calculate the length increment depending on the ::value_type of the buffer and the type of the Scilab type
394 * @param V buffer type which must have a ::value_type field
395 * @param T Scilab type
396 * @param v the instance on the Scilab type
397 * @return the number of V elements used to store the data
399 template<typename V, typename T>
400 size_t required_length(const V& /*it*/, T* v)
402 const size_t sizeof_prop_value = sizeof(typename V::value_type);
403 if (sizeof(typename T::type) >= sizeof_prop_value)
405 return v->getSize() * sizeof(typename T::type) / sizeof_prop_value;
409 // increase the size to contain enough space, manage the size_t rounding issue
410 return v->getSize() * sizeof(typename T::type) + (sizeof_prop_value - 1) / sizeof_prop_value;
414 template <typename T>
415 T* decode(std::vector<int>::iterator& prop_it)
417 std::vector<int> dims;
418 decodeDims(prop_it, dims);
420 T* v = new T(static_cast<int>(dims.size()), &dims[0]);
421 memcpy(v->get(), &(*prop_it), v->getSize() * sizeof(typename T::type));
423 prop_it += required_length(prop_it, v);
427 template <typename T>
428 bool encode(std::vector<int>& prop_content, T* v)
430 encodeDims(prop_content, v);
432 const int index = prop_content.size();
433 const int len = required_length(prop_content, v);
434 prop_content.resize(index + len);
436 // Using contiguity of the memory, we save the input into 'prop_content'
437 memcpy(&prop_content[index], v->get(), v->getSize() * sizeof(typename T::type));
442 types::Double* decode(std::vector<int>::iterator& prop_it)
444 std::vector<int> dims;
445 decodeDims(prop_it, dims);
447 bool isComplex = *prop_it++;
449 types::Double* v = new types::Double(static_cast<int>(dims.size()), &dims[0], isComplex);
450 memcpy(v->getReal(), &(*prop_it), v->getSize() * sizeof(double));
454 prop_it += required_length(prop_it, v);
455 memcpy(v->getImg(), &(*prop_it), v->getSize() * sizeof(double));
458 prop_it += required_length(prop_it, v);
462 bool encode(std::vector<int>& prop_content, types::Double* v)
464 encodeDims(prop_content, v);
467 prop_content.push_back(v->isComplex());
469 const int index = prop_content.size();
470 const int len = required_length(prop_content, v);
471 prop_content.resize(index + len);
473 // Using contiguity of the memory, we save the input into 'prop_content'
474 memcpy(&prop_content[index], v->get(), v->getSize() * sizeof(double));
478 prop_content.resize(index + 2 * len);
479 // Using contiguity of the memory, we save the input into 'prop_content'
480 memcpy(&prop_content[index + len], v->getImg(), v->getSize() * sizeof(double));
487 types::String* decode(std::vector<int>::iterator& prop_it)
489 std::vector<int> dims;
490 decodeDims(prop_it, dims);
492 types::String* v = new types::String(static_cast<int>(dims.size()), &dims[0]);
493 // retrieving the first value iterator
494 std::vector<int>::iterator strData = prop_it + v->getSize();
496 v->set(0, (char*) & (*strData));
497 strData += static_cast<size_t>(*prop_it++);
498 for (int i = 1; i < v->getSize(); i++)
500 v->set(i, (char*) & (*strData));
502 // increment the value iterator by the number of element
503 const size_t numberOfElem = static_cast<size_t>(*prop_it) - static_cast<size_t>(*(prop_it - 1)) ;
505 strData += numberOfElem;
512 bool encode(std::vector<int>& prop_content, types::String* v)
514 encodeDims(prop_content, v);
516 const int index = prop_content.size();
518 std::vector<char*> utf8;
519 utf8.reserve(v->getSize());
521 std::vector<size_t> str_len;
522 str_len.reserve(v->getSize());
525 for (int i = 0; i < v->getSize(); i++)
527 char* str = wide_string_to_UTF8(v->get(i));
530 // adding the '\0' byte to the len
531 const size_t len = strlen(str) + 1;
532 str_len.push_back(len);
534 offset += (len * sizeof(char) + sizeof(int) - 1) / sizeof(int);
535 prop_content.push_back(offset);
538 // reserve space for the string offsets and contents
539 prop_content.resize(index + v->getSize() + offset);
541 size_t len = str_len[0];
542 memcpy(&prop_content[index + v->getSize()], &(*utf8[0]), len * sizeof(char));
543 for (int i = 1; i < v->getSize(); i++)
546 memcpy(&prop_content[index + v->getSize() + prop_content[index + i - 1]], &(*utf8[i]), len * sizeof(char));
549 // free all the string, after being copied
550 for (std::vector<char*>::iterator it = utf8.begin(); it != utf8.end(); it++)
560 types::List* decode(std::vector<int>::iterator& prop_it)
562 int length = *prop_it++;
564 types::List* list = new types::List();
565 for (int i = 0; i < length; i++)
569 case types::InternalType::ScilabDouble:
570 list->set(i, decode<types::Double>(prop_it));
572 case types::InternalType::ScilabInt8:
573 list->set(i, decode<types::Int8>(prop_it));
575 case types::InternalType::ScilabUInt8:
576 list->set(i, decode<types::UInt8>(prop_it));
578 case types::InternalType::ScilabInt16:
579 list->set(i, decode<types::Int16>(prop_it));
581 case types::InternalType::ScilabUInt16:
582 list->set(i, decode<types::UInt16>(prop_it));
584 case types::InternalType::ScilabInt32:
585 list->set(i, decode<types::Int32>(prop_it));
587 case types::InternalType::ScilabUInt32:
588 list->set(i, decode<types::UInt32>(prop_it));
590 case types::InternalType::ScilabInt64:
591 list->set(i, decode<types::Int64>(prop_it));
593 case types::InternalType::ScilabUInt64:
594 list->set(i, decode<types::UInt64>(prop_it));
596 case types::InternalType::ScilabString:
597 list->set(i, decode<types::String>(prop_it));
599 case types::InternalType::ScilabBool:
600 list->set(i, decode<types::Bool>(prop_it));
602 case types::InternalType::ScilabList:
603 list->set(i, decode<types::List>(prop_it));
610 bool encode(std::vector<int>& prop_content, types::List* list)
612 // Save the number of list elements in the first element
613 prop_content.push_back(list->getSize());
615 for (int i = 0; i < list->getSize(); ++i)
617 // Insert a new element and save its variable type
618 prop_content.push_back(list->get(i)->getType());
620 switch (list->get(i)->getType())
622 case types::InternalType::ScilabDouble:
623 encode(prop_content, list->get(i)->getAs<types::Double>());
625 case types::InternalType::ScilabInt8:
626 encode(prop_content, list->get(i)->getAs<types::Int8>());
628 case types::InternalType::ScilabUInt8:
629 encode(prop_content, list->get(i)->getAs<types::UInt8>());
631 case types::InternalType::ScilabInt16:
632 encode(prop_content, list->get(i)->getAs<types::Int16>());
634 case types::InternalType::ScilabUInt16:
635 encode(prop_content, list->get(i)->getAs<types::UInt16>());
637 case types::InternalType::ScilabInt32:
638 encode(prop_content, list->get(i)->getAs<types::Int32>());
640 case types::InternalType::ScilabUInt32:
641 encode(prop_content, list->get(i)->getAs<types::UInt32>());
643 case types::InternalType::ScilabInt64:
644 encode(prop_content, list->get(i)->getAs<types::Int64>());
646 case types::InternalType::ScilabUInt64:
647 encode(prop_content, list->get(i)->getAs<types::UInt64>());
649 case types::InternalType::ScilabString:
650 encode(prop_content, list->get(i)->getAs<types::String>());
652 case types::InternalType::ScilabBool:
653 encode(prop_content, list->get(i)->getAs<types::Bool>());
666 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
668 ScicosID adaptee = adaptor.getAdaptee()->id();
670 std::vector<int> prop_content;
671 controller.getObjectProperty(adaptee, BLOCK, ODSTATE, prop_content);
673 // corner-case, the empty content is an empty double
674 if (prop_content.empty())
676 return types::Double::Empty();
679 // the returned value is a list
680 std::vector<int>::iterator prop_it = prop_content.begin();
681 return decode<types::List>(prop_it);
684 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
686 ScicosID adaptee = adaptor.getAdaptee()->id();
687 std::vector<int> prop_content;
689 // corner-case the empty content is an empty-double
690 if (v->getType() == types::InternalType::ScilabDouble)
692 types::Double* current = v->getAs<types::Double>();
693 if (current->getSize() != 0)
698 // propr_content is empty
699 controller.setObjectProperty(adaptee, BLOCK, ODSTATE, prop_content);
703 if (v->getType() != types::InternalType::ScilabList)
708 types::List* list = v->getAs<types::List>();
709 if (!encode(prop_content, list))
714 controller.setObjectProperty(adaptee, BLOCK, ODSTATE, prop_content);
720 * When setting a diagram in 'rpar', the Superblock's ports must be consistent with the "port blocks" inside it.
721 * By "port blocks", we mean IN_f, OUT_f, CLKIN_f, CLKOUT_f, CLKINV_f, CLKOUTV_f, INIMPL_f and OUTIMPL_f.
723 bool setInnerBlocksRefs(ModelAdapter& adaptor, const std::vector<ScicosID>& children, Controller& controller)
725 ScicosID adaptee = adaptor.getAdaptee()->id();
727 for (std::vector<ScicosID>::const_iterator it = children.begin(); it != children.end(); ++it)
729 if (controller.getObject(*it)->kind() == BLOCK) // Rule out Annotations and Links
732 controller.getObjectProperty(*it, BLOCK, SIM_FUNCTION_NAME, name);
734 // Find the "port blocks"
735 if (name == input || name == inimpl || name == output || name == outimpl)
737 std::vector<int> ipar;
738 controller.getObjectProperty(*it, BLOCK, IPAR, ipar);
739 if (ipar.size() != 1)
743 int portIndex = ipar[0];
745 // "name" is not enough to tell the event and data ports apart, so check the block's port.
746 object_properties_t kind;
747 std::vector<ScicosID> innerPort;
748 if (name == input || name == inimpl)
750 controller.getObjectProperty(*it, BLOCK, OUTPUTS, innerPort);
751 if (!innerPort.empty())
762 controller.getObjectProperty(*it, BLOCK, INPUTS, innerPort);
763 if (!innerPort.empty())
769 kind = EVENT_OUTPUTS;
773 std::vector<ScicosID> superPorts;
774 controller.getObjectProperty(adaptee, BLOCK, kind, superPorts);
775 if (static_cast<int>(superPorts.size()) < portIndex)
780 ScicosID port = superPorts[portIndex - 1];
782 // Check consistency of the implicitness between the inner and outer ports
784 controller.getObjectProperty(port, PORT, IMPLICIT, isImplicit);
785 if (name == input || name == output)
800 controller.setObjectProperty(*it, BLOCK, PORT_REFERENCE, port);
803 // Regardless of the ports, use the loop to set each Block's 'parent_block' property
804 controller.setObjectProperty(*it, BLOCK, PARENT_BLOCK, adaptee);
813 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
815 ScicosID adaptee = adaptor.getAdaptee()->id();
817 std::vector<ScicosID> diagramChild;
818 controller.getObjectProperty(adaptee, BLOCK, CHILDREN, diagramChild);
820 if (diagramChild.empty())
822 std::vector<double> rpar;
823 controller.getObjectProperty(adaptee, BLOCK, RPAR, rpar);
826 types::Double* o = new types::Double((int)rpar.size(), 1, &data);
828 std::copy(rpar.begin(), rpar.end(), stdext::checked_array_iterator<double*>(data, rpar.size()));
830 std::copy(rpar.begin(), rpar.end(), data);
834 else // SuperBlock, return the contained diagram
836 std::shared_ptr<model::Diagram> super = std::static_pointer_cast<model::Diagram>(controller.getObject(diagramChild[0]));
837 DiagramAdapter* localAdaptor = new DiagramAdapter(super);
839 DiagramAdapter* diagram = adaptor.getDiagram();
840 localAdaptor->setListObjects(diagram->getListObjects());
841 localAdaptor->setFrom(diagram->getFrom());
842 localAdaptor->setTo(diagram->getTo());
847 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
849 ScicosID adaptee = adaptor.getAdaptee()->id();
851 if (v->getType() == types::InternalType::ScilabDouble)
853 types::Double* current = v->getAs<types::Double>();
855 std::vector<double> rpar (current->getSize());
856 for (int i = 0; i < current->getSize(); ++i)
858 rpar[i] = current->get(i);
861 controller.setObjectProperty(adaptee, BLOCK, RPAR, rpar);
864 else if (v->getType() == types::InternalType::ScilabString)
866 // Allow Text blocks to define strings in rpar
869 else if (v->getType() == types::InternalType::ScilabUserType)
871 // Make sure the input describes a Diagram
872 const Adapters::adapters_index_t adapter_index = Adapters::instance().lookup_by_typename(v->getShortTypeStr());
873 if (adapter_index != Adapters::DIAGRAM_ADAPTER)
878 // Translate 'v' to an DiagramAdapter, save it and update the Block's children list
879 DiagramAdapter* diagram = v->getAs<DiagramAdapter>();
881 adaptor.setDiagram(diagram);
883 // Save the child diagram's ID so it is deleted on 'clear'
884 std::vector<ScicosID> diagramChild (1, diagram->getAdaptee()->id());
885 controller.setObjectProperty(adaptee, BLOCK, CHILDREN, diagramChild);
887 // Link the Superblock ports to their inner "port blocks"
888 std::vector<ScicosID> diagramChildren;
889 controller.getObjectProperty(diagram->getAdaptee()->id(), DIAGRAM, CHILDREN, diagramChildren);
890 return setInnerBlocksRefs(adaptor, diagramChildren, controller);
899 double toDouble(const int a)
901 return static_cast<double>(a);
907 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
909 ScicosID adaptee = adaptor.getAdaptee()->id();
911 std::vector<int> ipar;
912 controller.getObjectProperty(adaptee, BLOCK, IPAR, ipar);
915 types::Double* o = new types::Double((int)ipar.size(), 1, &data);
918 std::transform(ipar.begin(), ipar.end(), stdext::checked_array_iterator<double*>(data, ipar.size()), toDouble);
920 std::transform(ipar.begin(), ipar.end(), data, toDouble);
925 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
927 ScicosID adaptee = adaptor.getAdaptee()->id();
929 if (v->getType() == types::InternalType::ScilabList)
931 std::vector<int> ipar;
932 controller.setObjectProperty(adaptee, BLOCK, IPAR, ipar);
936 if (v->getType() != types::InternalType::ScilabDouble)
941 types::Double* current = v->getAs<types::Double>();
942 if (current->getCols() != 0 && current->getCols() != 1)
947 std::vector<int> ipar (current->getSize());
948 for (int i = 0; i < current->getSize(); ++i)
950 if (floor(current->get(i)) != current->get(i))
954 ipar[i] = static_cast<int>(current->get(i));
957 controller.setObjectProperty(adaptee, BLOCK, IPAR, ipar);
965 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
967 ScicosID adaptee = adaptor.getAdaptee()->id();
969 std::vector<int> prop_content;
970 controller.getObjectProperty(adaptee, BLOCK, OPAR, prop_content);
972 // corner-case, the empty content is an empty double
973 if (prop_content.empty())
975 return types::Double::Empty();
978 // the returned value is a list
979 std::vector<int>::iterator prop_it = prop_content.begin();
980 return decode<types::List>(prop_it);
983 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
985 ScicosID adaptee = adaptor.getAdaptee()->id();
986 std::vector<int> prop_content;
988 // corner-case the empty content is an empty-double
989 if (v->getType() == types::InternalType::ScilabDouble)
991 types::Double* current = v->getAs<types::Double>();
992 if (current->getSize() != 0)
997 // prop_content should be empty
998 controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content);
1002 if (v->getType() != types::InternalType::ScilabList)
1007 types::List* list = v->getAs<types::List>();
1008 if (!encode(prop_content, list))
1013 controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content);
1021 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1023 ScicosID adaptee = adaptor.getAdaptee()->id();
1026 controller.getObjectProperty(adaptee, BLOCK, SIM_BLOCKTYPE, type);
1028 types::String* o = new types::String(type.c_str());
1032 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1034 ScicosID adaptee = adaptor.getAdaptee()->id();
1036 if (v->getType() != types::InternalType::ScilabString)
1041 types::String* current = v->getAs<types::String>();
1042 if (current->getSize() != 1)
1047 char* c_str = wide_string_to_UTF8(current->get(0));
1048 std::string type (c_str);
1051 // the value validation is performed on the model
1052 return controller.setObjectProperty(adaptee, BLOCK, SIM_BLOCKTYPE, type) != FAIL;
1059 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1061 return get_ports_property<ModelAdapter, FIRING>(adaptor, EVENT_OUTPUTS, controller);
1064 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1066 return set_ports_property<ModelAdapter, FIRING>(adaptor, EVENT_OUTPUTS, controller, v);
1073 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1075 ScicosID adaptee = adaptor.getAdaptee()->id();
1077 std::vector<int> dep_ut;
1078 controller.getObjectProperty(adaptee, BLOCK, SIM_DEP_UT, dep_ut);
1081 types::Bool* o = new types::Bool(1, 2, &dep);
1089 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1091 ScicosID adaptee = adaptor.getAdaptee()->id();
1093 if (v->getType() != types::InternalType::ScilabBool)
1098 types::Bool* current = v->getAs<types::Bool>();
1099 if (current->getRows() != 1 || current->getCols() != 2)
1104 std::vector<int> dep_ut (2);
1105 dep_ut[0] = current->get(0);
1106 dep_ut[1] = current->get(1);
1108 controller.setObjectProperty(adaptee, BLOCK, SIM_DEP_UT, dep_ut);
1116 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1118 ScicosID adaptee = adaptor.getAdaptee()->id();
1121 controller.getObjectProperty(adaptee, BLOCK, LABEL, label);
1123 types::String* o = new types::String(1, 1);
1124 o->set(0, label.data());
1129 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1131 if (v->getType() != types::InternalType::ScilabString)
1136 types::String* current = v->getAs<types::String>();
1137 if (current->getSize() != 1)
1142 ScicosID adaptee = adaptor.getAdaptee()->id();
1144 char* c_str = wide_string_to_UTF8(current->get(0));
1145 std::string label(c_str);
1148 controller.setObjectProperty(adaptee, BLOCK, LABEL, label);
1156 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1158 ScicosID adaptee = adaptor.getAdaptee()->id();
1160 std::vector<int> nzcross;
1161 controller.getObjectProperty(adaptee, BLOCK, NZCROSS, nzcross);
1164 types::Double* o = new types::Double((int)nzcross.size(), 1, &data);
1167 std::transform(nzcross.begin(), nzcross.end(), stdext::checked_array_iterator<double*>(data, nzcross.size()), toDouble);
1169 std::transform(nzcross.begin(), nzcross.end(), data, toDouble);
1174 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1176 ScicosID adaptee = adaptor.getAdaptee()->id();
1178 if (v->getType() != types::InternalType::ScilabDouble)
1183 types::Double* current = v->getAs<types::Double>();
1184 if (current->getCols() != 0 && current->getCols() != 1)
1189 std::vector<int> nzcross (current->getSize());
1190 for (int i = 0; i < current->getSize(); ++i)
1192 if (floor(current->get(i)) != current->get(i))
1196 nzcross[i] = static_cast<int>(current->get(i));
1199 controller.setObjectProperty(adaptee, BLOCK, NZCROSS, nzcross);
1207 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1209 ScicosID adaptee = adaptor.getAdaptee()->id();
1211 std::vector<int> nmode;
1212 controller.getObjectProperty(adaptee, BLOCK, NMODE, nmode);
1215 types::Double* o = new types::Double((int)nmode.size(), 1, &data);
1218 std::transform(nmode.begin(), nmode.end(), stdext::checked_array_iterator<double*>(data, nmode.size()), toDouble);
1220 std::transform(nmode.begin(), nmode.end(), data, toDouble);
1225 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1227 ScicosID adaptee = adaptor.getAdaptee()->id();
1229 if (v->getType() != types::InternalType::ScilabDouble)
1234 types::Double* current = v->getAs<types::Double>();
1235 if (current->getCols() != 0 && current->getCols() != 1)
1240 std::vector<int> nmode (current->getSize());
1241 for (int i = 0; i < current->getSize(); ++i)
1243 if (floor(current->get(i)) != current->get(i))
1247 nmode[i] = static_cast<int>(current->get(i));
1250 controller.setObjectProperty(adaptee, BLOCK, NMODE, nmode);
1258 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1260 ScicosID adaptee = adaptor.getAdaptee()->id();
1262 std::vector<std::string> equations;
1263 controller.getObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1265 if (equations.size() == 0)
1267 return new types::List();
1270 types::TList* o = new types::TList();
1272 // Header, starting with "modelica"
1273 types::String* header = new types::String(1, 5);
1274 header->set(0, modelica.c_str());
1275 header->set(1, model.c_str());
1276 header->set(2, inputs.c_str());
1277 header->set(3, outputs.c_str());
1278 header->set(4, parameters.c_str());
1282 if (equations[0].c_str() == std::string())
1284 o->set(1, types::Double::Empty());
1288 types::String* modelField = new types::String(1, 1);
1289 modelField->set(0, equations[0].c_str());
1290 o->set(1, modelField);
1294 std::istringstream inputsSizeStr (equations[1]);
1296 inputsSizeStr >> inputsSize;
1297 if (inputsSize == 0)
1299 types::Double* inputsField = types::Double::Empty();
1300 o->set(2, inputsField);
1304 types::String* inputsField = new types::String(inputsSize, 1);
1305 for (int i = 0; i < inputsSize; ++i)
1307 inputsField->set(i, equations[i + 2].c_str());
1309 o->set(2, inputsField);
1313 std::istringstream outputsSizeStr (equations[2 + inputsSize]);
1315 outputsSizeStr >> outputsSize;
1316 if (outputsSize == 0)
1318 types::Double* outputsField = types::Double::Empty();
1319 o->set(3, outputsField);
1323 types::String* outputsField = new types::String(outputsSize, 1);
1324 for (int i = 0; i < outputsSize; ++i)
1326 outputsField->set(i, equations[i + 3 + inputsSize].c_str());
1328 o->set(3, outputsField);
1332 types::List* parametersField = new types::List();
1334 // 'parameters' names
1335 std::istringstream parametersSizeStr (equations[3 + inputsSize + outputsSize]);
1337 parametersSizeStr >> parametersSize;
1338 if (parametersSize == 0)
1340 types::Double* parametersNames = types::Double::Empty();
1341 parametersField->set(0, parametersNames);
1345 types::String* parametersNames = new types::String(parametersSize, 1);
1346 for (int i = 0; i < parametersSize; ++i)
1348 parametersNames->set(i, equations[i + 4 + inputsSize + outputsSize].c_str());
1350 parametersField->set(0, parametersNames);
1353 // 'parameters' values
1354 types::List* parametersValues = new types::List();
1355 for (int i = 0; i < parametersSize; ++i)
1357 std::istringstream parametersValueStr (equations[i + 4 + inputsSize + outputsSize + parametersSize]);
1358 double parametersVal;
1359 parametersValueStr >> parametersVal;
1360 types::Double* parametersValue = new types::Double(parametersVal);
1361 parametersValues->set(i, parametersValue);
1363 parametersField->set(1, parametersValues);
1365 o->set(4, parametersField);
1370 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1372 ScicosID adaptee = adaptor.getAdaptee()->id();
1374 if (v->getType() == types::InternalType::ScilabList)
1376 types::List* current = v->getAs<types::List>();
1377 if (current->getSize() != 0)
1384 if (v->getType() != types::InternalType::ScilabTList)
1389 types::TList* current = v->getAs<types::TList>();
1392 types::String* header = current->getFieldNames();
1393 if (header->getSize() != 5)
1397 if (header->get(0) != modelica)
1401 if (header->get(1) != model)
1405 if (header->get(2) != inputs)
1409 if (header->get(3) != outputs)
1413 if (header->get(4) != parameters)
1418 char* c_str; // Temporary buffer used for conversions
1421 std::vector<std::string> equations;
1422 if (current->get(1)->getType() == types::InternalType::ScilabString)
1424 types::String* modelField = current->get(1)->getAs<types::String>();
1425 if (modelField->getSize() != 1)
1430 c_str = wide_string_to_UTF8(modelField->get(0));
1431 std::string modelFieldStored(c_str);
1433 equations.push_back(modelFieldStored);
1435 else if (current->get(1)->getType() == types::InternalType::ScilabDouble)
1437 types::Double* modelFieldDouble = current->get(1)->getAs<types::Double>();
1438 if (modelFieldDouble->getSize() != 0)
1443 // An empty matrix stores an empty string, which will later be translated back to an empty matrix
1444 equations.push_back(std::string());
1453 if (current->get(2)->getType() == types::InternalType::ScilabDouble)
1455 types::Double* inputsField = current->get(2)->getAs<types::Double>();
1456 if (inputsField->getSize() != 0)
1462 std::ostringstream strInputs;
1463 strInputs << inputsSize;
1464 std::string inputsSizeStr = strInputs.str();
1465 equations.push_back(inputsSizeStr); // When 'inputs'=[], just insert "0" in 'equations'
1469 if (current->get(2)->getType() != types::InternalType::ScilabString)
1474 types::String* inputsField = current->get(2)->getAs<types::String>();
1475 inputsSize = inputsField->getSize();
1476 equations.resize(equations.size() + 1 + inputsSize);
1477 std::ostringstream strInputs;
1478 strInputs << inputsSize;
1479 std::string inputsSizeStr = strInputs.str();
1480 equations[1] = inputsSizeStr; // Saving the size of the 'inputs' field'
1481 for (size_t i = 0; i < inputsSize; ++i)
1483 c_str = wide_string_to_UTF8(inputsField->get(static_cast<int>(i)));
1484 std::string inputsFieldStored(c_str);
1486 equations[i + 2] = inputsFieldStored;
1492 if (current->get(3)->getType() == types::InternalType::ScilabDouble)
1494 types::Double* outputsField = current->get(3)->getAs<types::Double>();
1495 if (outputsField->getSize() != 0)
1501 std::ostringstream strOutputs;
1502 strOutputs << outputsSize;
1503 std::string outputsSizeStr = strOutputs.str();
1504 equations.push_back(outputsSizeStr); // When 'outputs'=[], just insert "0" in 'equations'
1508 if (current->get(3)->getType() != types::InternalType::ScilabString)
1513 types::String* outputsField = current->get(3)->getAs<types::String>();
1514 outputsSize = outputsField->getSize();
1515 equations.resize(equations.size() + 1 + outputsSize);
1516 std::ostringstream strOutputs;
1517 strOutputs << outputsSize;
1518 std::string outputsSizeStr = strOutputs.str();
1519 equations[2 + inputsSize] = outputsSizeStr; // Saving the size of the 'outputs' field'
1520 for (size_t i = 0; i < outputsSize; ++i)
1522 c_str = wide_string_to_UTF8(outputsField->get(static_cast<int>(i)));
1523 std::string outputsFieldStored(c_str);
1525 equations[i + 3 + inputsSize] = outputsFieldStored;
1530 int parametersIndex = 4;
1531 if (current->get(parametersIndex)->getType() == types::InternalType::ScilabDouble)
1533 // For backward compatibility sake, allow the presence of an empty matrix here
1534 types::Double* emptyMatrix = current->get(parametersIndex)->getAs<types::Double>();
1535 if (emptyMatrix->getSize() != 0)
1543 if (current->get(parametersIndex)->getType() != types::InternalType::ScilabList)
1548 types::List* list = current->get(parametersIndex)->getAs<types::List>();
1549 if (list->getSize() < 1)
1554 // 'parameters' names
1555 size_t parametersSize;
1556 if (list->get(0)->getType() == types::InternalType::ScilabDouble)
1558 types::Double* parametersNames = list->get(0)->getAs<types::Double>();
1559 if (parametersNames->getSize() != 0)
1564 // When 'parameters(1)'=[], just insert "0" in 'equations', set in the model and return
1566 std::ostringstream strParameters;
1567 strParameters << parametersSize;
1568 std::string parametersSizeStr = strParameters.str();
1569 equations.push_back(parametersSizeStr);
1571 controller.setObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1576 if (list->get(0)->getType() != types::InternalType::ScilabString)
1581 types::String* parametersNames = list->get(0)->getAs<types::String>();
1582 parametersSize = parametersNames->getSize();
1583 equations.resize(equations.size() + 1 + parametersSize);
1584 std::ostringstream strParameters;
1585 strParameters << parametersSize;
1586 std::string parametersSizeStr = strParameters.str();
1587 equations[3 + inputsSize + outputsSize] = parametersSizeStr; // Saving the size of the 'parameters' field'
1588 for (size_t i = 0; i < parametersSize; ++i)
1590 c_str = wide_string_to_UTF8(parametersNames->get(static_cast<int>(i)));
1591 std::string parametersName(c_str);
1593 equations[i + 4 + inputsSize + outputsSize] = parametersName;
1597 // 'parameters' values
1598 if (list->get(1)->getType() == types::InternalType::ScilabDouble)
1600 types::Double* parameterVal = list->get(1)->getAs<types::Double>();
1601 if (parameterVal->getSize() != static_cast<int>(parametersSize))
1606 for (size_t i = 0; i < parametersSize; ++i)
1608 std::ostringstream strParameterVal;
1609 strParameterVal << parameterVal->get(static_cast<int>(i));
1610 std::string parameterValStr = strParameterVal.str();
1611 equations.push_back(parameterValStr);
1616 if (list->get(1)->getType() != types::InternalType::ScilabList)
1621 types::List* list2 = list->get(1)->getAs<types::List>();
1622 if (list2->getSize() != static_cast<int>(parametersSize))
1627 equations.resize(equations.size() + parametersSize);
1628 for (size_t i = 0; i < parametersSize; ++i)
1630 if (list2->get(static_cast<int>(i))->getType() != types::InternalType::ScilabDouble)
1635 types::Double* parametersVal = list2->get(static_cast<int>(i))->getAs<types::Double>();
1636 if (parametersVal->getSize() != 1)
1641 std::ostringstream strParametersVal;
1642 strParametersVal << parametersVal->get(0);
1643 std::string parametersValStr = strParametersVal.str();
1644 equations[i + 4 + inputsSize + outputsSize + parametersSize] = parametersValStr;
1648 controller.setObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1656 static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1658 ScicosID adaptee = adaptor.getAdaptee()->id();
1661 controller.getObjectProperty(adaptee, BLOCK, UID, uid);
1663 types::String* o = new types::String(1, 1);
1664 o->set(0, uid.data());
1669 static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1671 if (v->getType() != types::InternalType::ScilabString)
1676 types::String* current = v->getAs<types::String>();
1677 if (current->getSize() != 1)
1682 ScicosID adaptee = adaptor.getAdaptee()->id();
1684 char* c_str = wide_string_to_UTF8(current->get(0));
1685 std::string uid(c_str);
1688 controller.setObjectProperty(adaptee, BLOCK, UID, uid);
1695 template<> property<ModelAdapter>::props_t property<ModelAdapter>::fields = property<ModelAdapter>::props_t();
1697 ModelAdapter::ModelAdapter(std::shared_ptr<model::Block> adaptee) :
1698 BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(adaptee),
1699 diagramAdapter(nullptr)
1701 if (property<ModelAdapter>::properties_have_not_been_set())
1703 property<ModelAdapter>::fields.reserve(23);
1704 property<ModelAdapter>::add_property(L"sim", &sim::get, &sim::set);
1705 property<ModelAdapter>::add_property(L"in", &in::get, &in::set);
1706 property<ModelAdapter>::add_property(L"in2", &in2::get, &in2::set);
1707 property<ModelAdapter>::add_property(L"intyp", &intyp::get, &intyp::set);
1708 property<ModelAdapter>::add_property(L"out", &out::get, &out::set);
1709 property<ModelAdapter>::add_property(L"out2", &out2::get, &out2::set);
1710 property<ModelAdapter>::add_property(L"outtyp", &outtyp::get, &outtyp::set);
1711 property<ModelAdapter>::add_property(L"evtin", &evtin::get, &evtin::set);
1712 property<ModelAdapter>::add_property(L"evtout", &evtout::get, &evtout::set);
1713 property<ModelAdapter>::add_property(L"state", &state::get, &state::set);
1714 property<ModelAdapter>::add_property(L"dstate", &dstate::get, &dstate::set);
1715 property<ModelAdapter>::add_property(L"odstate", &odstate::get, &odstate::set);
1716 property<ModelAdapter>::add_property(L"rpar", &rpar::get, &rpar::set);
1717 property<ModelAdapter>::add_property(L"ipar", &ipar::get, &ipar::set);
1718 property<ModelAdapter>::add_property(L"opar", &opar::get, &opar::set);
1719 property<ModelAdapter>::add_property(L"blocktype", &blocktype::get, &blocktype::set);
1720 property<ModelAdapter>::add_property(L"firing", &firing::get, &firing::set);
1721 property<ModelAdapter>::add_property(L"dep_ut", &dep_ut::get, &dep_ut::set);
1722 property<ModelAdapter>::add_property(L"label", &label::get, &label::set);
1723 property<ModelAdapter>::add_property(L"nzcross", &nzcross::get, &nzcross::set);
1724 property<ModelAdapter>::add_property(L"nmode", &nmode::get, &nmode::set);
1725 property<ModelAdapter>::add_property(L"equations", &equations::get, &equations::set);
1726 property<ModelAdapter>::add_property(L"uid", &uid::get, &uid::set);
1730 ModelAdapter::ModelAdapter(const ModelAdapter& adapter) :
1731 BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(adapter),
1732 diagramAdapter(adapter.getDiagram())
1736 ModelAdapter::~ModelAdapter()
1738 if (diagramAdapter != nullptr)
1740 diagramAdapter->DecreaseRef();
1741 diagramAdapter->killMe();
1745 std::wstring ModelAdapter::getTypeStr()
1747 return getSharedTypeStr();
1750 std::wstring ModelAdapter::getShortTypeStr()
1752 return getSharedTypeStr();
1755 DiagramAdapter* ModelAdapter::getDiagram() const
1757 if (diagramAdapter != nullptr)
1759 diagramAdapter->IncreaseRef();
1761 return diagramAdapter;
1764 void ModelAdapter::setDiagram(DiagramAdapter* newDiagram)
1766 if (newDiagram != nullptr)
1768 // The old 'diagramAdapter' needs to be freed after setting it to 'v'
1769 DiagramAdapter* temp = diagramAdapter;
1771 newDiagram->IncreaseRef();
1772 diagramAdapter = newDiagram;
1774 if (temp != nullptr)
1776 temp->DecreaseRef();
1782 } /* namespace view_scilab */
1783 } /* namespace org_scilab_modules_scicos */