Sinelabore Homepage

Ports#

Role in SysML v2#

A port definition defines a connection point to enable interactions between parts. A port usage is a usage of a port definition.

A connection definition is both a relationship that classifies connections between related things, such as items and parts. Two of the owned features of a connection definition must be connection ends, which specify the things that are related by the connection definition. Connection definitions with exactly two connection ends are called binary connection definitions, and they classify binary connections.

A port must have a direction (in or out at present). Presently only binary connections are supported

Mapping to C++#

The framework defines the base classes Port and and InputPort. The provide functionality to send and receive events or data via ports. Presently it is required to create own derived classes and overwrite the process and handle methods to add functionality to handle handling.

Example#

SysML v2 source code:

 1private import ScalarValues::*;
 2
 3package Test {
 4
 5  port def MyPort {
 6    attribute dataValue : Integer;
 7  }
 8
 9  part def PartA {
10    doc /*
11      * Generates data and sends it to other parts via this port
12      */
13    out port myPort : MyPort;
14  }
15
16  part def PartB {
17    doc /*
18    * Receive data via port
19    */
20    in port myPort : ~MyPort;
21  }
22
23	// Main system composition
24	part def System {
25		doc /*
26		 * Main system that contains the parts
27		 */
28		part partA : PartA;
29		part partB : PartB;
30		
31		// Connect the parts
32		connect partA.myPort to partB.myPort;  
33  }
34} // namespace

C++ source code:

 1#include <framework.h>
 2
 3namespace Test {
 4struct MyPortDef {
 5  int dataValue;
 6};
 7
 8using MyPort = std::variant<MyPortDef>;
 9
10class PartA : public Part {
11
12public:
13  PartA() {}
14
15  Port<MyPort> myPort;
16
17  virtual void process() override {}
18
19  // must be called by derived classes after constructing the parts
20  virtual void init(void) override {}
21};
22
23class PartB : public Part {
24
25public:
26  PartB() {
27    myPort.addHandler([this](const MyPort &e) {
28      std::visit([this](auto &&ev) { handle(ev); }, e);
29    });
30  }
31
32  // called by process() to handle received event
33  virtual void handle(const MyPortDef &e) { assert(false); };
34
35  InputPort<MyPort> myPort;
36
37  virtual void process() override { myPort.process(); }
38
39  // must be called by derived classes after constructing the parts
40  virtual void init(void) override {}
41};
42
43class System : public Part {
44
45public:
46  System() {}
47
48  std::unique_ptr<PartA> partA = std::make_unique<PartA>();
49
50  std::unique_ptr<PartB> partB = std::make_unique<PartB>();
51
52  virtual void process() override {
53
54    partA->process();
55
56    partB->process();
57  }
58
59  // must be called by derived classes after constructing the parts
60  virtual void init(void) override {
61    assert(partA);
62    assert(partB);
63    partA->init();
64
65    partB->init();
66
67    connect(&partA->myPort, &partB->myPort);
68  }
69};
70
71} // end of namespace Test