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
18 #include "internal.hxx"
24 #include "Controller.hxx"
25 #include "LinkAdapter.hxx"
26 #include "model/Port.hxx"
27 #include "model/Link.hxx"
30 #include "sci_malloc.h"
31 #include "charEncoding.h"
34 namespace org_scilab_modules_scicos
44 static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
46 model::Link* adaptee = adaptor.getAdaptee();
48 std::vector<double> controlPoints;
49 controller.getObjectProperty(adaptee->id(), adaptee->kind(), CONTROL_POINTS, controlPoints);
52 int size = (int)controlPoints.size() / 2;
53 types::Double* o = new types::Double(size, 1, &data);
56 std::copy(controlPoints.begin(), controlPoints.begin() + size, stdext::checked_array_iterator<double*>(data, size));
58 std::copy(controlPoints.begin(), controlPoints.begin() + size, data);
63 static bool set(LinkAdapter& adaptor, types::InternalType* v, Controller& controller)
65 model::Link* adaptee = adaptor.getAdaptee();
67 if (v->getType() != types::InternalType::ScilabDouble)
72 types::Double* current = v->getAs<types::Double>();
74 std::vector<double> controlPoints;
75 controller.getObjectProperty(adaptee->id(), adaptee->kind(), CONTROL_POINTS, controlPoints);
77 if (current->getSize() != static_cast<int>(controlPoints.size() / 2))
82 std::copy(current->getReal(), current->getReal() + current->getSize(), controlPoints.begin());
83 controller.setObjectProperty(adaptee->id(), adaptee->kind(), CONTROL_POINTS, controlPoints);
92 static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
94 model::Link* adaptee = adaptor.getAdaptee();
96 std::vector<double> controlPoints;
97 controller.getObjectProperty(adaptee->id(), adaptee->kind(), CONTROL_POINTS, controlPoints);
100 int size = (int)controlPoints.size() / 2;
101 types::Double* o = new types::Double(size, 1, &data);
104 std::copy(controlPoints.begin() + size, controlPoints.end(), stdext::checked_array_iterator<double*>(data, size));
106 std::copy(controlPoints.begin() + size, controlPoints.end(), data);
111 static bool set(LinkAdapter& adaptor, types::InternalType* v, Controller& controller)
113 model::Link* adaptee = adaptor.getAdaptee();
115 if (v->getType() != types::InternalType::ScilabDouble)
120 types::Double* current = v->getAs<types::Double>();
122 std::vector<double> controlPoints;
123 controller.getObjectProperty(adaptee->id(), adaptee->kind(), CONTROL_POINTS, controlPoints);
125 if (current->getSize() != static_cast<int>(controlPoints.size() / 2))
130 std::copy(current->getReal(), current->getReal() + current->getSize(), controlPoints.begin() + controlPoints.size() / 2);
131 controller.setObjectProperty(adaptee->id(), adaptee->kind(), CONTROL_POINTS, controlPoints);
140 static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
142 model::Link* adaptee = adaptor.getAdaptee();
145 controller.getObjectProperty(adaptee->id(), adaptee->kind(), LABEL, id);
147 types::String* o = new types::String(1, 1);
148 o->set(0, id.data());
153 static bool set(LinkAdapter& adaptor, types::InternalType* v, Controller& controller)
155 if (v->getType() != types::InternalType::ScilabString)
160 types::String* current = v->getAs<types::String>();
161 if (current->getSize() != 1)
166 model::Link* adaptee = adaptor.getAdaptee();
169 char* c_str = wide_string_to_UTF8(current->get(0));
170 id = std::string(c_str);
173 controller.setObjectProperty(adaptee->id(), adaptee->kind(), LABEL, id);
181 static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
183 model::Link* adaptee = adaptor.getAdaptee();
185 std::vector<double> thick;
186 controller.getObjectProperty(adaptee->id(), adaptee->kind(), THICK, thick);
189 types::Double* o = new types::Double(1, 2, &data);
196 static bool set(LinkAdapter& adaptor, types::InternalType* v, Controller& controller)
198 model::Link* adaptee = adaptor.getAdaptee();
200 if (v->getType() != types::InternalType::ScilabDouble)
205 types::Double* current = v->getAs<types::Double>();
206 if (current->getRows() != 1 || current->getCols() != 2)
211 std::vector<double> thick (2);
212 thick[0] = current->get(0);
213 thick[1] = current->get(1);
215 controller.setObjectProperty(adaptee->id(), adaptee->kind(), THICK, thick);
223 static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
225 model::Link* adaptee = adaptor.getAdaptee();
229 controller.getObjectProperty(adaptee->id(), adaptee->kind(), COLOR, color);
230 controller.getObjectProperty(adaptee->id(), adaptee->kind(), KIND, kind);
233 types::Double* o = new types::Double(1, 2, &data);
235 data[0] = static_cast<double>(color);
236 data[1] = static_cast<double>(kind);
240 static bool set(LinkAdapter& adaptor, types::InternalType* v, Controller& controller)
242 model::Link* adaptee = adaptor.getAdaptee();
244 if (v->getType() != types::InternalType::ScilabDouble)
249 types::Double* current = v->getAs<types::Double>();
250 if (current->getRows() != 1 || current->getCols() != 2)
254 if (floor(current->get(0)) != current->get(0) || floor(current->get(1)) != current->get(1))
259 int color = static_cast<int>(current->get(0));
260 int kind = static_cast<int>(current->get(1));
262 controller.setObjectProperty(adaptee->id(), adaptee->kind(), COLOR, color);
263 controller.setObjectProperty(adaptee->id(), adaptee->kind(), KIND, kind);
268 static types::Double* getLinkEnd(const LinkAdapter& adaptor, const Controller& controller, object_properties_t end)
270 model::Link* adaptee = adaptor.getAdaptee();
273 types::Double* o = new types::Double(1, 3, &data);
279 controller.getObjectProperty(adaptee->id(), adaptee->kind(), end, endID);
282 ScicosID sourceBlock;
283 controller.getObjectProperty(endID, PORT, SOURCE_BLOCK, sourceBlock);
285 // Looking for the block number among the block IDs
286 ScicosID parentDiagram;
287 controller.getObjectProperty(adaptee->id(), BLOCK, PARENT_DIAGRAM, parentDiagram);
288 std::vector<ScicosID> children;
289 if (parentDiagram == 0)
293 controller.getObjectProperty(parentDiagram, DIAGRAM, CHILDREN, children);
294 data[0] = static_cast<double>(std::distance(children.begin(), std::find(children.begin(), children.end(), sourceBlock)) + 1);
296 std::vector<ScicosID> sourceBlockPorts;
300 controller.getObjectProperty(sourceBlock, BLOCK, OUTPUTS, sourceBlockPorts);
302 case DESTINATION_PORT:
303 controller.getObjectProperty(sourceBlock, BLOCK, INPUTS, sourceBlockPorts);
308 data[1] = static_cast<double>(std::distance(sourceBlockPorts.begin(), std::find(sourceBlockPorts.begin(), sourceBlockPorts.end(), endID)) + 1);
311 controller.getObjectProperty(endID, PORT, IMPLICIT, isImplicit);
313 if (isImplicit == false)
316 controller.getObjectProperty(endID, PORT, PORT_KIND, kind);
317 if (kind == model::IN || kind == model::EIN)
323 // Default case, the property was initialized at [].
333 static bool setLinkEnd(LinkAdapter& adaptor, Controller& controller, object_properties_t end, types::InternalType* v)
335 model::Link* adaptee = adaptor.getAdaptee();
337 if (v->getType() != types::InternalType::ScilabDouble)
342 types::Double* current = v->getAs<types::Double>();
344 if ((current->getRows() != 1 || current->getCols() != 3) && current->getSize() != 0)
346 return false; // Must be [] or [x y z]
350 controller.getObjectProperty(adaptee->id(), adaptee->kind(), SOURCE_PORT, from);
352 controller.getObjectProperty(adaptee->id(), adaptee->kind(), DESTINATION_PORT, to);
353 ScicosID concernedPort;
355 object_properties_t otherEnd;
359 concernedPort = from;
361 otherEnd = DESTINATION_PORT;
363 case DESTINATION_PORT:
366 otherEnd = SOURCE_PORT;
371 ScicosID unconnected = 0;
373 if (current->getSize() == 0 || (current->get(0) == 0 || current->get(1) == 0))
375 // We want to set an empty link
376 if (concernedPort == 0)
378 // In this case, the link was already empty, do a dummy call to display the console status.
379 controller.setObjectProperty(adaptee->id(), adaptee->kind(), end, concernedPort);
383 // Untie the old link on both ends and set the 2 concerned ports as unconnected
384 controller.setObjectProperty(from, PORT, CONNECTED_SIGNALS, unconnected);
385 controller.setObjectProperty(to, PORT, CONNECTED_SIGNALS, unconnected);
387 controller.setObjectProperty(adaptee->id(), adaptee->kind(), SOURCE_PORT, unconnected);
388 controller.setObjectProperty(adaptee->id(), adaptee->kind(), DESTINATION_PORT, unconnected);
393 if (current->get(2) != 0 && current->get(2) != 1)
398 if (floor(current->get(0)) != current->get(0) || floor(current->get(1)) != current->get(1))
400 return false; // Must be an integer value
403 ScicosID parentDiagram;
404 controller.getObjectProperty(adaptee->id(), BLOCK, PARENT_DIAGRAM, parentDiagram);
405 std::vector<ScicosID> children;
406 if (parentDiagram != 0)
408 controller.getObjectProperty(parentDiagram, DIAGRAM, CHILDREN, children);
411 // Connect the new one
412 int blk = static_cast<int>(current->get(0));
413 int port = static_cast<int>(current->get(1));
414 int kind = static_cast<int>(current->get(2));
415 if (kind != Start && kind != End)
419 // kind == 0: trying to set the start of the link (output port)
420 // kind == 1: trying to set the end of the link (input port)
422 if (blk < 0 || blk > static_cast<int>(children.size()))
424 return false; // Trying to link to a non-existing block
426 ScicosID blkID = children[blk - 1];
428 std::vector<ScicosID> sourceBlockPorts;
430 bool newPortIsImplicit = false;
431 int newPortKind = static_cast<int>(model::UNDEF);
433 controller.getObjectProperty(adaptee->id(), adaptee->kind(), KIND, linkType);
434 if (linkType == model::activation)
436 std::vector<ScicosID> evtin;
437 std::vector<ScicosID> evtout;
438 controller.getObjectProperty(blkID, BLOCK, EVENT_INPUTS, evtin);
439 controller.getObjectProperty(blkID, BLOCK, EVENT_OUTPUTS, evtout);
445 // The other end must be an input
447 controller.getObjectProperty(otherPort, PORT, PORT_KIND, otherPortKind);
448 if (otherPortKind != model::EIN)
453 newPortKind = static_cast<int>(model::EOUT);
454 sourceBlockPorts = evtout;
460 // The other end must be an output
462 controller.getObjectProperty(otherPort, PORT, PORT_KIND, otherPortKind);
463 if (otherPortKind != model::EOUT)
468 newPortKind = static_cast<int>(model::EIN);
469 sourceBlockPorts = evtin;
473 else if (linkType == model::regular || linkType == model::implicit)
475 std::vector<ScicosID> in;
476 std::vector<ScicosID> out;
477 controller.getObjectProperty(blkID, BLOCK, INPUTS, in);
478 controller.getObjectProperty(blkID, BLOCK, OUTPUTS, out);
480 if (linkType == model::regular)
486 // The other end must be an input
488 controller.getObjectProperty(otherPort, PORT, PORT_KIND, otherPortKind);
489 if (otherPortKind != model::IN)
494 newPortKind = static_cast<int>(model::OUT);
495 sourceBlockPorts = out;
501 // The other end must be an output
502 int otherPortKind = 1;
503 controller.getObjectProperty(otherPort, PORT, PORT_KIND, otherPortKind);
504 if (otherPortKind != model::OUT)
509 newPortKind = static_cast<int>(model::IN);
510 sourceBlockPorts = in;
513 // Rule out the implicit ports
514 for (std::vector<ScicosID>::iterator it = sourceBlockPorts.begin(); it != sourceBlockPorts.end(); ++it)
517 controller.getObjectProperty(*it, PORT, IMPLICIT, isImplicit);
518 if (isImplicit == true)
520 sourceBlockPorts.erase(it);
524 else // model::implicit
526 newPortIsImplicit = true;
527 sourceBlockPorts.insert(sourceBlockPorts.begin(), in.begin(), in.end());
528 sourceBlockPorts.insert(sourceBlockPorts.begin(), out.begin(), out.end());
530 // Rule out the explicit ports
531 for (std::vector<ScicosID>::iterator it = sourceBlockPorts.begin(); it != sourceBlockPorts.end(); ++it)
534 controller.getObjectProperty(*it, PORT, IMPLICIT, isImplicit);
535 if (isImplicit == false)
537 sourceBlockPorts.erase(it);
543 // Disconnect the old port if it was connected. After that, concernedPort will be reused to designate the new port
544 if (concernedPort != 0)
546 controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, unconnected);
549 nBlockPorts = static_cast<int>(sourceBlockPorts.size());
550 if (nBlockPorts >= port)
552 concernedPort = sourceBlockPorts[port - 1];
556 while (nBlockPorts < port) // Create as many ports as necessary
558 concernedPort = controller.createObject(PORT);
559 controller.setObjectProperty(concernedPort, PORT, IMPLICIT, newPortIsImplicit);
560 controller.setObjectProperty(concernedPort, PORT, PORT_KIND, newPortKind);
561 controller.setObjectProperty(concernedPort, PORT, SOURCE_BLOCK, blkID);
562 controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, unconnected);
563 std::vector<int> dataType;
564 controller.getObjectProperty(concernedPort, PORT, DATATYPE, dataType);
565 dataType[0] = -1; // Default number of rows for new ports
566 controller.setObjectProperty(concernedPort, PORT, DATATYPE, dataType);
568 std::vector<ScicosID> concernedPorts;
569 if (linkType == model::activation)
573 controller.getObjectProperty(blkID, BLOCK, EVENT_OUTPUTS, concernedPorts);
574 concernedPorts.push_back(concernedPort);
575 controller.setObjectProperty(blkID, BLOCK, EVENT_OUTPUTS, concernedPorts);
579 controller.getObjectProperty(blkID, BLOCK, EVENT_INPUTS, concernedPorts);
580 concernedPorts.push_back(concernedPort);
581 controller.setObjectProperty(blkID, BLOCK, EVENT_INPUTS, concernedPorts);
584 else // model::regular || model::implicit
588 controller.getObjectProperty(blkID, BLOCK, OUTPUTS, concernedPorts);
589 concernedPorts.push_back(concernedPort);
590 controller.setObjectProperty(blkID, BLOCK, OUTPUTS, concernedPorts);
594 controller.getObjectProperty(blkID, BLOCK, INPUTS, concernedPorts);
595 concernedPorts.push_back(concernedPort);
596 controller.setObjectProperty(blkID, BLOCK, INPUTS, concernedPorts);
604 controller.getObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, oldLink);
607 // Disconnect the old other end port and delete the old link
609 controller.getObjectProperty(oldLink, LINK, otherEnd, oldPort);
610 controller.setObjectProperty(oldPort, PORT, CONNECTED_SIGNALS, unconnected);
611 controller.deleteObject(oldLink);
614 // Connect the new source and destination ports together
615 controller.setObjectProperty(concernedPort, PORT, CONNECTED_SIGNALS, adaptee->id());
616 controller.setObjectProperty(adaptee->id(), adaptee->kind(), end, concernedPort);
623 static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
625 return getLinkEnd(adaptor, controller, SOURCE_PORT);
628 static bool set(LinkAdapter& adaptor, types::InternalType* v, Controller& controller)
630 return setLinkEnd(adaptor, controller, SOURCE_PORT, v);
637 static types::InternalType* get(const LinkAdapter& adaptor, const Controller& controller)
639 return getLinkEnd(adaptor, controller, DESTINATION_PORT);
642 static bool set(LinkAdapter& adaptor, types::InternalType* v, Controller& controller)
644 return setLinkEnd(adaptor, controller, DESTINATION_PORT, v);
650 template<> property<LinkAdapter>::props_t property<LinkAdapter>::fields = property<LinkAdapter>::props_t();
652 LinkAdapter::LinkAdapter(const LinkAdapter& o) :
653 BaseAdapter<LinkAdapter, org_scilab_modules_scicos::model::Link>(o) {}
655 LinkAdapter::LinkAdapter(org_scilab_modules_scicos::model::Link* o) :
656 BaseAdapter<LinkAdapter, org_scilab_modules_scicos::model::Link>(o)
658 if (property<LinkAdapter>::properties_have_not_been_set())
660 property<LinkAdapter>::fields.reserve(7);
661 property<LinkAdapter>::add_property(L"xx", &xx::get, &xx::set);
662 property<LinkAdapter>::add_property(L"yy", &yy::get, &yy::set);
663 property<LinkAdapter>::add_property(L"id", &id::get, &id::set);
664 property<LinkAdapter>::add_property(L"thick", &thick::get, &thick::set);
665 property<LinkAdapter>::add_property(L"ct", &ct::get, &ct::set);
666 property<LinkAdapter>::add_property(L"from", &from::get, &from::set);
667 property<LinkAdapter>::add_property(L"to", &to::get, &to::set);
671 LinkAdapter::~LinkAdapter()
675 std::wstring LinkAdapter::getTypeStr()
677 return getSharedTypeStr();
679 std::wstring LinkAdapter::getShortTypeStr()
681 return getSharedTypeStr();
684 } /* namespace view_scilab */
685 } /* namespace org_scilab_modules_scicos */