Xcos MVC: implement state / dstate / blocktype
[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-2014 - Scilab Enterprises - Clement DAVID
4  *
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-en.txt
10  *
11  */
12
13 #include <string>
14 #include <vector>
15 #include <algorithm>
16
17 #include "list.hxx"
18 #include "double.hxx"
19 #include "string.hxx"
20
21 #include "Controller.hxx"
22 #include "ModelAdapter.hxx"
23 #include "ports_management.hxx"
24
25 namespace org_scilab_modules_scicos
26 {
27 namespace view_scilab
28 {
29
30 struct sim
31 {
32
33     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
34     {
35         model::Block* adaptee = adaptor.getAdaptee();
36
37         // First, extact the function Name
38         std::string name;
39         controller.getObjectProperty(adaptee->id(), adaptee->kind(), SIM_FUNCTION_NAME, name);
40         types::String* Name = new types::String(1, 1);
41         Name->set(0, name.data());
42
43         // Then the Api. If it is zero, then just return the Name. Otherwise, return a list containing both.
44         int api;
45         controller.getObjectProperty(adaptee->id(), adaptee->kind(), SIM_FUNCTION_API, api);
46
47         if (api == 0)
48         {
49             return Name;
50         }
51         else
52         {
53             types::Double* Api = new types::Double(1, 1, static_cast<double>(api));
54             types::List* o = new types::List();
55             o->set(0, Name);
56             o->set(1, Api);
57             return o;
58         }
59     }
60
61     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
62     {
63         model::Block* adaptee = adaptor.getAdaptee();
64
65         if (v->getType() == types::InternalType::ScilabString)
66         {
67             types::String* current = v->getAs<types::String>();
68             if (current->getSize() != 1)
69             {
70                 return false;
71             }
72
73             char* c_str = wide_string_to_UTF8(current->get(0));
74             std::string name = std::string(c_str);
75             FREE(c_str);
76
77             // If the input is a scalar string, then the functionApi is 0.
78             int api = 0;
79
80             controller.setObjectProperty(adaptee->id(), adaptee->kind(), SIM_FUNCTION_NAME, name);
81             controller.setObjectProperty(adaptee->id(), adaptee->kind(), SIM_FUNCTION_API, api);
82         }
83         else if (v->getType() == types::InternalType::ScilabList)
84         {
85             // If the input is a 2-sized list, then it must be string and positive integer.
86             types::List* current = v->getAs<types::List>();
87             if (current->getSize() != 2)
88             {
89                 return false;
90             }
91             if (current->get(0)->getType() != types::InternalType::ScilabString || current->get(1)->getType() != types::InternalType::ScilabDouble)
92             {
93                 return false;
94             }
95
96             types::String* Name = current->get(0)->getAs<types::String>();
97             if (Name->getSize() != 1)
98             {
99                 return false;
100             }
101             char* c_str = wide_string_to_UTF8(Name->get(0));
102             std::string name = std::string(c_str);
103             FREE(c_str);
104
105             types::Double* Api = current->get(1)->getAs<types::Double>();
106             if (Api->getSize() != 1)
107             {
108                 return false;
109             }
110             double api = Api->get(0);
111             if (floor(api) != api)
112             {
113                 return false;
114             }
115             int api_int = static_cast<int>(api);
116
117             controller.setObjectProperty(adaptee->id(), adaptee->kind(), SIM_FUNCTION_NAME, name);
118             controller.setObjectProperty(adaptee->id(), adaptee->kind(), SIM_FUNCTION_API, api_int);
119         }
120         else
121         {
122             return false;
123         }
124         return true;
125     }
126 };
127
128 struct in
129 {
130
131     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
132     {
133         return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, INPUTS, controller);
134     }
135
136     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
137     {
138         return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, INPUTS, controller, v);
139     }
140 };
141
142 struct in2
143 {
144
145     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
146     {
147         return get_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, INPUTS, controller);
148     }
149
150     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
151     {
152         return set_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, INPUTS, controller, v);
153     }
154 };
155
156 struct intyp
157 {
158
159     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
160     {
161         return get_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, INPUTS, controller);
162     }
163
164     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
165     {
166         return set_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, INPUTS, controller, v);
167     }
168 };
169
170 struct out
171 {
172
173     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
174     {
175         return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, OUTPUTS, controller);
176     }
177
178     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
179     {
180         return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, OUTPUTS, controller, v);
181     }
182 };
183
184 struct out2
185 {
186
187     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
188     {
189         return get_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, OUTPUTS, controller);
190     }
191
192     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
193     {
194         return set_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, OUTPUTS, controller, v);
195     }
196 };
197
198 struct outtyp
199 {
200
201     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
202     {
203         return get_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, OUTPUTS, controller);
204     }
205
206     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
207     {
208         return set_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, OUTPUTS, controller, v);
209     }
210 };
211
212 struct evtin
213 {
214
215     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
216     {
217         return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_INPUTS, controller);
218     }
219
220     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
221     {
222         return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_INPUTS, controller, v);
223     }
224 };
225
226 struct evtout
227 {
228
229     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
230     {
231         return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_OUTPUTS, controller);
232     }
233
234     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
235     {
236         return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_OUTPUTS, controller, v);
237     }
238 };
239
240 struct state
241 {
242
243     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
244     {
245         model::Block* adaptee = adaptor.getAdaptee();
246
247         std::vector<double> state;
248         controller.getObjectProperty(adaptee->id(), adaptee->kind(), STATE, state);
249
250         double* data;
251         types::Double* o = new types::Double(state.size(), 1, &data);
252
253         std::copy(state.begin(), state.end(), data);
254
255         return o;
256     }
257
258     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
259     {
260
261         if (v->getType() != types::InternalType::ScilabDouble)
262         {
263             return false;
264         }
265
266         types::Double* current = v->getAs<types::Double>();
267         if (current->getCols() != 0 && current->getCols() != 1)
268         {
269             return false;
270         }
271
272         model::Block* adaptee = adaptor.getAdaptee();
273
274         std::vector<double> state;
275         std::copy(current->getReal(), current->getReal() + current->getSize(), state.begin());
276
277         controller.setObjectProperty(adaptee->id(), adaptee->kind(), STATE, state);
278         return true;
279     }
280 };
281
282 struct dstate
283 {
284
285     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
286     {
287         model::Block* adaptee = adaptor.getAdaptee();
288
289         std::vector<double> dstate;
290         controller.getObjectProperty(adaptee->id(), adaptee->kind(), DSTATE, dstate);
291
292         double* data;
293         types::Double* o = new types::Double(dstate.size(), 1, &data);
294
295         std::copy(dstate.begin(), dstate.end(), data);
296
297         return o;
298     }
299
300     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
301     {
302
303         if (v->getType() != types::InternalType::ScilabDouble)
304         {
305             return false;
306         }
307
308         types::Double* current = v->getAs<types::Double>();
309         if (current->getCols() != 0 && current->getCols() != 1)
310         {
311             return false;
312         }
313
314         model::Block* adaptee = adaptor.getAdaptee();
315
316         std::vector<double> dstate;
317         std::copy(current->getReal(), current->getReal() + current->getSize(), dstate.begin());
318
319         controller.setObjectProperty(adaptee->id(), adaptee->kind(), DSTATE, dstate);
320         return true;
321     }
322 };
323
324 struct odstate
325 {
326
327     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
328     {
329         // FIXME: get odstate
330         return 0;
331     }
332
333     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
334     {
335         model::Block* adaptee = adaptor.getAdaptee();
336
337         if (v->getType() != types::InternalType::ScilabList)
338         {
339             return false;
340         }
341
342         types::List* current = v->getAs<types::List>();
343
344         if (current->getSize() == 0)
345         {
346             return true;
347         }
348         else
349         {
350             // FIXME: get the input list and store it in the odstate field
351             return false;
352         }
353     }
354 };
355
356 struct blocktype
357 {
358
359     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
360     {
361         model::Block* adaptee = adaptor.getAdaptee();
362
363         int type;
364         controller.getObjectProperty(adaptee->id(), adaptee->kind(), SIM_BLOCKTYPE, type);
365
366         wchar_t Type = type;
367         types::String* o = new types::String(&Type);
368
369         return o;
370     }
371
372     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
373     {
374         model::Block* adaptee = adaptor.getAdaptee();
375
376         if (v->getType() != types::InternalType::ScilabString)
377         {
378             return false;
379         }
380
381         types::String* current = v->getAs<types::String>();
382         if (current->getSize() != 1)
383         {
384             return false;
385         }
386         // The input must be a character
387         if (current->get(0)[0] == '\0')
388         {
389             return false;
390         }
391         if (current->get(0)[1] != '\0')
392         {
393             return false;
394         }
395
396         int type = current->get(0)[0];
397
398         controller.setObjectProperty(adaptee->id(), adaptee->kind(), SIM_BLOCKTYPE, type);
399         return true;
400     }
401 };
402
403 template<> property<ModelAdapter>::props_t property<ModelAdapter>::fields = property<ModelAdapter>::props_t();
404
405 ModelAdapter::ModelAdapter(const ModelAdapter& o) :
406     BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(o) { }
407
408 ModelAdapter::ModelAdapter(org_scilab_modules_scicos::model::Block* o) :
409     BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(o)
410 {
411     if (property<ModelAdapter>::properties_has_not_been_set())
412     {
413         property<ModelAdapter>::fields.reserve(13);
414         property<ModelAdapter>::add_property(L"sim", &sim::get, &sim::set);
415         property<ModelAdapter>::add_property(L"in", &in::get, &in::set);
416         property<ModelAdapter>::add_property(L"in2", &in2::get, &in2::set);
417         property<ModelAdapter>::add_property(L"intyp", &intyp::get, &intyp::set);
418         property<ModelAdapter>::add_property(L"out", &out::get, &out::set);
419         property<ModelAdapter>::add_property(L"out2", &out2::get, &out2::set);
420         property<ModelAdapter>::add_property(L"outtyp", &outtyp::get, &outtyp::set);
421         property<ModelAdapter>::add_property(L"evtin", &evtin::get, &evtin::set);
422         property<ModelAdapter>::add_property(L"evtout", &evtout::get, &evtout::set);
423         property<ModelAdapter>::add_property(L"state", &state::get, &state::set);
424         property<ModelAdapter>::add_property(L"dstate", &dstate::get, &dstate::set);
425         property<ModelAdapter>::add_property(L"odstate", &odstate::get, &odstate::set);
426         property<ModelAdapter>::add_property(L"blocktype", &blocktype::get, &blocktype::set);
427     }
428 }
429
430 ModelAdapter::~ModelAdapter()
431 {
432 }
433
434 bool ModelAdapter::toString(std::wostringstream& ostr)
435 {
436     ostr << L"ModelAdapter.hxx: Dunno what to display there" << std::endl;
437     return true;
438 }
439
440 std::wstring ModelAdapter::getTypeStr()
441 {
442     return getSharedTypeStr();
443 }
444
445 std::wstring ModelAdapter::getShortTypeStr()
446 {
447     return getSharedTypeStr();
448 }
449
450 } /* view_scilab */
451 } /* namespace org_scilab_modules_scicos */