Xcos MVC: add a test and use unnamed functions parameters
[scilab.git] / scilab / modules / scicos / src / cpp / view_scilab / BlockAdapter.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.1-en.txt
10  *
11  */
12
13 #include <string>
14 #include <memory>
15
16 #include "internal.hxx"
17 #include "list.hxx"
18 #include "mlist.hxx"
19 #include "string.hxx"
20 #include "types.hxx"
21 #include "user.hxx"
22
23 #include "Controller.hxx"
24 #include "model/Block.hxx"
25 #include "BlockAdapter.hxx"
26 #include "DiagramAdapter.hxx"
27 #include "GraphicsAdapter.hxx"
28 #include "ModelAdapter.hxx"
29
30 extern "C" {
31 #include "sci_malloc.h"
32 #include "charEncoding.h"
33 }
34
35 namespace org_scilab_modules_scicos
36 {
37 namespace view_scilab
38 {
39 namespace
40 {
41
42 std::wstring rpar(L"rpar");
43
44 struct graphics
45 {
46     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
47     {
48         GraphicsAdapter localAdaptor = GraphicsAdapter(adaptor.getAdaptee());
49         return localAdaptor.getAsTList(new types::MList(), controller);
50     }
51
52     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
53     {
54         GraphicsAdapter localAdaptor = GraphicsAdapter(adaptor.getAdaptee());
55         return localAdaptor.setAsTList(v, controller);
56     }
57 };
58
59 struct model
60 {
61     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
62     {
63         ModelAdapter localAdaptor = ModelAdapter(adaptor.getAdaptee());
64         types::MList* ret = localAdaptor.getAsTList(new types::MList(), controller)->getAs<types::MList>();
65
66         // If the Block is a SuperBlock, set its 'rpar' property with the saved Diagram
67         DiagramAdapter* rpar_content = adaptor.getRpar()->getAs<DiagramAdapter>();
68         if (rpar_content != 0 && localAdaptor.getDiagram() == 0)
69         {
70             // Decrease rpar_content's ref count to counter the increases from the other Adapters
71             rpar_content->DecreaseRef();
72             ret->set(rpar, rpar_content);
73         }
74
75         return ret;
76     }
77
78     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
79     {
80         ModelAdapter localAdaptor = ModelAdapter(adaptor.getAdaptee());
81         if (!localAdaptor.setAsTList(v, controller))
82         {
83             return false;
84         }
85
86         adaptor.setRpar(localAdaptor.getDiagram());
87         return true;
88     }
89 };
90
91 struct gui
92 {
93     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
94     {
95         std::string Interface;
96         ScicosID adaptee = adaptor.getAdaptee()->id();
97         controller.getObjectProperty(adaptee, BLOCK, INTERFACE_FUNCTION, Interface);
98
99         return new types::String(Interface.data());
100     }
101
102     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
103     {
104         if (v->getType() != types::InternalType::ScilabString)
105         {
106             return false;
107         }
108
109         types::String* current = v->getAs<types::String>();
110         if (current->getRows() != 1 || current->getCols() != 1)
111         {
112             return false;
113         }
114
115         wchar_t* w_name = current->get(0);
116         char* name = wide_string_to_UTF8(w_name);
117         std::string stName(name);
118         FREE(name);
119
120         ScicosID adaptee = adaptor.getAdaptee()->id();
121         controller.setObjectProperty(adaptee, BLOCK, INTERFACE_FUNCTION, stName);
122         return true;
123     }
124 };
125
126 struct doc
127 {
128     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& /*controller*/)
129     {
130         return adaptor.getDocContent();
131     }
132
133     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& /*controller*/)
134     {
135         adaptor.setDocContent(v->clone());
136         return true;
137     }
138 };
139
140 } /* namespace */
141
142 template<> property<BlockAdapter>::props_t property<BlockAdapter>::fields = property<BlockAdapter>::props_t();
143
144 BlockAdapter::BlockAdapter(std::shared_ptr<org_scilab_modules_scicos::model::Block> adaptee) :
145     BaseAdapter<BlockAdapter, org_scilab_modules_scicos::model::Block>(adaptee),
146     rpar_content(nullptr),
147     doc_content(new types::List())
148 {
149     if (property<BlockAdapter>::properties_have_not_been_set())
150     {
151         property<BlockAdapter>::fields.reserve(4);
152         property<BlockAdapter>::add_property(L"graphics", &graphics::get, &graphics::set);
153         property<BlockAdapter>::add_property(L"model", &model::get, &model::set);
154         property<BlockAdapter>::add_property(L"gui", &gui::get, &gui::set);
155         property<BlockAdapter>::add_property(L"doc", &doc::get, &doc::set);
156     }
157 }
158
159 BlockAdapter::BlockAdapter(const BlockAdapter& adapter) :
160     BaseAdapter<BlockAdapter, org_scilab_modules_scicos::model::Block>(adapter),
161     rpar_content(adapter.getRpar()),
162     doc_content(adapter.getDocContent())
163 {
164 }
165
166 BlockAdapter::~BlockAdapter()
167 {
168     if (rpar_content != nullptr)
169     {
170         rpar_content->DecreaseRef();
171         rpar_content->killMe();
172     }
173
174     doc_content->DecreaseRef();
175     doc_content->killMe();
176 }
177
178 std::wstring BlockAdapter::getTypeStr()
179 {
180     return getSharedTypeStr();
181 }
182
183 std::wstring BlockAdapter::getShortTypeStr()
184 {
185     return getSharedTypeStr();
186 }
187
188 types::InternalType* BlockAdapter::getRpar() const
189 {
190     if (rpar_content != nullptr)
191     {
192         rpar_content->IncreaseRef();
193     }
194     return rpar_content;
195 }
196
197 void BlockAdapter::setRpar(types::InternalType* v)
198 {
199     if (v != nullptr)
200     {
201         // The old 'rpar_content' needs to be freed after setting it to 'v'
202         types::InternalType* temp = rpar_content;
203
204         v->IncreaseRef();
205         rpar_content = v;
206
207         if (temp != nullptr)
208         {
209             temp->DecreaseRef();
210             temp->killMe();
211         }
212     }
213 }
214
215 types::InternalType* BlockAdapter::getDocContent() const
216 {
217     doc_content->IncreaseRef();
218     return doc_content;
219 }
220
221 void BlockAdapter::setDocContent(types::InternalType* v)
222 {
223     doc_content->DecreaseRef();
224     doc_content->killMe();
225
226     v->IncreaseRef();
227     doc_content = v;
228 }
229
230 } /* namespace view_scilab */
231 } /* namespace org_scilab_modules_scicos */