Changeset 14568 for trunk/FACT++


Ignore:
Timestamp:
11/06/12 00:25:32 (12 years ago)
Author:
tbretz
Message:
A bug fix to event compilation; a new implementation of get() which now has the possibility to set a timeout to wait for a valid event.
File:
1 edited

Legend:

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

    r14562 r14568  
    769769    // If valid data was received, but the size was zero, then
    770770    // null is returned as data
    771     if (evt->GetSize()==0)
     771    if (evt->GetSize()==0 || evt->GetFormat().empty())
    772772    {
    773773        ret->Set(String::New("data"), Null(), ReadOnly);
     
    780780    const vector<string> tok(tokenizer.begin(), tokenizer.end());
    781781
    782     Handle<Array> obj = tok.size()==1 ? ret : Array::New();
     782    Handle<Array> obj = tok.size()>1 ? Array::New() : ret;
    783783
    784784    const char *ptr = evt->GetText();
     785    const char *end = evt->GetText()+evt->GetSize();
     786
    785787    try
    786788    {
    787789        size_t pos = 1;
    788         for (auto it=tok.begin(); it!=tok.end(); it++, pos++)
     790        for (auto it=tok.begin(); it!=tok.end() && ptr<end; it++, pos++)
    789791        {
    790             if (ptr>=evt->GetText())
    791                 return ret;
    792 
    793792            char type = (*it)[0];
    794793            it++;
     
    839838    }
    840839}
    841 
     840/*
    842841Handle<Value> InterpreterV8::FuncGetData(const Arguments &args)
    843842{
     
    858857    return ret->IsNativeError() ? ThrowException(ret) : handle_scope.Close(ret);
    859858}
     859*/
     860Handle<Value> InterpreterV8::FuncGetData(const Arguments &args)
     861{
     862    if (args.Length()>1)
     863        return ThrowException(String::New("Number of arguments must not be greatr than 1."));
     864
     865    if (args.Length()==1 && !args[0]->IsInt32() && !args[0]->IsNull())
     866        return ThrowException(String::New("Argument 1 not an int32."));
     867
     868    // Using a Javascript function has the advantage that it is fully
     869    // interruptable without the need of C++ code
     870    const bool    null    = args.Length()==1 && args[0]->IsNull();
     871    const int32_t timeout = args.Length()==1 ? args[0]->Int32Value() : 0;
     872
     873    HandleScope handle_scope;
     874
     875    const Handle<Script> sleep = Script::Compile(String::New("dim.sleep();"));
     876
     877    const Handle<String> data  = String::New("data");
     878    const Handle<String> named = String::New("named");
     879
     880    const String::Utf8Value name(args.Holder()->Get(String::New("name")));
     881
     882    TryCatch exception;
     883
     884    Time t;
     885    while (!exception.HasCaught())
     886    {
     887        const pair<uint64_t, EventImp *> p = JsGetEvent(*name);
     888
     889        const EventImp *evt = p.second;
     890        if (evt)
     891        {
     892            const Handle<Value> val = ConvertEvent(evt, p.first, *name);
     893            if (val->IsNativeError())
     894                return ThrowException(val);
     895
     896            // Protect against the return of an exception
     897            if (!val.IsEmpty() && val->IsObject())
     898            {
     899                const Handle<Object> obj = val->ToObject();
     900                if (obj->Has(data) && obj->Get(named)->ToBoolean()->Value())
     901                    return handle_scope.Close(val);
     902            }
     903        }
     904
     905        if (args.Length()==0)
     906            break;
     907
     908        if (!null && Time()-t>=boost::posix_time::milliseconds(abs(timeout)))
     909            break;
     910
     911        // We cannot sleep directly because we have to give control back to
     912        // JavaScript ever now and then. This also allows us to catch
     913        // exceptions, either from the preemption or ConvertEvent
     914        sleep->Run();
     915    }
     916
     917    if (exception.HasCaught())
     918        return exception.ReThrow();
     919
     920    if (timeout>=0)
     921        return Undefined();
     922
     923    const string str = "Waiting for a valid event of "+string(*name)+" timed out.";
     924    return ThrowException(String::New(str.c_str()));
     925}
     926
    860927
    861928// This is a callback from the RemoteControl piping event handling
     
    10291096
    10301097    Handle<ObjectTemplate> tem = ObjectTemplate::New();
    1031     tem->Set(String::New("get"),    FunctionTemplate::New(WrapGetData), ReadOnly);
    1032     tem->Set(String::New("close"),  FunctionTemplate::New(WrapClose),   ReadOnly);
     1098    tem->Set(String::New("get"),    FunctionTemplate::New(WrapGetData),  ReadOnly);
     1099    tem->Set(String::New("close"),  FunctionTemplate::New(WrapClose),    ReadOnly);
    10331100    tem->Set(String::New("name"),   String::New(*str), ReadOnly);
    10341101    tem->Set(String::New("isOpen"), Boolean::New(true));
Note: See TracChangeset for help on using the changeset viewer.