Scicos: speedup model transformation
[scilab.git] / scilab / modules / scicos / src / cpp / view_scilab / ModelAdapter.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2014-2016 - Scilab Enterprises - Clement DAVID
4  * Copyright (C) 2017 - ESI Group - Clement DAVID
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17 #include <cwchar>
18 #include <cstring>
19
20 #include <string>
21 #include <vector>
22 #include <algorithm>
23 #include <sstream>
24
25 #include "bool.hxx"
26 #include "int.hxx"
27 #include "double.hxx"
28 #include "string.hxx"
29 #include "list.hxx"
30 #include "tlist.hxx"
31 #include "user.hxx"
32
33 #include "Controller.hxx"
34 #include "ModelAdapter.hxx"
35 #include "LinkAdapter.hxx"
36 #include "DiagramAdapter.hxx"
37
38 #include "view_scilab/Adapters.hxx"
39 #include "ports_management.hxx"
40 #include "utilities.hxx"
41 #include "controller_helpers.hxx"
42
43 #include "var2vec.hxx"
44 #include "vec2var.hxx"
45
46 extern "C" {
47 #include "sci_malloc.h"
48 #include "charEncoding.h"
49 #include "localization.h"
50 }
51
52 namespace org_scilab_modules_scicos
53 {
54 namespace view_scilab
55 {
56 namespace
57 {
58
59 const std::wstring modelica (L"modelica");
60 const std::wstring model (L"model");
61 const std::wstring inputs (L"inputs");
62 const std::wstring outputs (L"outputs");
63 const std::wstring parameters (L"parameters");
64
65 types::InternalType* get_with_vec2var(const ModelAdapter& adaptor, const Controller& controller, object_properties_t p)
66 {
67     model::Block* adaptee = adaptor.getAdaptee();
68
69     std::vector<double> prop_content;
70     controller.getObjectProperty(adaptee, p, prop_content);
71
72     // Corner-case, the empty content is an empty double
73     if (prop_content.empty())
74     {
75         return types::Double::Empty();
76     }
77
78     // The returned value is a list
79     types::InternalType* res;
80     if (!vec2var(prop_content, res))
81     {
82         return nullptr;
83     }
84
85     return res;
86 }
87
88 bool set_with_var2vec(ModelAdapter& adaptor, types::InternalType* v, Controller& controller, object_properties_t p)
89 {
90     model::Block* adaptee = adaptor.getAdaptee();
91
92     // corner-case the empty content is an empty-double
93     if (v->getType() == types::InternalType::ScilabDouble)
94     {
95         types::Double* current = v->getAs<types::Double>();
96         if (current->getSize() != 0)
97         {
98             return false;
99         }
100
101         // prop_content should be empty
102         std::vector<double> prop_content;
103         controller.setObjectProperty(adaptee, p, prop_content);
104         return true;
105     }
106
107     std::vector<double> prop_content;
108     if (!var2vec(v, prop_content))
109     {
110         return false;
111     }
112
113     controller.setObjectProperty(adaptee, p, prop_content);
114     return true;
115 }
116
117 struct sim
118 {
119
120     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
121     {
122         model::Block* adaptee = adaptor.getAdaptee();
123
124         // First, extract the function Name
125         std::string name;
126         controller.getObjectProperty(adaptee, SIM_FUNCTION_NAME, name);
127         types::String* Name = new types::String(1, 1);
128         Name->set(0, name.data());
129
130         // Then the Api. If it is zero, then just return the Name. Otherwise, return a list containing both.
131         int api;
132         controller.getObjectProperty(adaptee, SIM_FUNCTION_API, api);
133
134         if (api == 0)
135         {
136             return Name;
137         }
138         else
139         {
140             types::Double* Api = new types::Double(static_cast<double>(api));
141             types::List* o = new types::List();
142             o->set(0, Name);
143             o->set(1, Api);
144             return o;
145         }
146     }
147
148     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
149     {
150         model::Block* adaptee = adaptor.getAdaptee();
151
152         if (v->getType() == types::InternalType::ScilabString)
153         {
154             types::String* current = v->getAs<types::String>();
155             if (current->getSize() != 1)
156             {
157                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong dimension for field %s.%s : %d-by-%d expected.\n"), "model", "sim", 1, 1);
158                 return false;
159             }
160
161             char* c_str = wide_string_to_UTF8(current->get(0));
162             std::string name(c_str);
163             FREE(c_str);
164
165             // If the input is a scalar string, then the functionApi is 0.
166             int api = 0;
167
168             controller.setObjectProperty(adaptee, SIM_FUNCTION_NAME, name);
169             controller.setObjectProperty(adaptee, SIM_FUNCTION_API, api);
170         }
171         else if (v->getType() == types::InternalType::ScilabList)
172         {
173             // If the input is a 2-sized list, then it must be string and positive integer.
174             types::List* current = v->getAs<types::List>();
175             if (current->getSize() != 2)
176             {
177                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong length for field %s.%s : %d expected.\n"), "model", "sim", 2);
178                 return false;
179             }
180             if (current->get(0)->getType() != types::InternalType::ScilabString || current->get(1)->getType() != types::InternalType::ScilabDouble)
181             {
182                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : String matrix expected.\n"), "model", "sim");
183                 return false;
184             }
185
186             types::String* Name = current->get(0)->getAs<types::String>();
187             if (Name->getSize() != 1)
188             {
189                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong dimension for field %s.%s : %d-by-%d expected.\n"), "model", "sim(1)", 1, 1);
190                 return false;
191             }
192             char* c_str = wide_string_to_UTF8(Name->get(0));
193             std::string name(c_str);
194             FREE(c_str);
195
196             types::Double* Api = current->get(1)->getAs<types::Double>();
197             if (Api->getSize() != 1)
198             {
199                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong dimension for field %s.%s : %d-by-%d expected.\n"), "model", "sim(2)", 1, 1);
200                 return false;
201             }
202             double api = Api->get(0);
203             if (floor(api) != api)
204             {
205                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong value for field %s.%s : Round number expected.\n"), "model", "sim(2)");
206                 return false;
207             }
208             int api_int = static_cast<int>(api);
209
210             controller.setObjectProperty(adaptee, SIM_FUNCTION_NAME, name);
211             controller.setObjectProperty(adaptee, SIM_FUNCTION_API, api_int);
212         }
213         else
214         {
215             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : String matrix expected.\n"), "model", "sim");
216             return false;
217         }
218         return true;
219     }
220 };
221
222 struct in
223 {
224
225     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
226     {
227         return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, INPUTS, controller);
228     }
229
230     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
231     {
232         return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, INPUTS, controller, v);
233     }
234 };
235
236 struct in2
237 {
238
239     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
240     {
241         return get_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, INPUTS, controller);
242     }
243
244     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
245     {
246         return set_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, INPUTS, controller, v);
247     }
248 };
249
250 struct intyp
251 {
252
253     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
254     {
255         return get_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, INPUTS, controller);
256     }
257
258     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
259     {
260         return set_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, INPUTS, controller, v);
261     }
262 };
263
264 struct out
265 {
266
267     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
268     {
269         return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, OUTPUTS, controller);
270     }
271
272     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
273     {
274         return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, OUTPUTS, controller, v);
275     }
276 };
277
278 struct out2
279 {
280
281     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
282     {
283         return get_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, OUTPUTS, controller);
284     }
285
286     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
287     {
288         return set_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, OUTPUTS, controller, v);
289     }
290 };
291
292 struct outtyp
293 {
294
295     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
296     {
297         return get_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, OUTPUTS, controller);
298     }
299
300     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
301     {
302         return set_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, OUTPUTS, controller, v);
303     }
304 };
305
306 struct evtin
307 {
308
309     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
310     {
311         return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_INPUTS, controller);
312     }
313
314     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
315     {
316         return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_INPUTS, controller, v);
317     }
318 };
319
320 struct evtout
321 {
322
323     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
324     {
325         return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_OUTPUTS, controller);
326     }
327
328     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
329     {
330         return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_OUTPUTS, controller, v);
331     }
332 };
333
334 struct state
335 {
336
337     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
338     {
339         model::Block* adaptee = adaptor.getAdaptee();
340
341         std::vector<double> state;
342         controller.getObjectProperty(adaptee, STATE, state);
343
344         double* data;
345         types::Double* o = new types::Double((int)state.size(), 1, &data);
346
347 #ifdef _MSC_VER
348         std::copy(state.begin(), state.end(), stdext::checked_array_iterator<double*>(data, state.size()));
349 #else
350         std::copy(state.begin(), state.end(), data);
351 #endif
352         return o;
353     }
354
355     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
356     {
357
358         if (v->getType() != types::InternalType::ScilabDouble)
359         {
360             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : Real matrix expected.\n"), "model", "state");
361             return false;
362         }
363
364         types::Double* current = v->getAs<types::Double>();
365         // Only allow vectors and empty matrices
366         if (!current->isVector() && current->getSize() != 0)
367         {
368             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong size for field %s.%s : %d-by-%d expected.\n"), "model", "state");
369             return false;
370         }
371
372         model::Block* adaptee = adaptor.getAdaptee();
373
374         std::vector<double> state (current->getSize());
375         std::copy(current->getReal(), current->getReal() + current->getSize(), state.begin());
376
377         controller.setObjectProperty(adaptee, STATE, state);
378         return true;
379     }
380 };
381
382 struct dstate
383 {
384
385     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
386     {
387         model::Block* adaptee = adaptor.getAdaptee();
388
389         std::vector<double> dstate;
390         controller.getObjectProperty(adaptee, DSTATE, dstate);
391
392         double* data;
393         types::Double* o = new types::Double((int)dstate.size(), 1, &data);
394
395 #ifdef _MSC_VER
396         std::copy(dstate.begin(), dstate.end(), stdext::checked_array_iterator<double*>(data, dstate.size()));
397 #else
398         std::copy(dstate.begin(), dstate.end(), data);
399 #endif
400         return o;
401     }
402
403     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
404     {
405         model::Block* adaptee = adaptor.getAdaptee();
406
407         if (v->getType() == types::InternalType::ScilabString)
408         {
409             /*
410              * This seems to be a corner-case used for code generation on ScicosLab
411              */
412
413             types::String* current = v->getAs<types::String>();
414             if (current->getSize() != 1)
415             {
416                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : Real matrix expected.\n"), "model", "dstate");
417                 return false;
418             }
419
420             std::vector<double> dstate;
421             controller.setObjectProperty(adaptee, DSTATE, dstate);
422             return true;
423         }
424
425         if (v->getType() != types::InternalType::ScilabDouble)
426         {
427             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : Real matrix expected.\n"), "model", "dstate");
428             return false;
429         }
430         types::Double* current = v->getAs<types::Double>();
431         // Only allow vectors and empty matrices
432         if (!current->isVector() && current->getSize() != 0)
433         {
434             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong dimension for field %s.%s : m-by-1 expected.\n"), "model", "dstate");
435             return false;
436         }
437
438         std::vector<double> dstate (current->getSize());
439         std::copy(current->getReal(), current->getReal() + current->getSize(), dstate.begin());
440
441         controller.setObjectProperty(adaptee, DSTATE, dstate);
442         return true;
443     }
444 };
445
446 void decodeDims(std::vector<int>::iterator& prop_it, std::vector<int>& dims)
447 {
448     const int iDims = *prop_it++;
449     dims.resize(iDims);
450
451     memcpy(&dims[0], &(*prop_it), iDims * sizeof(int));
452     prop_it += iDims;
453 }
454
455 void encodeDims(std::vector<int>& prop_content, types::GenericType* v)
456 {
457     const int iDims = v->getDims();
458     prop_content.push_back(iDims);
459
460     const int index = (int)prop_content.size();
461     prop_content.resize(index + iDims);
462
463     memcpy(&prop_content[index], v->getDimsArray(), iDims * sizeof(int));
464 }
465
466 /**
467  * Calculate the length increment depending on the ::value_type of the buffer and the type of the Scilab type
468  *
469  * @param V buffer type which must have a ::value_type field
470  * @param T Scilab type
471  * @param v the instance on the Scilab type
472  * @return the number of V elements used to store the data
473  */
474 template<typename V, typename T>
475 size_t required_length(const V& /*it*/, T* v)
476 {
477     const size_t sizeof_prop_value = sizeof(typename V::value_type);
478     if (sizeof(typename T::type) >= sizeof_prop_value)
479     {
480         return v->getSize() * sizeof(typename T::type) / sizeof_prop_value;
481     }
482     else
483     {
484         // increase the size to contain enough space, manage the size_t rounding issue
485         return v->getSize() * sizeof(typename T::type) + (sizeof_prop_value - 1) / sizeof_prop_value;
486     }
487 }
488
489 template <typename T>
490 T* decode(std::vector<int>::iterator& prop_it)
491 {
492     std::vector<int> dims;
493     decodeDims(prop_it, dims);
494
495     T* v = new T(static_cast<int>(dims.size()), &dims[0]);
496     memcpy(v->get(), &(*prop_it), v->getSize() * sizeof(typename T::type));
497
498     prop_it += required_length(prop_it, v);
499     return v;
500 }
501
502 template <typename T>
503 bool encode(std::vector<int>& prop_content, T* v)
504 {
505     encodeDims(prop_content, v);
506
507     const int index = (int)prop_content.size();
508     const int len = (int)required_length(prop_content, v);
509     prop_content.resize(index + len);
510
511     // Using contiguity of the memory, we save the input into 'prop_content'
512     memcpy(&prop_content[index], v->get(), v->getSize() * sizeof(typename T::type));
513     return true;
514 }
515
516 template<>
517 types::Double* decode(std::vector<int>::iterator& prop_it)
518 {
519     std::vector<int> dims;
520     decodeDims(prop_it, dims);
521
522     bool isComplex = *prop_it++ != 0;
523
524     types::Double* v = new types::Double(static_cast<int>(dims.size()), &dims[0], isComplex);
525     memcpy(v->getReal(), &(*prop_it), v->getSize() * sizeof(double));
526
527     if (isComplex)
528     {
529         prop_it += required_length(prop_it, v);
530         memcpy(v->getImg(), &(*prop_it), v->getSize() * sizeof(double));
531     }
532
533     prop_it += required_length(prop_it, v);
534     return v;
535 }
536
537 bool encode(std::vector<int>& prop_content, types::Double* v)
538 {
539     encodeDims(prop_content, v);
540
541     // Flag for complex
542     prop_content.push_back(v->isComplex());
543
544     const int index = (int)prop_content.size();
545     const int len = (int)required_length(prop_content, v);
546     prop_content.resize(index + len);
547
548     // Using contiguity of the memory, we save the input into 'prop_content'
549     memcpy(&prop_content[index], v->get(), v->getSize() * sizeof(double));
550
551     if (v->isComplex())
552     {
553         prop_content.resize(index + 2 * len);
554         // Using contiguity of the memory, we save the input into 'prop_content'
555         memcpy(&prop_content[index + len], v->getImg(), v->getSize() * sizeof(double));
556     }
557
558     return true;
559 }
560
561 template<>
562 types::String* decode(std::vector<int>::iterator& prop_it)
563 {
564     std::vector<int> dims;
565     decodeDims(prop_it, dims);
566
567     types::String* v = new types::String(static_cast<int>(dims.size()), &dims[0]);
568     // retrieving the first value iterator
569     std::vector<int>::iterator strData = prop_it + v->getSize();
570
571     v->set(0, (char*) & (*strData));
572     strData += static_cast<size_t>(*prop_it++);
573     for (int i = 1; i < v->getSize(); i++)
574     {
575         v->set(i, (char*) & (*strData));
576
577         // increment the value iterator by the number of element
578         const size_t numberOfElem = static_cast<size_t>(*prop_it) - static_cast<size_t>(*(prop_it - 1)) ;
579         prop_it++;
580         strData += numberOfElem;
581     }
582
583     prop_it = strData;
584     return v;
585 }
586
587 bool encode(std::vector<int>& prop_content, types::String* v)
588 {
589     encodeDims(prop_content, v);
590
591     const int index = (int)prop_content.size();
592
593     std::vector<char*> utf8;
594     utf8.reserve(v->getSize());
595
596     std::vector<size_t> str_len;
597     str_len.reserve(v->getSize());
598
599     size_t offset = 0;
600     for (int i = 0; i < v->getSize(); i++)
601     {
602         char* str = wide_string_to_UTF8(v->get(i));
603         utf8.push_back(str);
604
605         // adding the '\0' byte to the len
606         const size_t len = strlen(str) + 1;
607         str_len.push_back(len);
608
609         offset += (len * sizeof(char) + sizeof(int) - 1) / sizeof(int);
610         prop_content.push_back((int)offset);
611     }
612
613     // reserve space for the string offsets and contents
614     prop_content.resize(index + v->getSize() + offset);
615
616     size_t len = str_len[0];
617     memcpy(&prop_content[index + v->getSize()], &(*utf8[0]), len * sizeof(char));
618     for (int i = 1; i < v->getSize(); i++)
619     {
620         len = str_len[i];
621         memcpy(&prop_content[index + v->getSize() + prop_content[index + i - 1]], &(*utf8[i]), len * sizeof(char));
622     }
623
624     // free all the string, after being copied
625     for (std::vector<char*>::iterator it = utf8.begin(); it != utf8.end(); it++)
626     {
627         FREE(*it);
628     }
629
630     return true;
631 }
632
633
634 template<>
635 types::List* decode(std::vector<int>::iterator& prop_it)
636 {
637     int length = *prop_it++;
638
639     types::List* list = new types::List();
640     for (int i = 0; i < length; i++)
641     {
642         switch (*prop_it++)
643         {
644             case types::InternalType::ScilabDouble:
645                 list->set(i, decode<types::Double>(prop_it));
646                 break;
647             case types::InternalType::ScilabInt8:
648                 list->set(i, decode<types::Int8>(prop_it));
649                 break;
650             case types::InternalType::ScilabUInt8:
651                 list->set(i, decode<types::UInt8>(prop_it));
652                 break;
653             case types::InternalType::ScilabInt16:
654                 list->set(i, decode<types::Int16>(prop_it));
655                 break;
656             case types::InternalType::ScilabUInt16:
657                 list->set(i, decode<types::UInt16>(prop_it));
658                 break;
659             case types::InternalType::ScilabInt32:
660                 list->set(i, decode<types::Int32>(prop_it));
661                 break;
662             case types::InternalType::ScilabUInt32:
663                 list->set(i, decode<types::UInt32>(prop_it));
664                 break;
665             case types::InternalType::ScilabInt64:
666                 list->set(i, decode<types::Int64>(prop_it));
667                 break;
668             case types::InternalType::ScilabUInt64:
669                 list->set(i, decode<types::UInt64>(prop_it));
670                 break;
671             case types::InternalType::ScilabString:
672                 list->set(i, decode<types::String>(prop_it));
673                 break;
674             case types::InternalType::ScilabBool:
675                 list->set(i, decode<types::Bool>(prop_it));
676                 break;
677             case types::InternalType::ScilabList:
678                 list->set(i, decode<types::List>(prop_it));
679                 break;
680         }
681     }
682     return list;
683 }
684
685 bool encode(std::vector<int>& prop_content, types::List* list)
686 {
687     // Save the number of list elements in the first element
688     prop_content.push_back(list->getSize());
689
690     for (int i = 0; i < list->getSize(); ++i)
691     {
692         // Insert a new element and save its variable type
693         prop_content.push_back(list->get(i)->getType());
694
695         switch (list->get(i)->getType())
696         {
697             case types::InternalType::ScilabDouble:
698                 encode(prop_content, list->get(i)->getAs<types::Double>());
699                 break;
700             case types::InternalType::ScilabInt8:
701                 encode(prop_content, list->get(i)->getAs<types::Int8>());
702                 break;
703             case types::InternalType::ScilabUInt8:
704                 encode(prop_content, list->get(i)->getAs<types::UInt8>());
705                 break;
706             case types::InternalType::ScilabInt16:
707                 encode(prop_content, list->get(i)->getAs<types::Int16>());
708                 break;
709             case types::InternalType::ScilabUInt16:
710                 encode(prop_content, list->get(i)->getAs<types::UInt16>());
711                 break;
712             case types::InternalType::ScilabInt32:
713                 encode(prop_content, list->get(i)->getAs<types::Int32>());
714                 break;
715             case types::InternalType::ScilabUInt32:
716                 encode(prop_content, list->get(i)->getAs<types::UInt32>());
717                 break;
718             case types::InternalType::ScilabInt64:
719                 encode(prop_content, list->get(i)->getAs<types::Int64>());
720                 break;
721             case types::InternalType::ScilabUInt64:
722                 encode(prop_content, list->get(i)->getAs<types::UInt64>());
723                 break;
724             case types::InternalType::ScilabString:
725                 encode(prop_content, list->get(i)->getAs<types::String>());
726                 break;
727             case types::InternalType::ScilabBool:
728                 encode(prop_content, list->get(i)->getAs<types::Bool>());
729                 break;
730             default:
731                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : List expected.\n"), "model", "props");
732                 return false;
733         }
734     }
735
736     return true;
737 }
738
739 struct odstate
740 {
741
742     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
743     {
744         return get_with_vec2var(adaptor, controller, ODSTATE);
745     }
746
747     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
748     {
749         return set_with_var2vec(adaptor, v, controller, ODSTATE);
750     }
751 };
752
753 /*
754  * When setting a diagram in 'rpar', the Superblock's ports must be consistent with the "port blocks" inside it.
755  * By "port blocks", we mean IN_f, OUT_f, CLKIN_f, CLKOUT_f, CLKINV_f, CLKOUTV_f, INIMPL_f and OUTIMPL_f.
756  */
757 bool setInnerBlocksRefs(ModelAdapter& adaptor, const std::vector<ScicosID>& children, Controller& controller)
758 {
759     const std::string input ("input");
760     const std::string output ("output");
761     const std::string inimpl ("inimpl");
762     const std::string outimpl ("outimpl");
763
764     model::Block* adaptee = adaptor.getAdaptee();
765
766     for (std::vector<ScicosID>::const_iterator it = children.begin(); it != children.end(); ++it)
767     {
768         if (*it == ScicosID())
769         {
770             continue; // Rule out mlists (Deleted or Annotations)
771         }
772
773         model::BaseObject* child = controller.getBaseObject(*it);
774         if (child->kind() == BLOCK) // Rule out Annotations and Links
775         {
776             std::string name;
777             controller.getObjectProperty(child, SIM_FUNCTION_NAME, name);
778
779             // Find the "port blocks"
780             if (name == input || name == inimpl || name == output || name == outimpl)
781             {
782                 std::vector<int> ipar;
783                 controller.getObjectProperty(child, IPAR, ipar);
784                 if (ipar.size() != 1)
785                 {
786                     std::string uid;
787                     controller.getObjectProperty(child, UID, uid);
788                     get_or_allocate_logger()->log(LOG_ERROR, _("Wrong value for field %s.%s : %s (%s) has an invalid port number.\n"), "model", "rpar", name.c_str(), uid.c_str());
789                     return false;
790                 }
791                 int portIndex = ipar[0];
792
793                 // "name" is not enough to tell the event and data ports apart, so check the block's port.
794                 object_properties_t kind;
795                 std::vector<ScicosID> innerPort;
796                 if (name == input || name == inimpl)
797                 {
798                     controller.getObjectProperty(child, OUTPUTS, innerPort);
799                     if (!innerPort.empty())
800                     {
801                         kind = INPUTS;
802                     }
803                     else
804                     {
805                         kind = EVENT_INPUTS;
806                     }
807                 }
808                 else
809                 {
810                     controller.getObjectProperty(child, INPUTS, innerPort);
811                     if (!innerPort.empty())
812                     {
813                         kind = OUTPUTS;
814                     }
815                     else
816                     {
817                         kind = EVENT_OUTPUTS;
818                     }
819                 }
820
821                 std::vector<ScicosID> superPorts;
822                 controller.getObjectProperty(adaptee, kind, superPorts);
823                 if (static_cast<int>(superPorts.size()) < portIndex)
824                 {
825                     if (!superPorts.empty())
826                     {
827                         // Arbitrarily take the highest possible value in case the user enters a wrong number
828                         portIndex = (int)superPorts.size();
829                     }
830                     else
831                     {
832                         std::string uid;
833                         controller.getObjectProperty(child, UID, uid);
834                         get_or_allocate_logger()->log(LOG_ERROR, _("Wrong value for field %s.%s : %s (%s) has an invalid port number.\n"), "model", "rpar", name.c_str(), uid.c_str());
835                         return false;
836                     }
837                 }
838
839                 ScicosID port = superPorts[portIndex - 1];
840
841                 // Check consistency of the implicitness between the inner and outer ports
842                 bool isImplicit;
843                 controller.getObjectProperty(port, PORT, IMPLICIT, isImplicit);
844                 if (name == input || name == output)
845                 {
846                     if (isImplicit)
847                     {
848                         std::string uid;
849                         controller.getObjectProperty(child, UID, uid);
850                         get_or_allocate_logger()->log(LOG_ERROR, _("Wrong value for field %s.%s : %s (%s) has an invalid implicit port.\n"), "model", "rpar", name.c_str(), uid.c_str());
851                         return false;
852                     }
853                 }
854                 else
855                 {
856                     if (!isImplicit)
857                     {
858                         std::string uid;
859                         controller.getObjectProperty(child, UID, uid);
860                         get_or_allocate_logger()->log(LOG_ERROR, _("Wrong value for field %s.%s : %s (%s) has an invalid explicit port.\n"), "model", "rpar", name.c_str(), uid.c_str());
861                         return false;
862                     }
863                 }
864
865                 controller.setObjectProperty(child, PORT_REFERENCE, port);
866             }
867         }
868     }
869     return true;
870 }
871
872 struct rpar
873 {
874
875     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
876     {
877         model::Block* adaptee = adaptor.getAdaptee();
878
879         std::vector<ScicosID> diagramChildren;
880         controller.getObjectProperty(adaptee, CHILDREN, diagramChildren);
881
882         if (diagramChildren.empty())
883         {
884             std::vector<double> rpar;
885             controller.getObjectProperty(adaptee, RPAR, rpar);
886
887             double *data;
888             types::Double* o = new types::Double((int)rpar.size(), 1, &data);
889 #ifdef _MSC_VER
890             std::copy(rpar.begin(), rpar.end(), stdext::checked_array_iterator<double*>(data, rpar.size()));
891 #else
892             std::copy(rpar.begin(), rpar.end(), data);
893 #endif
894             return o;
895         }
896         else // SuperBlock, return the contained diagram (allocating it on demand)
897         {
898             DiagramAdapter* d = new DiagramAdapter(controller, controller.referenceBaseObject(adaptee));
899             return d;
900         }
901     }
902
903     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
904     {
905         model::Block* adaptee = adaptor.getAdaptee();
906
907         if (v->getType() == types::InternalType::ScilabDouble)
908         {
909             types::Double* current = v->getAs<types::Double>();
910
911             std::vector<double> rpar (current->getSize());
912             for (int i = 0; i < current->getSize(); ++i)
913             {
914                 rpar[i] = current->get(i);
915             }
916
917             controller.setObjectProperty(adaptee, RPAR, rpar);
918             return true;
919         }
920         else if (v->getType() == types::InternalType::ScilabString)
921         {
922             // Allow Text blocks to define strings in rpar
923             return true;
924         }
925         else if (v->getType() == types::InternalType::ScilabUserType)
926         {
927             // Make sure the input describes a Diagram
928             const Adapters::adapters_index_t adapter_index = Adapters::instance().lookup_by_typename(v->getShortTypeStr());
929             if (adapter_index != Adapters::DIAGRAM_ADAPTER)
930             {
931                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : Diagram expected.\n"), "model", "rpar");
932                 return false;
933             }
934             const DiagramAdapter* diagram = v->getAs<DiagramAdapter>();
935             DiagramAdapter* superblock = new DiagramAdapter(controller, controller.referenceBaseObject(adaptee));
936
937             // copy the values by name to preserve adaptors specific properties
938             superblock->copyProperties(*diagram, controller);
939
940             superblock->killMe();
941             return true;
942         }
943         else if (v->getType() == types::InternalType::ScilabMList)
944         {
945             DiagramAdapter* diagram = new DiagramAdapter(controller, controller.referenceBaseObject(adaptee));
946             if (!diagram->setAsTList(v, controller))
947             {
948                 diagram->killMe();
949                 return false;
950             }
951
952             diagram->killMe();
953             return true;
954         }
955         else
956         {
957             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : Real matrix expected.\n"), "model", "rpar");
958             return false;
959         }
960     }
961 };
962
963 double toDouble(const int a)
964 {
965     return static_cast<double>(a);
966 }
967
968 struct ipar
969 {
970
971     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
972     {
973         model::Block* adaptee = adaptor.getAdaptee();
974
975         std::vector<int> ipar;
976         controller.getObjectProperty(adaptee, IPAR, ipar);
977
978         double *data;
979         types::Double* o = new types::Double((int)ipar.size(), 1, &data);
980
981 #ifdef _MSC_VER
982         std::transform(ipar.begin(), ipar.end(), stdext::checked_array_iterator<double*>(data, ipar.size()), toDouble);
983 #else
984         std::transform(ipar.begin(), ipar.end(), data, toDouble);
985 #endif
986         return o;
987     }
988
989     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
990     {
991         model::Block* adaptee = adaptor.getAdaptee();
992
993         if (v->getType() == types::InternalType::ScilabList)
994         {
995             std::vector<int> ipar;
996             controller.setObjectProperty(adaptee, IPAR, ipar);
997             get_or_allocate_logger()->log(LOG_TRACE, _("Wrong type for field %s.%s : List clear previous value.\n"), "model", "ipar");
998             return true;
999         }
1000
1001         // FIXME: ScilabInts should be managed there
1002         if (v->getType() != types::InternalType::ScilabDouble)
1003         {
1004             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : Real matrix expected.\n"), "model", "ipar");
1005             return false;
1006         }
1007         types::Double* current = v->getAs<types::Double>();
1008         // Only allow vectors and empty matrices
1009         if (!current->isVector() && current->getSize() != 0)
1010         {
1011             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong dimension for field %s.%s : m-by-1 matrix expected.\n"), "model", "ipar");
1012             return false;
1013         }
1014
1015         std::vector<int> ipar (current->getSize());
1016         for (int i = 0; i < current->getSize(); ++i)
1017         {
1018             if (floor(current->get(i)) != current->get(i))
1019             {
1020                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong value for field %s.%s : Integer values expected.\n"), "model", "ipar");
1021                 return false;
1022             }
1023             ipar[i] = static_cast<int>(current->get(i));
1024         }
1025
1026         controller.setObjectProperty(adaptee, IPAR, ipar);
1027         return true;
1028     }
1029 };
1030
1031 struct opar
1032 {
1033
1034     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1035     {
1036         return get_with_vec2var(adaptor, controller, OPAR);
1037     }
1038
1039     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1040     {
1041         return set_with_var2vec(adaptor, v, controller, OPAR);
1042     }
1043 };
1044
1045 struct blocktype
1046 {
1047
1048     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1049     {
1050         model::Block* adaptee = adaptor.getAdaptee();
1051
1052         std::string type;
1053         controller.getObjectProperty(adaptee, SIM_BLOCKTYPE, type);
1054
1055         types::String* o = new types::String(type.c_str());
1056         return o;
1057     }
1058
1059     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1060     {
1061         model::Block* adaptee = adaptor.getAdaptee();
1062
1063         if (v->getType() != types::InternalType::ScilabString)
1064         {
1065             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : String expected.\n"), "model", "blocktype");
1066             return false;
1067         }
1068
1069         types::String* current = v->getAs<types::String>();
1070         if (current->getSize() != 1)
1071         {
1072             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong dimension for field %s.%s : String expected.\n"), "model", "blocktype");
1073             return false;
1074         }
1075
1076         char* c_str = wide_string_to_UTF8(current->get(0));
1077         std::string type (c_str);
1078         FREE(c_str);
1079
1080         // the value validation is performed on the model
1081         return controller.setObjectProperty(adaptee, SIM_BLOCKTYPE, type) != FAIL;
1082     }
1083 };
1084
1085 struct firing
1086 {
1087
1088     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1089     {
1090         return get_ports_property<ModelAdapter, FIRING>(adaptor, EVENT_OUTPUTS, controller);
1091     }
1092
1093     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1094     {
1095         return set_ports_property<ModelAdapter, FIRING>(adaptor, EVENT_OUTPUTS, controller, v);
1096     }
1097 };
1098
1099 struct dep_ut
1100 {
1101
1102     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1103     {
1104         model::Block* adaptee = adaptor.getAdaptee();
1105
1106         std::vector<int> dep_ut;
1107         controller.getObjectProperty(adaptee, SIM_DEP_UT, dep_ut);
1108
1109         int* dep;
1110         types::Bool* o = new types::Bool(1, 2, &dep);
1111
1112         dep[0] = dep_ut[0];
1113         dep[1] = dep_ut[1];
1114
1115         return o;
1116     }
1117
1118     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1119     {
1120         model::Block* adaptee = adaptor.getAdaptee();
1121
1122         if (v->getType() != types::InternalType::ScilabBool)
1123         {
1124             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : Boolean matrix expected.\n"), "model", "dep_ut");
1125             return false;
1126         }
1127
1128         types::Bool* current = v->getAs<types::Bool>();
1129         if (current->getSize() != 2)
1130         {
1131             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong dimension for field %s.%s : %d-by-%d expected.\n"), "model", "dep_ut", 1, 2);
1132             return false;
1133         }
1134
1135         std::vector<int> dep_ut (2);
1136         dep_ut[0] = current->get(0);
1137         dep_ut[1] = current->get(1);
1138
1139         controller.setObjectProperty(adaptee, SIM_DEP_UT, dep_ut);
1140         return true;
1141     }
1142 };
1143
1144 // Valid C identifier definition
1145 // https://msdn.microsoft.com/en-us/library/e7f8y25b.aspx
1146 bool isValidCIdentifier(const std::string& label)
1147 {
1148     auto is_nondigit = [](char c)
1149     {
1150         return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || '_' == c;
1151     };
1152     auto is_digit = [](char c)
1153     {
1154         return ('0' <= c && c <= '9');
1155     };
1156
1157     // is a valid but empty string
1158     if (label.empty())
1159     {
1160         return true;
1161     }
1162     // the first character should be a non digit
1163     if (!is_nondigit(label[0]))
1164     {
1165         return false;
1166     }
1167     // others  should be either a digit or a non digit
1168     auto found = std::find_if_not(label.begin(), label.end(), [is_nondigit, is_digit](char c)
1169     {
1170         return is_nondigit(c) || is_digit(c);
1171     } );
1172     return found == label.end();
1173 }
1174
1175 struct label
1176 {
1177     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1178     {
1179         model::Block* adaptee = adaptor.getAdaptee();
1180
1181         ScicosID label;
1182         std::string description;
1183
1184         controller.getObjectProperty(adaptee, LABEL, label);
1185         if (label != ScicosID())
1186         {
1187             controller.getObjectProperty(label, ANNOTATION, DESCRIPTION, description);
1188         }
1189         else
1190         {
1191             controller.getObjectProperty(adaptee, DESCRIPTION, description);
1192         }
1193
1194         types::String* o = new types::String(1, 1);
1195
1196         // safety check ; the returned value should always be a valid C / modelica identifier
1197         if (isValidCIdentifier(description))
1198         {
1199             o->set(0, description.data());
1200         }
1201         else
1202         {
1203             o->set(0, "");
1204         }
1205         return o;
1206     }
1207
1208     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1209     {
1210         if (v->getType() != types::InternalType::ScilabString)
1211         {
1212             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : String expected.\n"), "model", "label");
1213             return false;
1214         }
1215
1216         types::String* current = v->getAs<types::String>();
1217         if (current->getSize() != 1)
1218         {
1219             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong dimension for field %s.%s : String expected.\n"), "model", "label");
1220             return false;
1221         }
1222
1223         model::Block* adaptee = adaptor.getAdaptee();
1224
1225         char* c_str = wide_string_to_UTF8(current->get(0));
1226         std::string description(c_str);
1227         FREE(c_str);
1228
1229         // TODO: validate a C/Scilab identifier only
1230         //        if (!isValidCIdentifier(label))
1231         //        {
1232         //            get_or_allocate_logger()->log(LOG_ERROR, _("Wrong value for field %s.%s : Valid C identifier expected.\n"), "model", "label");
1233         //            return false;
1234         //        }
1235
1236         controller.setObjectProperty(adaptee, DESCRIPTION, description);
1237         return true;
1238     }
1239 };
1240
1241 struct nzcross
1242 {
1243
1244     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1245     {
1246         model::Block* adaptee = adaptor.getAdaptee();
1247
1248         std::vector<int> nzcross;
1249         controller.getObjectProperty(adaptee, NZCROSS, nzcross);
1250
1251         double *data;
1252         types::Double* o = new types::Double((int)nzcross.size(), 1, &data);
1253
1254 #ifdef _MSC_VER
1255         std::transform(nzcross.begin(), nzcross.end(), stdext::checked_array_iterator<double*>(data, nzcross.size()), toDouble);
1256 #else
1257         std::transform(nzcross.begin(), nzcross.end(), data, toDouble);
1258 #endif
1259         return o;
1260     }
1261
1262     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1263     {
1264         model::Block* adaptee = adaptor.getAdaptee();
1265
1266         if (v->getType() != types::InternalType::ScilabDouble)
1267         {
1268             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : Real matrix expected.\n"), "model", "nzcross");
1269             return false;
1270         }
1271
1272         types::Double* current = v->getAs<types::Double>();
1273         // Only allow vectors and empty matrices
1274         if (!current->isVector() && current->getSize() != 0)
1275         {
1276             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong dimension for field %s.%s : m-by-1 expected.\n"), "model", "nzcross");
1277             return false;
1278         }
1279
1280         std::vector<int> nzcross (current->getSize());
1281         for (int i = 0; i < current->getSize(); ++i)
1282         {
1283             if (floor(current->get(i)) != current->get(i))
1284             {
1285                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong value for field %s.%s : Integer values expected.\n"), "model", "nzcross");
1286                 return false;
1287             }
1288             nzcross[i] = static_cast<int>(current->get(i));
1289         }
1290
1291         controller.setObjectProperty(adaptee, NZCROSS, nzcross);
1292         return true;
1293     }
1294 };
1295
1296 struct nmode
1297 {
1298
1299     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1300     {
1301         model::Block* adaptee = adaptor.getAdaptee();
1302
1303         std::vector<int> nmode;
1304         controller.getObjectProperty(adaptee, NMODE, nmode);
1305
1306         double *data;
1307         types::Double* o = new types::Double((int)nmode.size(), 1, &data);
1308
1309 #ifdef _MSC_VER
1310         std::transform(nmode.begin(), nmode.end(), stdext::checked_array_iterator<double*>(data, nmode.size()), toDouble);
1311 #else
1312         std::transform(nmode.begin(), nmode.end(), data, toDouble);
1313 #endif
1314         return o;
1315     }
1316
1317     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1318     {
1319         model::Block* adaptee = adaptor.getAdaptee();
1320
1321         if (v->getType() != types::InternalType::ScilabDouble)
1322         {
1323             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : Real matrix expected.\n"), "model", "nmode");
1324             return false;
1325         }
1326
1327         types::Double* current = v->getAs<types::Double>();
1328         // Only allow vectors and empty matrices
1329         if (!current->isVector() && current->getSize() != 0)
1330         {
1331             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong dimension for field %s.%s : m-by-1 expected.\n"), "model", "nzcross");
1332             return false;
1333         }
1334
1335         std::vector<int> nmode (current->getSize());
1336         for (int i = 0; i < current->getSize(); ++i)
1337         {
1338             if (floor(current->get(i)) != current->get(i))
1339             {
1340                 get_or_allocate_logger()->log(LOG_ERROR, _("Wrong value for field %s.%s : Integer values expected.\n"), "model", "nzcross");
1341                 return false;
1342             }
1343             nmode[i] = static_cast<int>(current->get(i));
1344         }
1345
1346         controller.setObjectProperty(adaptee, NMODE, nmode);
1347         return true;
1348     }
1349 };
1350
1351 struct equations
1352 {
1353
1354     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1355     {
1356         return get_with_vec2var(adaptor, controller, EQUATIONS);
1357     }
1358
1359     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1360     {
1361         return set_with_var2vec(adaptor, v, controller, EQUATIONS);
1362     }
1363 };
1364
1365 struct uid
1366 {
1367
1368     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1369     {
1370         model::Block* adaptee = adaptor.getAdaptee();
1371
1372         std::string uid;
1373         controller.getObjectProperty(adaptee, UID, uid);
1374
1375         types::String* o = new types::String(1, 1);
1376         o->set(0, uid.data());
1377
1378         return o;
1379     }
1380
1381     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1382     {
1383         if (v->getType() != types::InternalType::ScilabString)
1384         {
1385             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong type for field %s.%s : String expected.\n"), "model", "uid");
1386             return false;
1387         }
1388
1389         types::String* current = v->getAs<types::String>();
1390         if (current->getSize() != 1)
1391         {
1392             get_or_allocate_logger()->log(LOG_ERROR, _("Wrong dimension for field %s.%s : String expected.\n"), "model", "uid");
1393             return false;
1394         }
1395
1396         model::Block* adaptee = adaptor.getAdaptee();
1397
1398         char* c_str = wide_string_to_UTF8(current->get(0));
1399         std::string uid(c_str);
1400         FREE(c_str);
1401
1402         controller.setObjectProperty(adaptee, UID, uid);
1403         return true;
1404     }
1405 };
1406
1407 } /* namespace */
1408
1409 template<> property<ModelAdapter>::props_t property<ModelAdapter>::fields = property<ModelAdapter>::props_t();
1410 static void initialize_fields()
1411 {
1412     if (property<ModelAdapter>::properties_have_not_been_set())
1413     {
1414         property<ModelAdapter>::reserve_properties(23);
1415         property<ModelAdapter>::add_property(L"sim", &sim::get, &sim::set);
1416         property<ModelAdapter>::add_property(L"in", &in::get, &in::set);
1417         property<ModelAdapter>::add_property(L"in2", &in2::get, &in2::set);
1418         property<ModelAdapter>::add_property(L"intyp", &intyp::get, &intyp::set);
1419         property<ModelAdapter>::add_property(L"out", &out::get, &out::set);
1420         property<ModelAdapter>::add_property(L"out2", &out2::get, &out2::set);
1421         property<ModelAdapter>::add_property(L"outtyp", &outtyp::get, &outtyp::set);
1422         property<ModelAdapter>::add_property(L"evtin", &evtin::get, &evtin::set);
1423         property<ModelAdapter>::add_property(L"evtout", &evtout::get, &evtout::set);
1424         property<ModelAdapter>::add_property(L"state", &state::get, &state::set);
1425         property<ModelAdapter>::add_property(L"dstate", &dstate::get, &dstate::set);
1426         property<ModelAdapter>::add_property(L"odstate", &odstate::get, &odstate::set);
1427         property<ModelAdapter>::add_property(L"rpar", &rpar::get, &rpar::set);
1428         property<ModelAdapter>::add_property(L"ipar", &ipar::get, &ipar::set);
1429         property<ModelAdapter>::add_property(L"opar", &opar::get, &opar::set);
1430         property<ModelAdapter>::add_property(L"blocktype", &blocktype::get, &blocktype::set);
1431         property<ModelAdapter>::add_property(L"firing", &firing::get, &firing::set);
1432         property<ModelAdapter>::add_property(L"dep_ut", &dep_ut::get, &dep_ut::set);
1433         property<ModelAdapter>::add_property(L"label", &label::get, &label::set);
1434         property<ModelAdapter>::add_property(L"nzcross", &nzcross::get, &nzcross::set);
1435         property<ModelAdapter>::add_property(L"nmode", &nmode::get, &nmode::set);
1436         property<ModelAdapter>::add_property(L"equations", &equations::get, &equations::set);
1437         property<ModelAdapter>::add_property(L"uid", &uid::get, &uid::set);
1438         property<ModelAdapter>::shrink_to_fit();
1439     }
1440 }
1441
1442 ModelAdapter::ModelAdapter() :
1443     BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>()
1444 {
1445     initialize_fields();
1446 }
1447
1448 ModelAdapter::ModelAdapter(const Controller& c, model::Block* adaptee) :
1449     BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(c, adaptee)
1450 {
1451     initialize_fields();
1452 }
1453
1454 ModelAdapter::~ModelAdapter()
1455 {
1456 }
1457
1458 std::wstring ModelAdapter::getTypeStr() const
1459 {
1460     return getSharedTypeStr();
1461 }
1462
1463 std::wstring ModelAdapter::getShortTypeStr() const
1464 {
1465     return getSharedTypeStr();
1466 }
1467
1468 } /* namespace view_scilab */
1469 } /* namespace org_scilab_modules_scicos */