15 #include "xrubysupport.h"
18 #include <QDataStream>
22 #define XRUBYSUPPORT_RB ":/script/xrubysupport.rb" //in the qrc.
24 XRuby::XRuby(
const char *name,
bool runtime,
const shared_ptr<XMeasure> &measure)
27 m_thread(shared_from_this(), &
XRuby::execute) {
29 m_lsnChildCreated = tr[ *
this].onChildCreated().connectWeakly(shared_from_this(),
30 &XRuby::onChildCreated, XListener::FLAG_MAIN_THREAD_CALL);
37 XRuby::rnode_create(
const shared_ptr<XNode> &node) {
38 if(
auto vnode = dynamic_pointer_cast<XValueNodeBase>(node)) {
39 return m_rubyClassValueNode->rubyObject(vnode);
41 else if(
auto lnode = dynamic_pointer_cast<XListNodeBase>(node)) {
42 return m_rubyClassListNode->rubyObject(lnode);
45 return m_rubyClassNode->rubyObject(node);
50 XRuby::rnode_child(
const shared_ptr<XNode> &node, Ruby::Value var) {
51 shared_ptr<XNode> child;
53 if(Ruby::isConvertible<long>(var)) {
54 long idx = Ruby::convert<long>(var);
57 if ((idx >= 0) && (idx < (int)shot.size()))
58 child = shot.list()->at(idx);
61 throw (std::string)formatString(
"No such node idx:%ld on %s\n",
62 idx, node->getName().c_str());
65 else if(Ruby::isConvertible<const char*>(var)) {
66 const char *name = Ruby::convert<const char*>(var);
67 child = node->getChild(name);
69 throw (std::string)formatString(
"No such node name:%s on %s\n",
70 name, node->getName().c_str());
74 throw (std::string)formatString(
"Ill format to find node on %s\n", node->getName().c_str());
75 return rnode_create(child);
78 XRuby::rlistnode_create_child(
const shared_ptr<XNode> &node, Ruby::Value rbtype, Ruby::Value rbname) {
79 const char *type = Ruby::convert<const char*>(rbtype);
80 const char *name = Ruby::convert<const char*>(rbname);
82 shared_ptr<XNode> child;
84 if( shot[ *node].isRuntime() ) {
85 throw (std::string)formatString(
"Node %s is run-time node!\n", node->getName().c_str());
89 throw (std::string)formatString(
"Error on %s : Not ListNode. Could not make child"
90 " name = %s, type = %s\n", node->getName().c_str(), name, type);
93 child = node->getChild(name);
96 if(lnode->isThreadSafeDuringCreationByTypename()) {
97 child = lnode->createByTypename(type, name);
100 shared_ptr<Payload::tCreateChild> x(
new Payload::tCreateChild);
105 shot.talk(shot[ *
this].onChildCreated(), x);
115 throw (std::string)formatString(
116 "Error on %s : Could not make child"
117 " name = %s, type = %s\n", node->getName().c_str(), name, type);
119 return rnode_create(child);
122 XRuby::onChildCreated(
const Snapshot &,
const shared_ptr<Payload::tCreateChild> &x) {
123 x->child = x->lnode->createByTypename(x->type, x->name);
129 XRuby::rlistnode_release_child(
const shared_ptr<XNode> &node, Ruby::Value rbchild) {
132 throw (std::string)formatString(
"Error on %s : Not ListNode.", node->getName().c_str());
135 if( !shot[ *lnode].isUIEnabled()) {
136 throw (std::string)formatString(
"Node %s is read-only!\n", node->getName().c_str());
138 shared_ptr<XNode> child(m_rubyClassNode->unwrap(rbchild));
139 lnode->release(child);
144 XRuby::rnode_name(
const shared_ptr<XNode> &node) {
148 XRuby::rnode_count(
const shared_ptr<XNode> &node) {
153 XRuby::rnode_touch(
const shared_ptr<XNode> &node) {
156 throw (std::string)formatString(
"Type mismatch on node %s\n", node->getName().c_str());
157 dbgPrint(QString(
"Ruby, Node %1, touching."));
159 if(tr[ *tnode].isUIEnabled() )
162 throw (std::string)formatString(
"Node %s is read-only!\n", node->getName().c_str());
167 XRuby::rvaluenode_set(
const shared_ptr<XNode> &node, Ruby::Value var) {
171 dbgPrint(QString(
"Ruby, Node %1, setting new value.").arg(node->getName()) );
172 if( !shot[ *node].isUIEnabled()) {
173 throw (std::string)formatString(
"Node %s is read-only!\n", node->getName().c_str());
176 dbgPrint(QString(
"Ruby, Node %1, new value: %2.").arg(node->getName()).arg(shot[ *vnode].to_str()) );
177 return XRuby::getValueOfNode(vnode);
180 XRuby::rvaluenode_load(
const shared_ptr<XNode> &node, Ruby::Value var) {
184 dbgPrint(QString(
"Ruby, Node %1, loading new value.").arg(node->getName()) );
185 if( shot[ *node].isRuntime()) {
186 throw (std::string)formatString(
"Node %s is run-time node!\n", node->getName().c_str());
189 dbgPrint(QString(
"Ruby, Node %1, new value: %2.").arg(node->getName()).arg(shot[ *vnode].to_str()) );
190 return XRuby::getValueOfNode(vnode);
193 XRuby::rvaluenode_get(
const shared_ptr<XNode> &node) {
196 return XRuby::getValueOfNode(vnode);
199 XRuby::rvaluenode_to_str(
const shared_ptr<XNode> &node) {
206 auto dnode = dynamic_pointer_cast<
XDoubleNode>(node);
207 auto inode = dynamic_pointer_cast<
XIntNode>(node);
208 auto uinode = dynamic_pointer_cast<
XUIntNode>(node);
209 auto lnode = dynamic_pointer_cast<
XLongNode>(node);
210 auto ulnode = dynamic_pointer_cast<
XULongNode>(node);
211 auto bnode = dynamic_pointer_cast<
XBoolNode>(node);
213 if(Ruby::isConvertible<long>(value)) {
214 long integer = Ruby::convert<long>(value);
215 if(uinode || ulnode) {
217 throw (std::string)formatString(
"Negative FIXNUM on %s\n", node->getName().c_str());
220 if(inode) { trans( *inode) = integer;
return; }
221 if(lnode) { trans( *lnode) = integer;
return; }
222 if(uinode) { trans( *uinode) = integer;
return; }
223 if(ulnode) { trans( *ulnode) = integer;
return; }
224 double dbl = integer;
225 if(dnode) { trans( *dnode) = dbl;
return;}
226 throw (std::string)formatString(
"FIXNUM is not appropreate on %s\n", node->getName().c_str());
228 else if(Ruby::isConvertible<double>(value)) {
229 double dbl = Ruby::convert<double>(value);
230 if(dnode) { trans( *dnode) = dbl;
return;}
231 throw (std::string)formatString(
"FLOAT is not appropreate on %s\n", node->getName().c_str());
233 else if(Ruby::isConvertible<const char*>(value)) {
235 trans( *node).str(Ruby::convert<const char*>(value));
238 throw (std::string)formatString(
"Validation error %s on %s\n"
239 , (
const char*)e.msg().c_str(), node->getName().c_str());
242 else if(Ruby::isConvertible<bool>(value)) {
243 bool v = Ruby::convert<bool>(value);
244 if(bnode) { trans( *bnode) = v;
return;}
245 throw (std::string)formatString(
"TRUE is not appropreate on %s\n", node->getName().c_str());
248 throw (std::string)formatString(
"UNKNOWN TYPE is not appropreate on %s\n", node->getName().c_str());
251 XRuby::getValueOfNode(
const shared_ptr<XValueNodeBase> &node) {
252 auto dnode = dynamic_pointer_cast<
XDoubleNode>(node);
253 auto inode = dynamic_pointer_cast<
XIntNode>(node);
254 auto uinode = dynamic_pointer_cast<
XUIntNode>(node);
255 auto lnode = dynamic_pointer_cast<
XLongNode>(node);
256 auto ulnode = dynamic_pointer_cast<
XULongNode>(node);
257 auto bnode = dynamic_pointer_cast<
XBoolNode>(node);
258 auto snode = dynamic_pointer_cast<
XStringNode>(node);
270 shared_ptr<XRubyThread>
273 long id = Ruby::convert<long>(threadid);
274 shared_ptr<XRubyThread> rubythread;
277 for(XNode::const_iterator it = shot.list()->begin(); it != shot.list()->end(); ++it) {
280 if(
id == shot[ *th->threadID()])
288 shared_ptr<XString> sstr(
new XString(Ruby::convert<const char*>(str)));
289 shared_ptr<XRubyThread> rubythread(
findRubyThread(node, threadid));
292 shot.talk(shot[ *rubythread].onMessageOut(), sstr);
293 dbgPrint(QString(
"Ruby [%1]; %2").arg(shot[ *rubythread->filename()].to_str()).arg( *sstr));
296 dbgPrint(QString(
"Ruby [global]; %1").arg(*sstr));
302 shared_ptr<XRubyThread> rubythread(
findRubyThread(node, threadid));
304 XString line = rubythread->gets();
310 throw XString(
"UNKNOWN Ruby thread\n");
314 XRuby::is_main_terminated(
const shared_ptr<XNode> &) {
321 m_ruby.reset(
new Ruby(
"KAME"));
322 shared_ptr<XRuby> xruby = dynamic_pointer_cast<
XRuby>(shared_from_this());
324 m_rubyClassNode->defineMethod<&XRuby::rnode_name>(
"name");
325 m_rubyClassNode->defineMethod<&XRuby::rnode_touch>(
"touch");
326 m_rubyClassNode->defineMethod1<&XRuby::rnode_child>(
"child");
327 m_rubyClassNode->defineMethod<&XRuby::rnode_count>(
"count");
330 m_rubyClassNode->rubyClassObject()));
331 m_rubyClassValueNode->defineMethod1<&XRuby::rvaluenode_set>(
"internal_set");
332 m_rubyClassValueNode->defineMethod1<&XRuby::rvaluenode_load>(
"internal_load");
333 m_rubyClassValueNode->defineMethod<&XRuby::rvaluenode_get>(
"internal_get");
336 m_rubyClassNode->rubyClassObject()));
337 m_rubyClassListNode->defineMethod2<&XRuby::rlistnode_create_child>(
"internal_create");
338 m_rubyClassListNode->defineMethod1<&XRuby::rlistnode_release_child>(
"release");
341 shared_ptr<XMeasure> measure = m_measure.lock();
343 XString name = measure->getName();
344 name[0] = toupper(name[0]);
345 Ruby::Value rbRootNode = rnode_create(measure);
346 m_ruby->defineGlobalConst(name.c_str(), rbRootNode);
347 m_ruby->defineGlobalConst(
"RootNode", rbRootNode);
350 Ruby::Value rbRubyThreads = rnode_create(shared_from_this());
351 m_ruby->defineGlobalConst(
"XRubyThreads", rbRubyThreads);
353 rbRubyThreads,
"my_rbdefout");
355 rbRubyThreads,
"my_rbdefin");
356 m_rubyClassNode->defineSingletonMethod<&XRuby::is_main_terminated>(
357 rbRubyThreads,
"is_main_terminated");
361 QFile scriptfile(XRUBYSUPPORT_RB);
362 if( !scriptfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
363 gErrPrint(
"No KAME ruby support file installed.");
366 fprintf(stderr,
"Loading ruby scripting monitor.\n");
368 QDataStream( &scriptfile).readRawData(data,
sizeof(data));
370 int state = m_ruby->evalProtect(data);
372 fprintf(stderr,
"Ruby, exception(s) occurred.\n");
373 m_ruby->printErrorInfo();
377 fprintf(stderr,
"ruby fin");
379 fprintf(stderr,
"ished\n");