Changeset 15430
- Timestamp:
- 04/24/13 22:40:45 (12 years ago)
- Location:
- trunk/FACT++/src
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/InterpreterV8.cc
r15350 r15430 1474 1474 } 1475 1475 1476 1477 1476 void InterpreterV8::JsHandleState(const std::string &server, const State &state) 1478 1477 { … … 1524 1523 if (!HandleException(exception, "dim.onchange")) 1525 1524 V8::TerminateExecution(fThreadId); 1525 } 1526 1527 Handle<Value> InterpreterV8::FuncSetInterrupt(const Arguments &args) 1528 { 1529 if (args.Length()!=1) 1530 return ThrowException(String::New("Number of arguments must be 1.")); 1531 1532 if (!args[0]->IsNull() && !args[0]->IsUndefined() && !args[0]->IsFunction()) 1533 return ThrowException(String::New("Argument not a function, null or undefined.")); 1534 1535 if (args[0]->IsNull() || args[0]->IsUndefined()) 1536 { 1537 fInterruptCallback.Dispose(); 1538 return Undefined(); 1539 } 1540 1541 // Returns the value if the setter intercepts the request. Otherwise, returns an empty handle. 1542 fInterruptCallback = Persistent<Object>::New(args[0]->ToObject()); 1543 return Undefined(); 1544 } 1545 1546 int InterpreterV8::JsHandleInterrupt(const EventImp &evt) 1547 { 1548 const Locker locker; 1549 1550 if (fThreadId<0) 1551 return -42; 1552 1553 if (fInterruptCallback.IsEmpty()) 1554 return -42; 1555 1556 const HandleScope handle_scope; 1557 1558 fInterruptCallback->CreationContext()->Enter(); 1559 1560 // ------------------------------------------------------------------- 1561 1562 TryCatch exception; 1563 1564 const string str = evt.GetString(); 1565 1566 const size_t p = str.find_last_of('\n'); 1567 1568 const string irq = p==string::npos?str:str.substr(0, p); 1569 const string usr = p==string::npos?"nobody":str.substr(p+1); 1570 1571 Local<Value> irq_str = String::New(irq.c_str()); 1572 Local<Value> usr_str = String::New(usr.c_str()); 1573 Local<Value> date = Date::New(evt.GetJavaDate()); 1574 1575 int32_t rc = -42; 1576 if (!date.IsEmpty()) 1577 { 1578 const int id = V8::GetCurrentThreadId(); 1579 fThreadIds.insert(id); 1580 1581 Handle<Value> args[] = { irq_str, date, usr_str }; 1582 Handle<Function> fun = Handle<Function>(Function::Cast(*fInterruptCallback)); 1583 1584 const Handle<Value> val = fun->Call(fun, 3, args); 1585 1586 rc = !val.IsEmpty() && val->IsInt32() ? val->Int32Value() : 0; 1587 1588 fThreadIds.erase(id); 1589 } 1590 1591 if (!HandleException(exception, "interrupt")) 1592 V8::TerminateExecution(fThreadId); 1593 1594 return rc<10 || rc>255 ? -42 : rc; 1526 1595 } 1527 1596 … … 2342 2411 dimctrl->Set(String::New("setState"), FunctionTemplate::New(WrapSetState), ReadOnly); 2343 2412 dimctrl->Set(String::New("getState"), FunctionTemplate::New(WrapGetState), ReadOnly); 2413 dimctrl->Set(String::New("setInterruptHandler"), FunctionTemplate::New(WrapSetInterrupt), ReadOnly); 2344 2414 2345 2415 Handle<ObjectTemplate> v8 = ObjectTemplate::New(); … … 2522 2592 fStateCallbacks.clear(); 2523 2593 2594 // Now we can dispose the persistent interrupt handler 2595 fInterruptCallback.Dispose(); 2596 2524 2597 // Now we can dispose all persistent handles from reverse maps 2525 2598 for (auto it=fReverseMap.begin(); it!=fReverseMap.end(); it++) -
trunk/FACT++/src/InterpreterV8.h
r15172 r15430 46 46 // List of all states already set 47 47 std::vector<std::pair<int, std::string>> fStates; 48 49 // Interrupt handler 50 v8::Persistent<v8::Object> fInterruptCallback; 48 51 49 52 static v8::Handle<v8::FunctionTemplate> fTemplateLocal; … … 86 89 v8::Handle<v8::Value> FuncGetServices(const v8::Arguments& args); 87 90 v8::Handle<v8::Value> FuncNewState(const v8::Arguments& args); 91 v8::Handle<v8::Value> FuncSetInterrupt(const v8::Arguments& args); 88 92 //v8::Handle<v8::Value> FuncOpen(const v8::Arguments& args); 89 93 v8::Handle<v8::Value> FuncSubscription(const v8::Arguments& args); … … 142 146 static v8::Handle<v8::Value> WrapGetDescription(const v8::Arguments &args){ if (This) return This->FuncGetDescription(args);else return v8::Undefined(); } 143 147 static v8::Handle<v8::Value> WrapGetServices(const v8::Arguments &args){ if (This) return This->FuncGetServices(args);else return v8::Undefined(); } 148 static v8::Handle<v8::Value> WrapSetInterrupt(const v8::Arguments &args){ if (This) return This->FuncSetInterrupt(args);else return v8::Undefined(); } 144 149 //static v8::Handle<v8::Value> WrapOpen(const v8::Arguments &args) { if (This) return This->FuncOpen(args); else return v8::Undefined(); } 145 150 static v8::Handle<v8::Value> WrapSubscription(const v8::Arguments &args){ if (This) return This->FuncSubscription(args);else return v8::Undefined(); } … … 204 209 virtual std::pair<uint64_t, EventImp *> JsGetEvent(const std::string &) { return std::make_pair(0, (EventImp*)0); }; 205 210 211 int JsHandleInterrupt(const EventImp &); 206 212 void JsHandleEvent(const EventImp &, uint64_t, const std::string &); 207 213 void JsHandleState(const std::string &, const State &); -
trunk/FACT++/src/RemoteControl.h
r15128 r15430 523 523 fImp = &imp; 524 524 fImp->SetStateCallback(bind(&InterpreterV8::JsHandleState, this, placeholders::_1, placeholders::_2)); 525 fImp->SetInterruptHandler(bind(&InterpreterV8::JsHandleInterrupt, this, placeholders::_1)); 525 526 } 526 527 }; -
trunk/FACT++/src/StateMachineDimControl.cc
r15295 r15430 130 130 InterpreterV8::JsStop(); 131 131 return GetCurrentState(); 132 } 133 134 int StateMachineDimControl::InterruptScript(const EventImp &evt) 135 { 136 if (!fInterruptHandler) 137 return GetCurrentState(); 138 139 string str = evt.GetString(); 140 141 const size_t p = str.find_last_of('\n'); 142 if (p!=string::npos) 143 str[p] = ':'; 144 145 Info("Interrupt request received ["+str+"]"); 146 return fInterruptHandler(evt); 132 147 } 133 148 … … 510 525 (bind(&StateMachineDimControl::StopScript, this)) 511 526 ("Stop a runnning batch script or JavaScript"); 527 528 AddEvent("INTERRUPT", "C") 529 (bind(&StateMachineDimControl::InterruptScript, this, placeholders::_1)) 530 ("Send an interrupt request (IRQ) to a running JavaScript"); 512 531 } 513 532 … … 565 584 return !Dim::SendCommand("DIM_CONTROL/STOP", fUser); 566 585 586 if (conf.Has("interrupt")) 587 return !Dim::SendCommand("DIM_CONTROL/INTERRUPT", conf.Get<string>("interrupt")+"\n"+fUser); 588 567 589 if (conf.Has("start")) 568 590 return !Dim::SendCommand("DIM_CONTROL/START", conf.Get<string>("start")+" user='"+fUser+"'"+fArgumentsJS); -
trunk/FACT++/src/StateMachineDimControl.h
r15041 r15430 36 36 std::string fArgumentsJS; 37 37 38 std::function<int(const EventImp &)> fInterruptHandler; 39 38 40 std::string Line(const std::string &txt, char fill); 39 41 … … 46 48 int StartScript(const EventImp &imp, const std::string &cmd); 47 49 int StopScript(); 50 int InterruptScript(const EventImp &imp); 48 51 49 52 int HandleStateChange(const std::string &server, DimDescriptions *state); … … 72 75 void SetStateCallback(const std::function<void(const std::string &, const State &)> &func) { fStateCallback = func; } 73 76 77 void SetInterruptHandler(const std::function<int(const EventImp &)> &func=std::function<int(const EventImp &)>()) { fInterruptHandler = func; } 78 74 79 public: 75 80 StateMachineDimControl(std::ostream &out=std::cout); -
trunk/FACT++/src/dimctrl.cc
r15188 r15430 1 1 #include "StateMachineDimControl.h" 2 3 //#include <sys/stat.h> 2 4 3 5 #include "RemoteControl.h" … … 43 45 { 44 46 control.add_options() 47 ("batch", var<string>(), "Start a batch script with the given name at the given label (script.dim[:N]) on the dimctrl-server") 45 48 ("start", var<string>(), "Start a java script with the given name on the dimctrl-server") 46 ("batch", var<string>(), "Start a batch script with the given name at the given label (script.dim[:N]) on the dimctrl-server")47 49 ("stop", po_switch(), "Stop a currently running script on the dimctrl-server") 50 ("interrupt", var<string>()->implicit_value(""), "Send an interrupt request (IRQ) to a running JavaScript.") 48 51 ("restart", var<string>(), "Send 'EXIT 126' to the given server") 49 52 ("msg", var<string>(), "Send a message to the chat server.") … … 106 109 int main(int argc, const char* argv[]) 107 110 { 111 //chmod(argv[0], 04775); 112 108 113 Configuration conf(argv[0]); 109 114 conf.SetPrintUsage(PrintUsage);
Note:
See TracChangeset
for help on using the changeset viewer.