Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
JSHubPort.hxx
Go to the documentation of this file.
1
35#ifndef _UTILS_JSHUBPORT_HXX_
36#define _UTILS_JSHUBPORT_HXX_
37
38#ifdef __EMSCRIPTEN__
39
40#include <emscripten.h>
41#include <emscripten/bind.h>
42#include <emscripten/val.h>
43
44#include "utils/Hub.hxx"
46
47class JSHubFeedback {
48public:
50 virtual void on_open() {}
51
53 virtual void on_close() {}
54
56 virtual void on_error(string error) {}
57
58 static void call_on_error(unsigned long p, string error)
59 {
60 ((JSHubFeedback *)p)->on_error(error);
61 }
62};
63
64class JSHubPort : public HubPortInterface
65{
66public:
67 JSHubPort(unsigned long parent, emscripten::val send_fn, unsigned long feedback = 0)
68 : parent_(reinterpret_cast<CanHubFlow *>(parent))
69 , feedback_(reinterpret_cast<JSHubFeedback *>(feedback))
70 , sendFn_(send_fn)
71 , gcHub_(parent_->service())
72 , gcAdapter_(
73 GCAdapterBase::CreateGridConnectAdapter(&gcHub_, parent_, false))
74 {
75 extern int JSHubPort_debug_port_num;
76 myPortNum_ = JSHubPort_debug_port_num++;
77 HASSERT(sendFn_.typeof().as<std::string>() == "function");
78 gcHub_.register_port(this);
79 active_ = true;
80 if (feedback_)
81 {
82 feedback_->on_open();
83 }
84 }
85
86 ~JSHubPort()
87 {
88 pause();
89 }
90
91 void fb_close()
92 {
93 if (feedback_)
94 {
95 feedback_->on_close();
96 }
97 }
98
99 void fb_error(string e)
100 {
101 if (feedback_)
102 {
103 feedback_->on_error(e);
104 }
105 }
106
107 void abandon()
108 {
109 pause();
110 if (gcAdapter_.get() == nullptr && !gcHub_.is_waiting())
111 {
112 delete this;
113 }
114 }
115
116 void pause()
117 {
118 if (active_)
119 {
120 gcHub_.unregister_port(this);
121 if (gcAdapter_->shutdown())
122 {
123 gcAdapter_.reset();
124 }
125 active_ = false;
126 }
127 }
128
129 void resume()
130 {
131 if (!active_)
132 {
133 gcHub_.register_port(this);
135 &gcHub_, parent_, false));
136 active_ = true;
137 }
138 }
139
141 unsigned priority = UINT_MAX) OVERRIDE
142 {
143 sendFn_((string &)*buffer->data());
144 buffer->unref();
145 }
146
147 void recv(string s)
148 {
149 auto *b = gcHub_.alloc();
150 b->data()->assign(s);
151 b->data()->skipMember_ = this;
152 gcHub_.send(b);
153 }
154
155 int get_port_num() {
156 return myPortNum_;
157 }
158
159private:
160 CanHubFlow *parent_;
161 JSHubFeedback* feedback_;
162 emscripten::val sendFn_;
163 HubFlow gcHub_;
164 std::unique_ptr<GCAdapterBase> gcAdapter_;
165 bool active_;
166 int myPortNum_;
167};
168
169EMSCRIPTEN_BINDINGS(js_hub_module)
170{
171 emscripten::class_<JSHubPort>("JSHubPort")
172 // .constructor<unsigned long, emscripten::val>()
173 .constructor<unsigned long, emscripten::val, unsigned long>()
174 .function("recv", &JSHubPort::recv)
175 .function("pause", &JSHubPort::pause)
176 .function("abandon", &JSHubPort::abandon)
177 .function("get_port_num", &JSHubPort::get_port_num)
178 .function("resume", &JSHubPort::resume);
179
180 emscripten::class_<JSHubFeedback>("JSHubFeedback")
181 .class_function("call_on_error", &JSHubFeedback::call_on_error);
182}
183
184#endif // __EMSCRIPTEN__
185#endif // _UTILS_JSHUBPORT_HXX_
ssize_t recv(int socket, void *buffer, size_t length, int flags)
Receive a message from a connection-mode or connectionless-mode socket.
Definition Socket.cxx:225
Base class for all QMember types that hold data in an expandable format.
Definition Buffer.hxx:195
virtual void send(Buffer< HubData > *message, unsigned priority=UINT_MAX)=0
Entry point to the flow.
Publicly visible API for the gridconnect-to-CAN bridge.
static GCAdapterBase * CreateGridConnectAdapter(HubFlow *gc_side, CanHubFlow *can_side, bool double_bytes)
This function connects an ASCII (GridConnect-format) CAN adapter to a binary CAN adapter,...
#define OVERRIDE
Function attribute for virtual functions declaring that this funciton is overriding a funciton that s...
Definition macros.h:180
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138