Changeset 16802


Ignore:
Timestamp:
06/10/13 17:22:45 (11 years ago)
Author:
tbretz
Message:
Allow arguments to be given to the interrupt handler and added a possibility to trigger an interrupt also from within the script; some modification to the way code is executed so that return values are only printed really when some code is finished from the command line, but not for include or when the main program is run.
Location:
trunk/FACT++/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/InterpreterV8.cc

    r16538 r16802  
    715715Handle<Value> InterpreterV8::FuncInclude(const Arguments& args)
    716716{
    717     for (int i=0; i<args.Length(); i++)
    718     {
    719         const String::AsciiValue file(args[i]);
    720         if (*file == NULL)
    721             return ThrowException(String::New("File name missing."));
    722 
    723         if (strlen(*file)==0)
    724             return ThrowException(String::New("File name empty."));
    725 
    726         izstream fin(*file);
    727         if (!fin)
    728             return ThrowException(String::New(errno!=0?strerror(errno):"Insufficient memory for decompression"));
    729 
    730         string buffer;
    731         getline(fin, buffer, '\0');
    732 
    733         if ((fin.fail() && !fin.eof()) || fin.bad())
    734             return ThrowException(String::New(strerror(errno)));
    735 
    736         if (buffer.length()>1 && buffer[0]=='#' && buffer[1]=='!')
    737             buffer.insert(0, "//");
    738 
    739         const Handle<Value> rc = ExecuteCode(buffer, *file);
    740         if (rc.IsEmpty())
    741             return Undefined();
    742     }
    743 
    744     return Undefined();
     717    if (args.Length()!=1)
     718        return ThrowException(String::New("Number of arguments must be one."));
     719
     720    if (!args[0]->IsString())
     721        return ThrowException(String::New("Argument must be a string."));
     722
     723    const String::AsciiValue file(args[0]);
     724    if (*file == NULL)
     725        return ThrowException(String::New("File name missing."));
     726
     727    if (strlen(*file)==0)
     728        return ThrowException(String::New("File name empty."));
     729
     730    izstream fin(*file);
     731    if (!fin)
     732        return ThrowException(String::New(errno!=0?strerror(errno):"Insufficient memory for decompression"));
     733
     734    string buffer;
     735    getline(fin, buffer, '\0');
     736
     737    if ((fin.fail() && !fin.eof()) || fin.bad())
     738        return ThrowException(String::New(strerror(errno)));
     739
     740    if (buffer.length()>1 && buffer[0]=='#' && buffer[1]=='!')
     741        buffer.insert(0, "//");
     742
     743    return ExecuteCode(buffer, *file);
    745744}
    746745
     
    15561555}
    15571556
     1557// ==========================================================================
     1558//                           Interrupt handling
     1559// ==========================================================================
     1560
    15581561Handle<Value> InterpreterV8::FuncSetInterrupt(const Arguments &args)
    15591562{
     
    15751578}
    15761579
     1580Handle<Value> InterpreterV8::HandleInterruptImp(string str, uint64_t time)
     1581{
     1582    if (fInterruptCallback.IsEmpty())
     1583        return Handle<Value>();
     1584
     1585    const size_t p = str.find_last_of('\n');
     1586
     1587    const string usr = p==string::npos?"":str.substr(p+1);
     1588
     1589    string irq = p==string::npos?str:str.substr(0, p);
     1590    const map<string,string> data = Tools::Split(irq, true);
     1591
     1592    Local<Value>  irq_str = String::New(irq.c_str());
     1593    Local<Value>  usr_str = String::New(usr.c_str());
     1594    Local<Value>  date    = Date::New(time);
     1595    Handle<Object> arr    = Array::New(data.size());
     1596
     1597    if (date.IsEmpty() || arr.IsEmpty())
     1598        return Handle<Value>();
     1599
     1600    for (auto it=data.begin(); it!=data.end(); it++)
     1601    {
     1602        cout << "|" << it->first << "=" << it->second << "|" << endl;
     1603        arr->Set(String::New(it->first.c_str()), String::New(it->second.c_str()));
     1604    }
     1605
     1606    Handle<Value> args[] = { irq_str, arr, date, usr_str };
     1607    Handle<Function> fun = Handle<Function>(Function::Cast(*fInterruptCallback));
     1608
     1609    return fun->Call(fun, 4, args);
     1610}
     1611
    15771612int InterpreterV8::JsHandleInterrupt(const EventImp &evt)
    15781613{
     
    15821617        return -42;
    15831618
    1584     if (fInterruptCallback.IsEmpty())
    1585         return -42;
    1586 
    15871619    const HandleScope handle_scope;
    15881620
     
    15931625    TryCatch exception;
    15941626
    1595     const string str = evt.GetString();
    1596 
    1597     const size_t p = str.find_last_of('\n');
    1598 
    1599     const string irq = p==string::npos?str:str.substr(0, p);
    1600     const string usr = p==string::npos?"nobody":str.substr(p+1);
    1601 
    1602     Local<Value> irq_str = String::New(irq.c_str());
    1603     Local<Value> usr_str = String::New(usr.c_str());
    1604     Local<Value> date = Date::New(evt.GetJavaDate());
    1605 
    1606     int32_t rc = -42;
    1607     if (!date.IsEmpty())
    1608     {
    1609         const int id = V8::GetCurrentThreadId();
    1610         fThreadIds.insert(id);
    1611 
    1612         Handle<Value> args[] = { irq_str, date, usr_str };
    1613         Handle<Function> fun = Handle<Function>(Function::Cast(*fInterruptCallback));
    1614 
    1615         const Handle<Value> val = fun->Call(fun, 3, args);
    1616 
    1617         rc = !val.IsEmpty() && val->IsInt32() ? val->Int32Value() : 0;
    1618 
    1619         fThreadIds.erase(id);
    1620     }
     1627    const int id = V8::GetCurrentThreadId();
     1628    fThreadIds.insert(id);
     1629
     1630    const Handle<Value> val = HandleInterruptImp(evt.GetString(), evt.GetJavaDate());
     1631
     1632    fThreadIds.erase(id);
     1633
     1634    const int rc = !val.IsEmpty() && val->IsInt32() ? val->Int32Value() : 0;
    16211635
    16221636    if (!HandleException(exception, "interrupt"))
     
    16261640}
    16271641
    1628 /*
    1629 void Cleanup( Persistent<Value> object, void *parameter )
    1630 {
    1631     cout << "======================> RemoveMyObj()" << endl;
    1632 }*/
     1642Handle<Value> InterpreterV8::FuncTriggerInterrupt(const Arguments &args)
     1643{
     1644    string data;
     1645    for (int i=0; i<args.Length(); i++)
     1646    {
     1647        const String::AsciiValue str(args[i]);
     1648
     1649        if (string(*str).find_first_of('\n')!=string::npos)
     1650            return ThrowException(String::New("No argument must contain line breaks."));
     1651
     1652        if (!*str)
     1653            continue;
     1654
     1655        data += *str;
     1656        data += ' ';
     1657    }
     1658
     1659    HandleScope handle_scope;
     1660
     1661    const Handle<Value> rc = HandleInterruptImp(Tools::Trim(data), Time().JavaDate());
     1662    return handle_scope.Close(rc);
     1663}
     1664
     1665// ==========================================================================
     1666//                           Class 'Subscription'
     1667// ==========================================================================
    16331668
    16341669Handle<Value> InterpreterV8::FuncSubscription(const Arguments &args)
     
    22152250        return Undefined();
    22162251
    2217     // If all went well and the result wasn't undefined then print
    2218     // the returned value.
    2219     if (!rc->IsUndefined() && file!="internal")
    2220         JsResult(*String::AsciiValue(rc));
    2221 
    22222252    if (!global.IsEmpty() && !save_date.IsEmpty())
    22232253    {
     
    22772307
    22782308        // Execute code which was entered
    2279         ExecuteCode(command, "console");
     2309        const Handle<Value> rc = ExecuteCode(command, "console");
     2310
     2311        // If all went well and the result wasn't undefined then print
     2312        // the returned value.
     2313        if (!rc->IsUndefined() && !rc->IsFunction())
     2314            JsResult(*String::AsciiValue(rc));
     2315
    22802316        if (!HandleException(exception, "console"))
    22812317            lout << endl;
     
    24432479    dimctrl->Set(String::New("getState"),    FunctionTemplate::New(WrapGetState),  ReadOnly);
    24442480    dimctrl->Set(String::New("setInterruptHandler"), FunctionTemplate::New(WrapSetInterrupt), ReadOnly);
     2481    dimctrl->Set(String::New("triggerInterrupt"), FunctionTemplate::New(WrapTriggerInterrupt), ReadOnly);
    24452482
    24462483    Handle<ObjectTemplate> v8 = ObjectTemplate::New();
  • trunk/FACT++/src/InterpreterV8.h

    r16102 r16802  
    9191    v8::Handle<v8::Value> FuncNewState(const v8::Arguments& args);
    9292    v8::Handle<v8::Value> FuncSetInterrupt(const v8::Arguments& args);
     93    v8::Handle<v8::Value> FuncTriggerInterrupt(const v8::Arguments& args);
    9394    //v8::Handle<v8::Value> FuncOpen(const v8::Arguments& args);
    9495    v8::Handle<v8::Value> FuncSubscription(const v8::Arguments& args);
     
    149150    static v8::Handle<v8::Value> WrapGetServices(const v8::Arguments &args){ if (This) return This->FuncGetServices(args);else return v8::Undefined(); }
    150151    static v8::Handle<v8::Value> WrapSetInterrupt(const v8::Arguments &args){ if (This) return This->FuncSetInterrupt(args);else return v8::Undefined(); }
     152    static v8::Handle<v8::Value> WrapTriggerInterrupt(const v8::Arguments &args){ if (This) return This->FuncTriggerInterrupt(args);else return v8::Undefined(); }
    151153    //static v8::Handle<v8::Value> WrapOpen(const v8::Arguments &args)     { if (This) return This->FuncOpen(args);     else return v8::Undefined(); }
    152154    static v8::Handle<v8::Value> WrapSubscription(const v8::Arguments &args){ if (This) return This->FuncSubscription(args);else return v8::Undefined(); }
     
    170172    v8::Handle<v8::Value> ConvertEvent(const EventImp *evt, uint64_t, const char *str);
    171173#endif
     174
     175    v8::Handle<v8::Value> HandleInterruptImp(std::string, uint64_t);
    172176
    173177public:
Note: See TracChangeset for help on using the changeset viewer.